[IMP] sequence rename
[odoo/odoo.git] / doc / source / guides / client-action.rst
1 Creating a new client action
2 ============================
3
4 Client actions are the client-side of OpenERP's "Server Actions": instead of
5 allowing for semi-arbitrary code to be executed in the server, they allow
6 for execution of client-customized code.
7
8 On the server side, a client action is an action of type ``ir.actions.client``,
9 which has (at most) two properties: a mandatory ``tag``, which is an arbitrary
10 string by which the client will identify the action, and an optional ``params``
11 which is simply a map of keys and values sent to the client as-is (this way,
12 client actions can be made generic and reused in multiple contexts).
13
14 General Structure
15 -----------------
16
17 In the OpenERP Web code, a client action only requires two pieces of
18 information:
19
20 * Mapping the action's ``tag`` to an OpenERP Web object
21
22 * The OpenERP Web object itself, which must inherit from
23   :js:class:`openerp.web.Widget`
24
25 Our example will be the actual code for the widgets client action (a client
26 action displaying a ``res.widget`` object, used in the homepage dashboard of
27 the web client):
28
29 .. code-block:: javascript
30
31     // Registers the object 'openerp.web_dashboard.Widget' to the client
32     // action tag 'board.home.widgets'
33     openerp.web.client_actions.add(
34         'board.home.widgets', 'openerp.web_dashboard.Widget');
35     // This object inherits from View, but only Widget is required
36     openerp.web_dashboard.Widget = openerp.web.View.extend({
37         template: 'HomeWidget'
38     });
39
40 At this point, the generic ``Widget`` lifecycle takes over, the template is
41 rendered, inserted in the client DOM, bound on the object's ``$element``
42 property and the object is started.
43
44 If the client action takes parameters, these parameters are passed in as a
45 second positional parameter to the constructor:
46
47 .. code-block:: javascript
48
49     init: function (parent, params) {
50         // execute the Widget's init
51         this._super(parent);
52         // board.home.widgets only takes a single param, the identifier of the
53         // res.widget object it should display. Store it for later
54         this.widget_id = params.widget_id;
55     }
56
57 More complex initialization (DOM manipulations, RPC requests, ...) should be
58 performed in the ``start()`` method.
59
60 .. note::
61     As required by ``Widget``'s contract, if ``start`` executes any
62     asynchronous code it should return a ``$.Deferred`` so callers know when
63     it's ready for interaction.
64
65     Although generally speaking client actions are not really interacted with.
66
67 .. code-block:: javascript
68
69     start: function () {
70         return $.when(
71             this._super(),
72             // Simply read the res.widget object this action should display
73             new openerp.web.DataSet(this, 'res.widget').read_ids(
74                 [this.widget_id], ['title'], this.on_widget_loaded));
75     }
76
77 The client action can then behave exactly as it wishes to within its root
78 (``this.$element``). In this case, it performs further renderings once its
79 widget's content is retrieved:
80
81 .. code-block:: javascript
82
83     on_widget_loaded: function (widgets) {
84         var widget = widgets[0];
85         var url = _.sprintf(
86             '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
87             this.session.session_id, widget.id);
88         this.$element.html(QWeb.render('HomeWidget.content', {
89             widget: widget,
90             url: url
91         }));
92     }