mirror of
https://github.com/nextcloud/documentation.git
synced 2025-10-26 11:18:02 +00:00
Merge pull request #501 from owncloud/app-nav
ownCloud 8: Add app developer documentation for list entry actions
This commit is contained in:
commit
6be12f796f
@ -322,6 +322,7 @@ By default there is only a responder for JSON but more can be added easily:
|
||||
namespace OCA\MyApp\Controller;
|
||||
|
||||
use \OCP\AppFramework\Controller;
|
||||
use \OCP\AppFramework\Http\DataResponse;
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
@ -329,7 +330,15 @@ By default there is only a responder for JSON but more can be added easily:
|
||||
|
||||
// XMLResponse has to be implemented
|
||||
$this->registerResponder('xml', function($value) {
|
||||
return new XMLResponse($value);
|
||||
if ($value instanceof DataResponse) {
|
||||
return new XMLResponse(
|
||||
$value->getData(),
|
||||
$value->getStatus(),
|
||||
$value->getHeaders()
|
||||
);
|
||||
} else {
|
||||
return new XMLResponse($value);
|
||||
}
|
||||
});
|
||||
|
||||
return array('test' => 'hi');
|
||||
@ -339,6 +348,32 @@ By default there is only a responder for JSON but more can be added easily:
|
||||
|
||||
.. note:: The above example would only return XML if the **format** parameter was *xml*. If you want to return an XMLResponse regardless of the format parameter, extend the Response class and return a new instance of it from the controller method instead.
|
||||
|
||||
.. versionadded:: 8
|
||||
|
||||
Because returning values works fine in case of a success but not in case of failure that requires a custom HTTP error code, you can always wrap the value in a **DataResponse**. This works for both normal responses and error responses.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace OCA\MyApp\Controller;
|
||||
|
||||
use \OCP\AppFramework\Controller;
|
||||
use \OCP\AppFramework\Http\DataResponse;
|
||||
use \OCP\AppFramework\Http\Http;
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
public function returnHi() {
|
||||
try {
|
||||
return new DataResponse(calculate_hi());
|
||||
} catch (\Exception $ex) {
|
||||
return new DataResponse(array('msg' => 'not found!'), Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Templates
|
||||
---------
|
||||
A :doc:`template <templates>` can be rendered by returning a TemplateResponse. A TemplateResponse takes the following parameters:
|
||||
|
||||
@ -37,9 +37,15 @@ To use the commonly used layout consisting of sidebar navigation and content the
|
||||
|
||||
<div id="app">
|
||||
<div id="app-navigation">Your navigation</div>
|
||||
<div id="app-content">Your content</div>
|
||||
<div id="app-content">
|
||||
<div id="app-content-wrapper">
|
||||
Your content in here
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
For built in mobile support your content has to be wrapped inside another div with the id **app-content-wrapper**.
|
||||
|
||||
Navigation
|
||||
==========
|
||||
ownCloud provides a default CSS navigation layout. If list entries should have 16x16 px icons, the **with-icon** class can be added to the base **ul**. The maximum supported indention level is two, further indentions are not recommended.
|
||||
@ -102,6 +108,155 @@ The class which should be applied to a first level element (**li**) that hosts o
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Menus
|
||||
-----
|
||||
|
||||
.. versionadded:: 8
|
||||
|
||||
To add actions that affect the current list element you can add a menu for second and/or first level elements by adding the button and menu inside the corresponding **li** element and adding the **with-menu** css class:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<div id="app-navigation">
|
||||
<ul>
|
||||
<li class="with-counter with-menu">
|
||||
<a href="#">First level entry</a>
|
||||
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter">15</li>
|
||||
<li class="app-navigation-entry-utils-menu-button svg"><button></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="app-navigation-entry-menu open">
|
||||
<ul>
|
||||
<li><button class="icon-rename svg" title="rename"></button></li>
|
||||
<li><button class="icon-delete svg" title="delete"></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</div>
|
||||
|
||||
The div with the class **app-navigation-entry-utils** contains only the button (class: **app-navigation-entry-utils-menu-button**) to display the menu but in many cases another entry is needed to display some sort of count (mails count, unread feed count, etc.). In that case add the **with-counter** class to the list entry to adjust the correct padding and text-oveflow of the entry's title.
|
||||
|
||||
The count should be limitted to 999 and turn to 999+ if any higher number is given. If AngularJS is used the following filter can be used to get the correct behaviour:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
app.filter('counterFormatter', function () {
|
||||
'use strict';
|
||||
return function (count) {
|
||||
if (count > 999) {
|
||||
return '999+';
|
||||
}
|
||||
return count;
|
||||
};
|
||||
});
|
||||
|
||||
Use it like this:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<li class="app-navigation-entry-utils-counter">{{ count | counterFormatter }}</li>
|
||||
|
||||
The menu is hidden by default (**display: none**) and has to be triggered by adding the **open** class to the **app-navigation-entry-menu** div.
|
||||
|
||||
In case of AngularJS the following small directive can be added to handle all the display and click logic out of the box:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
app.run(function ($document, $rootScope) {
|
||||
'use strict';
|
||||
$document.click(function (event) {
|
||||
$rootScope.$broadcast('documentClicked', event);
|
||||
});
|
||||
});
|
||||
|
||||
app.directive('appNavigationEntryUtils', function () {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'C',
|
||||
link: function (scope, elm) {
|
||||
var menu = elm.siblings('.app-navigation-entry-menu');
|
||||
var button = $(elm)
|
||||
.find('.app-navigation-entry-utils-menu-button button');
|
||||
|
||||
button.click(function () {
|
||||
menu.toggleClass('open');
|
||||
});
|
||||
|
||||
scope.$on('documentClicked', function (scope, event) {
|
||||
if (event.target !== button[0]) {
|
||||
menu.removeClass('open');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
Editing
|
||||
-------
|
||||
|
||||
.. versionadded:: 8
|
||||
|
||||
Often an edit option is needed an entry. To add one for a given entry simply hide the title and add the following div inside the entry:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<div id="app-navigation">
|
||||
<ul class="with-icon">
|
||||
<li>
|
||||
<a href="#" class="hidden">First level entry</a>
|
||||
|
||||
<div class="app-navigation-entry-edit">
|
||||
<form>
|
||||
<input type="text" value="First level entry" autofocus-on-insert>
|
||||
<input type="submit" value="" class="action icon-checkmark">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
If AngularJS is used you want to autofocus the input box. This can be achieved by placing the show condition inside an **ng-if** on the **app-navigation-entry-edit** div and adding the following directive:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
app.directive('autofocusOnInsert', function () {
|
||||
'use strict';
|
||||
return function (scope, elm) {
|
||||
elm.focus();
|
||||
};
|
||||
});
|
||||
|
||||
**ng-if** is required because it removes/inserts the element into the DOM dynamically instead of just adding a **display: none** to it like **ng-show** and **ng-hide**.
|
||||
|
||||
Undo entry
|
||||
----------
|
||||
|
||||
.. versionadded:: 8
|
||||
|
||||
If you want to undo a performed action on a navigation entry such as deletion, you should show the undo directly in place of the entry and make it disappear after location change or 7 seconds:
|
||||
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<div id="app-navigation">
|
||||
<ul class="with-icon">
|
||||
<li>
|
||||
<a href="#" class="hidden">First level entry</a>
|
||||
|
||||
<div class="app-navigation-entry-deleted">
|
||||
<div class="app-navigation-entry-deleted-description">Deleted X</div>
|
||||
<button class="app-navigation-entry-deleted-button icon-history" title="Undo"></button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
Settings Area
|
||||
=============
|
||||
|
||||
Loading…
Reference in New Issue
Block a user