mirror of
https://github.com/nextcloud/documentation.git
synced 2025-12-13 16:09:29 +07:00
233 lines
7.9 KiB
ReStructuredText
233 lines
7.9 KiB
ReStructuredText
.. _ApplicationJs:
|
|
|
|
==========
|
|
JavaScript
|
|
==========
|
|
|
|
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
|
|
|
|
The JavaScript files reside in the **js/** folder and should be included
|
|
in the appropriate controller. There are two methods to inject your JavaScript files.
|
|
|
|
1. ``Util::addScript``
|
|
2. ``Util::addInitScript``
|
|
|
|
.. code-block:: php
|
|
|
|
/**
|
|
* Add a javascript file
|
|
*
|
|
* @param string $application Your application ID, e.g. 'your_app'
|
|
* @param string $file Your script name, e.g. 'main'
|
|
* @param string $afterAppId Optional, the script will be loaded after this app
|
|
* @param bool $prepend Optional, if true the script will be prepended to this app scripts list
|
|
*/
|
|
public static function addScript(string $application, string $file = null, string $afterAppId = 'core', bool $prepend = false): void
|
|
|
|
/**
|
|
* Add a standalone init js file that is loaded for initialization.
|
|
* Be careful loading scripts using this method as they are loaded early
|
|
* and block the initial page rendering. They should not have dependencies
|
|
* on any other scripts than core-common and core-main.
|
|
*
|
|
* @param string $application Your application ID, e.g. 'your_app'
|
|
* @param string $file Your script name, e.g. 'main'
|
|
*/
|
|
public static function addInitScript(string $application, string $file): void
|
|
|
|
.. note:: If your script is only needed after a specific event, e.g. after the Files app is loaded,
|
|
you will have to register a Listener in your app ``Appinfo/Application.php``.
|
|
|
|
Here is an example for the Files app (which emits the ``LoadAdditionalScriptsEvent``).
|
|
For more information about app bootstrapping, see the :ref:`application-php` section.
|
|
|
|
.. code-block:: php
|
|
|
|
namespace OCA\YourApp\AppInfo;
|
|
|
|
use OCA\Files\Event\LoadAdditionalScriptsEvent;
|
|
use OCA\YourApp\Listener\LoadAdditionalListener;
|
|
use OCP\AppFramework\App;
|
|
use OCP\AppFramework\Bootstrap\IBootContext;
|
|
use OCP\AppFramework\Bootstrap\IBootstrap;
|
|
use OCP\AppFramework\Bootstrap\IRegistrationContext;
|
|
|
|
/**
|
|
* @package OCA\YourApp\AppInfo
|
|
*/
|
|
class Application extends App implements IBackendProvider, IAuthMechanismProvider, IBootstrap {
|
|
public const APP_ID = 'your_app';
|
|
|
|
public function __construct(array $urlParams = []) {
|
|
parent::__construct(self::APP_ID, $urlParams);
|
|
}
|
|
|
|
public function register(IRegistrationContext $context): void {
|
|
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class);
|
|
}
|
|
|
|
public function boot(IBootContext $context): void {}
|
|
|
|
.. code-block:: php
|
|
|
|
namespace OCA\YourApp\Listener;
|
|
|
|
use OCA\YourApp\AppInfo\Application;
|
|
use OCA\Files\Event\LoadAdditionalScriptsEvent;
|
|
use OCP\EventDispatcher\Event;
|
|
use OCP\EventDispatcher\IEventListener;
|
|
use OCP\Util;
|
|
|
|
class LoadAdditionalListener implements IEventListener {
|
|
|
|
public function handle(Event $event): void {
|
|
if (!($event instanceof LoadAdditionalScriptsEvent)) {
|
|
return;
|
|
}
|
|
|
|
Util::addInitScript(Application::APP_ID, 'init');
|
|
Util::addScript(Application::APP_ID, 'main', 'files');
|
|
}
|
|
}
|
|
|
|
|
|
Sending the CSRF token
|
|
----------------------
|
|
|
|
If any other JavaScript request library than jQuery is being used, the requests need to send the CSRF token as an HTTP header named **requesttoken**. The token is available in the global variable **OC.requestToken**.
|
|
|
|
For AngularJS the following lines would need to be added:
|
|
|
|
.. code-block:: js
|
|
|
|
var app = angular.module('MyApp', []).config(['$httpProvider', function($httpProvider) {
|
|
$httpProvider.defaults.headers.common.requesttoken = OC.requestToken;
|
|
}]);
|
|
|
|
|
|
Generating URLs
|
|
---------------
|
|
|
|
To send requests to Nextcloud the base URL where Nextcloud is currently running is needed. To get the base URL use:
|
|
|
|
.. code-block:: js
|
|
|
|
var baseUrl = OC.generateUrl('');
|
|
|
|
Full URLs can be generated by using:
|
|
|
|
.. code-block:: js
|
|
|
|
var authorUrl = OC.generateUrl('/apps/myapp/authors/1');
|
|
|
|
|
|
Extending core parts
|
|
--------------------
|
|
|
|
It is possible to extend components of the core web UI. The following examples
|
|
should show how this is possible.
|
|
|
|
Extending the "new" menu in the files app
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
.. versionadded:: 9.0
|
|
|
|
.. code-block:: js
|
|
|
|
var myFileMenuPlugin = {
|
|
attach: function (menu) {
|
|
menu.addMenuEntry({
|
|
id: 'abc',
|
|
displayName: 'Menu display name',
|
|
templateName: 'templateName.ext',
|
|
iconClass: 'icon-filetype-text',
|
|
fileType: 'file',
|
|
actionHandler: function () {
|
|
console.log('do something here');
|
|
}
|
|
});
|
|
}
|
|
};
|
|
OC.Plugins.register('OCA.Files.NewFileMenu', myFileMenuPlugin);
|
|
|
|
This will register a new menu entry in the "New" menu of the files app. The
|
|
method ``attach()`` is called once the menu is built. This usually happens right
|
|
after the click on the button.
|
|
|
|
|
|
Loading initial state
|
|
---------------------
|
|
|
|
Often apps have some kind of initial state. Often the first thing a script does
|
|
is querying an endpoint to obtain this initial state. This makes the user
|
|
experience sub optimal as they have to wait for yet another request to finish
|
|
loading.
|
|
|
|
To provide the initial state in a standardized way quickly to the javascript
|
|
Nextcloud provides an API. The API consists of a PHP part (that supplies the state)
|
|
and a JS part (that fetches and parses the state).
|
|
|
|
Providing the initial state with PHP
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
Providing state in PHP is done via the ``OCP\AppFramework\Services\IInitialState``. This service
|
|
has two methods you can use to provide the initial state. They will automatically be scoped
|
|
to your app, so you don't have to provide your app id anymore.
|
|
|
|
* ``provideInitialState(string $key, $data)``:
|
|
If you know for sure your state will be used. For example on the settings page of your app.
|
|
* ``provideLazyInitialState(string $key, Closure $closure)``:
|
|
If you want to inject your state on a general page. For example the initial state of the notifications app. The callback will be invoked if and only if a template is rendered.
|
|
|
|
You call both methods with the name of your app and a key. This is to scope
|
|
the states properly. You will need both when retrieving the initial state in
|
|
javascript.
|
|
|
|
The data for the initial state is converted to JSON. So be sure that the
|
|
data you provide (either in $data or as a return from the $closure) can be converted
|
|
to JSON.
|
|
|
|
Obtaining the initial state in JavaScript
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
To obtain the initial state in your JavaScript you have to only call one
|
|
function
|
|
|
|
- Vue way with `@nextcloud/initial-state <https://github.com/nextcloud/nextcloud-initial-state>`_:
|
|
|
|
.. code-block:: js
|
|
|
|
import { loadState } from '@nextcloud/initial-state'
|
|
|
|
const val = loadState('myapp', 'user_preference')
|
|
|
|
// Provide a fallback value to return when the state is not found
|
|
const valWithFallback = loadState('myapp', 'user_preference', 'no_preference')
|
|
|
|
- Legacy way:
|
|
|
|
.. code-block:: js
|
|
|
|
const state = OCP.InitialState.loadState('MyApp', 'MyState');
|
|
|
|
Now state will contain the provided state which you can use as any variable. It
|
|
is as simple as that.
|
|
|
|
.. _basics_frontend_javascript_keyboard_shortcuts:
|
|
|
|
|
|
Keyboard shortcuts
|
|
------------------
|
|
|
|
In case you want to improve your user experience with keyboard shortcuts, make sure
|
|
to not overwrite browser, operating system and other Nextcloud wide shortcuts.
|
|
Also there is an accessibility setting for users to opt-out of **any** keyboard shortcuts
|
|
Nextcloud wide. You can check the setting with the following function which returns a boolean
|
|
(available in Nextcloud 25 and later):
|
|
|
|
.. code-block:: js
|
|
|
|
OCP.Accessibility.disableKeyboardShortcuts();
|
|
|
|
If that is the case, no additional shortcuts shall be registered by any app. Only ``space``
|
|
to toggle checkboxes and ``enter`` to submit the currently active buttons or links are okay,
|
|
as any other shortcut might interfere with screenreaders and other accessibility tools.
|