[DOC] doc: add information on session and client action
This commit is contained in:
@@ -616,23 +616,23 @@ Widget API
|
||||
generated DOM root with the following attributes:
|
||||
|
||||
|
||||
.. attribute:: Widget.id
|
||||
.. attribute:: Widget.id
|
||||
|
||||
Used to generate an ``id`` attribute on the generated DOM
|
||||
root. Note that this is rarely needed, and is probably not a good idea
|
||||
if a widget can be used more than once.
|
||||
Used to generate an ``id`` attribute on the generated DOM
|
||||
root. Note that this is rarely needed, and is probably not a good idea
|
||||
if a widget can be used more than once.
|
||||
|
||||
.. attribute:: Widget.className
|
||||
.. attribute:: Widget.className
|
||||
|
||||
Used to generate a ``class`` attribute on the generated DOM root. Note
|
||||
that it can actually contain more than one css class:
|
||||
*'some-class other-class'*
|
||||
Used to generate a ``class`` attribute on the generated DOM root. Note
|
||||
that it can actually contain more than one css class:
|
||||
*'some-class other-class'*
|
||||
|
||||
.. attribute:: Widget.attributes
|
||||
.. attribute:: Widget.attributes
|
||||
|
||||
Mapping (object literal) of attribute names to attribute
|
||||
values. Each of these k:v pairs will be set as a DOM attribute
|
||||
on the generated DOM root.
|
||||
Mapping (object literal) of attribute names to attribute
|
||||
values. Each of these k:v pairs will be set as a DOM attribute
|
||||
on the generated DOM root.
|
||||
|
||||
.. attribute:: Widget.el
|
||||
|
||||
@@ -651,13 +651,21 @@ Widget API
|
||||
initialized but before it has been started. The root element generated by
|
||||
the template will be set as the DOM root of the widget.
|
||||
|
||||
.. attribute:: xmlDependencies
|
||||
.. attribute:: Widget.xmlDependencies
|
||||
|
||||
List of paths to xml files that need to be loaded before the
|
||||
widget can be rendered. This will not induce loading anything that has already
|
||||
been loaded.
|
||||
been loaded. This is useful when you want to load your templates lazily,
|
||||
or if you want to share a widget between the website and the web client
|
||||
interface.
|
||||
|
||||
.. attribute:: events
|
||||
.. code-block:: javascript
|
||||
|
||||
var EditorMenuBar = Widget.extend({
|
||||
xmlDependencies: ['/web_editor/static/src/xml/editor.xml'],
|
||||
...
|
||||
|
||||
.. attribute:: Widget.events
|
||||
|
||||
Events are a mapping of an event selector (an event name and an optional
|
||||
CSS selector separated by a space) to a callback. The callback can
|
||||
@@ -682,7 +690,7 @@ Widget API
|
||||
Note: the use of an inline function is discouraged, and will probably be
|
||||
removed sometimes in the future.
|
||||
|
||||
.. attribute:: custom_events
|
||||
.. attribute:: Widget.custom_events
|
||||
|
||||
this is almost the same as the *events* attribute, but the keys
|
||||
are arbitrary strings. They represent business events triggered by
|
||||
@@ -1265,6 +1273,55 @@ when the module is loaded.
|
||||
Note that translation functions need some care. The string given in argument
|
||||
should not be dynamic.
|
||||
|
||||
Session
|
||||
=======
|
||||
|
||||
There is a specific module provided by the web client which contains some
|
||||
information specific to the user current *session*. Some notable keys are
|
||||
|
||||
- uid: the current user ID (its ID as a *res.users*)
|
||||
- user_name: the user name, as a string
|
||||
- the user context (user ID, language and timezone)
|
||||
- partner_id: the ID of the partner associated to the current user
|
||||
- db: the name of the database currently being in use
|
||||
|
||||
Adding information to the session
|
||||
---------------------------------
|
||||
|
||||
When the /web route is loaded, the server will inject some session information
|
||||
in the template a script tag. The information will be read from the method
|
||||
*session_info* of the model *ir.http*. So, if one wants to add a specific
|
||||
information, it can be done by overriding the session_info method and adding it
|
||||
to the dictionary.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class IrHttp(models.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
def session_info(self):
|
||||
result = super(IrHttp, self).session_info()
|
||||
result['some_key'] = get_some_value_from_db()
|
||||
return result
|
||||
|
||||
Now, the value can be obtained in javascript by reading it in the session:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var session = require('web.session');
|
||||
var myValue = session.some_key;
|
||||
...
|
||||
|
||||
Note that this mechanism is designed to reduce the amount of communication
|
||||
needed by the web client to be ready. It is more appropriate for data which is
|
||||
cheap to compute (a slow session_info call will delay the loading for the web
|
||||
client for everyone), and for data which is required early in the initialization
|
||||
process.
|
||||
|
||||
Views
|
||||
======
|
||||
|
||||
@@ -1400,6 +1457,7 @@ order.
|
||||
Options:
|
||||
|
||||
- type: setting the input type (*text* by default, can be set on *number*)
|
||||
|
||||
On edit mode, the field is rendered as an input with the HTML attribute type
|
||||
setted on *number* (so user can benefit the native support, especially on
|
||||
mobile). In this case, the default formatting is disabled to avoid incompability.
|
||||
@@ -1409,7 +1467,7 @@ order.
|
||||
<field name="int_value" options='{"type": "number"}'/>
|
||||
|
||||
- step: set the step to the value up and down when the user click on buttons
|
||||
(only for input of type number, 1 by default)
|
||||
(only for input of type number, 1 by default)
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -1431,6 +1489,7 @@ order.
|
||||
Options:
|
||||
|
||||
- type: setting the input type (*text* by default, can be set on *number*)
|
||||
|
||||
On edit mode, the field is rendered as an input with the HTML attribute type
|
||||
setted on *number* (so user can benefit the native support, especially on
|
||||
mobile). In this case, the default formatting is disabled to avoid incompability.
|
||||
@@ -1440,7 +1499,7 @@ order.
|
||||
<field name="int_value" options='{"type": "number"}'/>
|
||||
|
||||
- step: set the step to the value up and down when the user click on buttons
|
||||
(only for input of type number, 1 by default)
|
||||
(only for input of type number, 1 by default)
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
@@ -1996,6 +2055,122 @@ Relational fields
|
||||
This widget is exactly the same as a FieldOne2Many. It is registered at this
|
||||
key only for backward compatibility reasons. Please avoid using this.
|
||||
|
||||
|
||||
Client actions
|
||||
==============
|
||||
|
||||
The idea of a client action is a customized widget that is integrated in the
|
||||
web client interface, just like a *act_window_action*. This is useful when
|
||||
you need a component that is not closely linked to an existing view or a
|
||||
specific model. For example, the Discuss application is actually a client
|
||||
action.
|
||||
|
||||
A client action is a term that has various meanings, depending on the context:
|
||||
|
||||
- from the perspective of the server, it is a record of the model *ir_action*,
|
||||
with a field *tag* of type char
|
||||
- from the perspective of the web client, it is a widget, which inherit from
|
||||
the class AbstractAction, and is supposed to be registered in the
|
||||
action registry under the corresponding key (from the field char)
|
||||
|
||||
Whenever a menu item is associated to a client action, opening it will simply
|
||||
fetch the action definition from the server, then lookup into its action
|
||||
registry to get the Widget definition at the appropriate key, and finally, it
|
||||
will instantiate and append the widget to the proper place in the DOM.
|
||||
|
||||
Adding a client action
|
||||
----------------------
|
||||
|
||||
A client action is a widget which will control the part of the screen below the
|
||||
menu bar. It can have a control panel, if necessary. Defining a client action
|
||||
can be done in two steps: implementing a new widget, and registering the widget
|
||||
in the action registry.
|
||||
|
||||
- Implementing a new client action:
|
||||
This is done by creating a widget:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
|
||||
var ClientAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
...
|
||||
});
|
||||
|
||||
Do not add the controlpanel mixin if you do not need it. Note that some
|
||||
code is needed to interact with the control panel (via the
|
||||
``update_control_panel`` method given by the mixin).
|
||||
|
||||
- Registering the client action:
|
||||
As usual, we need to make the web client aware of the mapping between
|
||||
client actions and the actual class:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var core = require('web.core');
|
||||
|
||||
core.action_registry.add('my-custom-action', ClientAction);
|
||||
|
||||
|
||||
Then, to use the client action in the web client, we need to create a client
|
||||
action record (a record of the model ``ir.actions.client``) with the proper
|
||||
``tag`` attribute:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<record id="my_client_action" model="ir.actions.client">
|
||||
<field name="name">Some Name</field>
|
||||
<field name="tag">my-custom-action</field>
|
||||
</record>
|
||||
|
||||
|
||||
Using the control panel mixin
|
||||
-----------------------------
|
||||
|
||||
By default, the AbstractAction class does not include the control panel mixin.
|
||||
This means that a client action does not display a control panel. In order to
|
||||
do that, several steps should be done.
|
||||
|
||||
- add ControlPanelMixin in the widget:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
|
||||
var MyClientAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
...
|
||||
});
|
||||
|
||||
- call the method *update_control_panel* whenever we need to update the control
|
||||
panel. For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var SomeClientAction = Widget.extend(ControlPanelMixin, {
|
||||
...
|
||||
start: function () {
|
||||
this._renderButtons();
|
||||
this._updateControlPanel();
|
||||
...
|
||||
},
|
||||
do_show: function () {
|
||||
...
|
||||
this._updateControlPanel();
|
||||
},
|
||||
_renderButtons: function () {
|
||||
this.$buttons = $(QWeb.render('SomeTemplate.Buttons'));
|
||||
this.$buttons.on('click', ...);
|
||||
},
|
||||
_updateControlPanel: function () {
|
||||
this.update_control_panel({
|
||||
cp_content: {
|
||||
$buttons: this.$buttons,
|
||||
},
|
||||
});
|
||||
|
||||
For more information, look into the *control_panel.js* file.
|
||||
|
||||
.. _.appendTo():
|
||||
http://api.jquery.com/appendTo/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user