rm files, move postload hook
[odoo/odoo.git] / addons / web / doc / list-view.rst
1 List View
2 =========
3
4 Style Hooks
5 -----------
6
7 The list view provides a few style hook classes for re-styling of list views in
8 various situations:
9
10 ``.oe_list``
11
12     The root element of the list view, styling rules should be rooted
13     on that class.
14
15 ``table.oe_list_content``
16
17     The root table for the listview, accessory components may be
18     generated or added outside this section, this is the list view
19     "proper".
20
21 ``.oe_list_buttons``
22
23     The action buttons array for the list view, with its sub-elements
24
25     ``.oe_list_add``
26
27         The default "Create"/"Add" button of the list view
28
29     ``.oe_alternative``
30
31         The "alternative choice" for the list view, by default text
32         along the lines of "or import" with a link.
33
34 ``.oe_list_field_cell``
35
36     The cell (``td``) for a given field of the list view, cells which
37     are *not* fields (e.g. name of a group, or number of items in a
38     group) will not have this class. The field cell can be further
39     specified:
40
41     ``.oe_number``
42
43         Numeric cell types (integer and float)
44
45     ``.oe_button``
46
47         Action button (``button`` tag in the view) inside the cell
48
49     ``.oe_readonly``
50
51         Readonly field cell
52
53     ``.oe_list_field_$type``
54
55         Additional class for the precise type of the cell, ``$type``
56         is the field's @widget if there is one, otherwise it's the
57         field's type.
58
59 ``.oe_list_record_selector``
60
61     Selector cells
62
63 Editable list view
64 ++++++++++++++++++
65
66 The editable list view module adds a few supplementary style hook
67 classes, for edition situations:
68
69 ``.oe_list_editable``
70
71     Added to the ``.oe_list`` when the list is editable (however that
72     was done). The class may be removed on-the-fly if the list becomes
73     non-editable.
74
75 ``.oe_editing``
76
77     Added to both ``.oe_list`` and ``.oe_list_button`` (as the
78     buttons may be outside of the list view) when a row of the list is
79     currently being edited.
80
81 ``tr.oe_edition``
82
83     Class set on the row being edited itself. Note that the edition
84     form is *not* contained within the row, this allows for styling or
85     modifying the row while it's being edited separately. Mostly for
86     fields which can not be edited (e.g. read-only fields).
87
88 Columns display customization
89 -----------------------------
90
91 The list view provides a registry to
92 :js:class:`openerp.web.list.Column` objects allowing for the
93 customization of a column's display (e.g. so that a binary field is
94 rendered as a link to the binary file directly in the list view).
95
96 The registry is ``instance.web.list.columns``, the keys are of the
97 form ``tag.type`` where ``tag`` can be ``field`` or ``button``, and
98 ``type`` can be either the field's type or the field's ``@widget`` (in
99 the view).
100
101 Most of the time, you'll want to define a ``tag.widget`` key
102 (e.g. ``field.progressbar``).
103
104 .. js:class:: openerp.web.list.Column(id, tag, attrs)
105
106     .. js:function:: openerp.web.list.Column.format(record_data, options)
107
108         Top-level formatting method, returns an empty string if the
109         column is invisible (unless the ``process_modifiers=false``
110         option is provided); returns ``options.value_if_empty`` or an
111         empty string if there is no value in the record for the
112         column.
113
114         Otherwise calls :js:func:`~openerp.web.list.Column._format`
115         and returns its result.
116
117         This method only needs to be overridden if the column has no
118         concept of values (and needs to bypass that check), for a
119         button for instance.
120
121         Otherwise, custom columns should generally override
122         :js:func:`~openerp.web.list.Column._format` instead.
123
124         :returns: String
125
126     .. js:function:: openerp.web.list.Column._format(record_data, options)
127
128         Never called directly, called if the column is visible and has
129         a value.
130
131         The default implementation calls
132         :js:func:`~openerp.web.format_value` and htmlescapes the
133         result (via ``_.escape``).
134
135         Note that the implementation of
136         :js:func:`~openerp.web.list.Column._format` *must* escape the
137         data provided to it, its output will *not* be escaped by
138         :js:func:`~openerp.web.list.Column.format`.
139
140         :returns: String
141
142 Editable list view
143 ------------------
144
145 List view edition is an extension to the base listview providing the
146 capability of inline record edition by delegating to an embedded form
147 view.
148
149 Editability status
150 ++++++++++++++++++
151
152 The editability status of a list view can be queried through the
153 :js:func:`~openerp.web.ListView.editable` method, will return a falsy
154 value if the listview is not currently editable.
155
156 The editability status is based on three flags:
157
158 ``tree/@editable``
159
160     If present, can be either ``"top"`` or ``"bottom"``. Either will
161     make the list view editable, with new records being respectively
162     created at the top or at the bottom of the view.
163
164 ``context.set_editable``
165
166     Boolean flag extracted from a search context (during the
167     :js:func:`~openerp.web.ListView.do_search`` handler), ``true``
168     will make the view editable (from the top), ``false`` or the
169     absence of the flag is a noop.
170
171 ``defaults.editable``
172
173     Like ``tree/@editable``, one of absent (``null``)), ``"top"`` or
174     ``"bottom"``, fallback for the list view if none of the previous
175     two flags are set.
176
177 These three flags can only *make* a listview editable, they can *not*
178 override a previously set flag. To do that, a listview user should
179 instead cancel :ref:`the edit:before event <listview-edit-before>`.
180
181 The editable list view module adds a number of methods to the list
182 view, on top of implementing the :js:class:`EditorDelegate` protocol:
183
184 Interaction Methods
185 +++++++++++++++++++
186
187 .. js:function:: openerp.web.ListView.ensure_saved
188
189     Attempts to resolve the pending edition, if any, by saving the
190     edited row's current state.
191
192     :returns: delegate resolving to all editions having been saved, or
193               rejected if a pending edition could not be saved
194               (e.g. validation failure)
195
196 .. js:function:: openerp.web.ListView.start_edition([record][, options])
197
198     Starts editing the provided record inline, through an overlay form
199     view of editable fields in the record.
200
201     If no record is provided, creates a new one according to the
202     editability configuration of the list view.
203
204     This method resolves any pending edition when invoked, before
205     starting a new edition.
206
207     :param record: record to edit, or null to create a new record
208     :type record: :js:class:`~openerp.web.list.Record`
209     :param EditOptions options:
210     :returns: delegate to the form used for the edition
211
212 .. js:function:: openerp.web.ListView.save_edition
213
214     Resolves the pending edition.
215
216     :returns: delegate to the save being completed, resolves to an
217               object with two attributes ``created`` (flag indicating
218               whether the saved record was just created or was
219               updated) and ``record`` the reloaded record having been
220               edited.
221
222 .. js:function:: openerp.web.ListView.cancel_edition([force=false])
223
224     Cancels pending edition, cleans up the list view in case of
225     creation (removes the empty record being created).
226
227     :param Boolean force: doesn't check if the user has added any
228                           data, discards the edition unconditionally
229
230 Utility Methods
231 +++++++++++++++
232
233 .. js:function:: openerp.web.ListView.get_cells_for(row)
234
235     Extracts the cells from a listview row, and puts them in a
236     {fieldname: cell} mapping for analysis and manipulation.
237
238     :param jQuery row:
239     :rtype: Object
240
241 .. js:function:: openerp.web.ListView.with_event(event_name, event, action[, args][, trigger_params])
242
243     Executes ``action`` in the context of the view's editor,
244     bracketing it with cancellable event signals.
245
246     :param String event_name: base name for the bracketing event, will
247                               be postfixed by ``:before`` and
248                               ``:after`` before being called
249                               (respectively before and after
250                               ``action`` is executed)
251     :param Object event: object passed to the ``:before`` event
252                          handlers.
253     :param Function action: function called with the view's editor as
254                             its ``this``. May return a deferred.
255     :param Array args: arguments passed to ``action``
256     :param Array trigger_params: arguments passed to the ``:after``
257                                  event handler alongside the results
258                                  of ``action``
259
260 Behavioral Customizations
261 +++++++++++++++++++++++++
262
263 .. js:function:: openerp.web.ListView.handle_onwrite(record)
264
265     Implements the handling of the ``onwrite`` listview attribute:
266     calls the RPC methods specified by ``@onwrite``, and if that
267     method returns an array of ids loads or reloads the records
268     corresponding to those ids.
269
270     :param record: record being written having triggered the
271                    ``onwrite`` callback
272     :type record: openerp.web.list.Record
273     :returns: deferred to all reloadings being done
274
275 Events
276 ++++++
277
278 For simpler interactions by/with external users of the listview, the
279 view provides a number of dedicated events to its lifecycle.
280
281 .. note:: if an event is defined as *cancellable*, it means its first
282           parameter is an object on which the ``cancel`` attribute can
283           be set. If the ``cancel`` attribute is set, the view will
284           abort its current behavior as soon as possible, and rollback
285           any state modification.
286
287           Generally speaking, an event should only be cancelled (by
288           setting the ``cancel`` flag to ``true``), uncancelling an
289           event is undefined as event handlers are executed on a
290           first-come-first-serve basis and later handlers may
291           re-cancel an uncancelled event.
292
293 .. _listview-edit-before:
294
295 ``edit:before`` *cancellable*
296
297     Invoked before the list view starts editing a record.
298
299     Provided with an event object with a single property ``record``,
300     holding the attributes of the record being edited (``record`` is
301     empty *but not null* for a new record)
302
303 ``edit:after``
304
305     Invoked after the list view has gone into an edition state,
306     provided with the attributes of the record being edited (see
307     ``edit:before``) as first parameter and the form used for the
308     edition as second parameter.
309
310 ``save:before`` *cancellable*
311
312     Invoked right before saving a pending edition, provided with an
313     event object holding the listview's editor (``editor``) and the
314     edition form (``form``)
315
316 ``save:after``
317
318     Invoked after a save has been completed
319
320 ``cancel:before`` *cancellable*
321
322     Invoked before cancelling a pending edition, provided with the
323     same information as ``save:before``.
324
325 ``cancel:after``
326
327     Invoked after a pending edition has been cancelled.
328
329 DOM events
330 ++++++++++
331
332 The list view has grown hooks for the ``keyup`` event on its edition
333 form (during edition): any such event bubbling out of the edition form
334 will be forwarded to a method ``keyup_EVENTNAME``, where ``EVENTNAME``
335 is the name of the key in ``$.ui.keyCode``.
336
337 The method will also get the event object (originally passed to the
338 ``keyup`` handler) as its sole parameter.
339
340 The base editable list view has handlers for the ``ENTER`` and
341 ``ESCAPE`` keys.
342
343 Editor
344 ------
345
346 The list-edition modules does not generally interact with the embedded
347 formview, delegating instead to its
348 :js:class:`~openerp.web.list.Editor`.
349
350 .. js:class:: openerp.web.list.Editor(parent[, options])
351
352     The editor object provides a more convenient interface to form
353     views, and simplifies the usage of form views for semi-arbitrary
354     edition of stuff.
355
356     However, the editor does *not* task itself with being internally
357     consistent at this point: calling
358     e.g. :js:func:`~openerp.web.list.Editor.edit` multiple times in a
359     row without saving or cancelling each edit is undefined.
360
361     :param parent:
362     :type parent: :js:class:`~openerp.web.Widget`
363     :param EditorOptions options:
364
365     .. js:function:: openerp.web.list.Editor.is_editing([record_state])
366
367         Indicates whether the editor is currently in the process of
368         providing edition for a record.
369
370         Can be filtered by the state of the record being edited
371         (whether it's a record being *created* or a record being
372         *altered*), in which case it asserts both that an edition is
373         underway and that the record being edited respectively does
374         not yet exist in the database or already exists there.
375
376         :param record_state: state of the record being edited.
377                              Either ``"new"`` or ``"edit"``.
378         :type record_state: String
379         :rtype: Boolean
380
381     .. js:function:: openerp.web.list.Editor.edit(record, configureField[, options])
382
383         Loads the provided record into the internal form view and
384         displays the form view.
385
386         Will also attempt to focus the first visible field of the form
387         view.
388
389         :param Object record: record to load into the form view
390                               (key:value mapping similar to the result
391                               of a ``read``)
392         :param configureField: function called with each field of the
393                                form view right after the form is
394                                displayed, lets whoever called this
395                                method do some last-minute
396                                configuration of form fields.
397         :type configureField: Function<String, openerp.web.form.Field>
398         :param EditOptions options:
399         :returns: jQuery delegate to the form object
400
401     .. js:function:: openerp.web.list.Editor.save
402
403         Attempts to save the internal form, then hide it
404
405         :returns: delegate to the record under edition (with ``id``
406                   added for a creation). The record is not updated
407                   from when it was passed in, aside from the ``id``
408                   attribute.
409
410     .. js:function:: openerp.web.list.Editor.cancel([force=false])
411
412         Attemps to cancel the edition of the internal form, then hide
413         the form
414
415         :param Boolean force: unconditionally cancels the edition of
416                               the internal form, even if the user has
417                               already entered data in it.
418         :returns: delegate to the record under edition
419
420 .. js:class:: EditorOptions
421
422     .. js:attribute:: EditorOptions.formView
423
424         Form view (sub)-class to instantiate and delegate edition to.
425
426         By default, :js:class:`~openerp.web.FormView`
427
428     .. js:attribute:: EditorOptions.delegate
429
430         Object used to get various bits of information about how to
431         display stuff.
432
433         By default, uses the editor's parent widget. See
434         :js:class:`EditorDelegate` for the methods and attributes to
435         provide.
436
437 .. js:class:: EditorDelegate
438
439     Informal protocol defining the methods and attributes expected of
440     the :js:class:`~openerp.web.list.Editor`'s delegate.
441
442     .. js:attribute:: EditorDelegate.dataset
443
444         The dataset passed to the form view to synchronize the form
445         view and the outer widget.
446
447     .. js:function:: EditorDelegate.edition_view(editor)
448
449         Called by the :js:class:`~openerp.web.list.Editor` object to
450         get a form view (JSON) to pass along to the form view it
451         created.
452
453         The result should be a valid form view, see :doc:`Form Notes
454         <form-notes>` for various peculiarities of the form view
455         format.
456
457         :param editor: editor object asking for the view
458         :type editor: :js:class:`~openerp.web.list.Editor`
459         :returns: form view
460         :rtype: Object
461
462     .. js:function:: EditorDelegate.prepends_on_create
463
464         By default, the :js:class:`~openerp.web.list.Editor` will
465         append the ids of newly created records to the
466         :js:attr:`EditorDelegate.dataset`. If this method returns
467         ``true``, it will prepend these ids instead.
468
469         :returns: whether new records should be prepended to the
470                   dataset (instead of appended)
471         :rtype: Boolean
472
473
474 .. js:class:: EditOptions
475
476     Options object optionally passed into a method starting an edition
477     to configure its setup and behavior
478
479     .. js:attribute:: focus_field
480
481         Name of the field to set focus on after setting up the edition
482         of the record.
483
484         If this option is not provided, or the requested field can not
485         be focused (invisible, readonly or not in the view), the first
486         visible non-readonly field is focused.
487
488 Changes from 6.1
489 ----------------
490
491 * The editable listview behavior has been rewritten pretty much from
492   scratch, any code touching on editability will have to be modified
493
494   * The overloading of :js:class:`~openerp.web.ListView.Groups` and
495     :js:class:`~openerp.web.ListView.List` for editability has been
496     drastically simplified, and most of the behavior has been moved to
497     the list view itself. Only
498     :js:func:`~openerp.web.ListView.List.row_clicked` is still
499     overridden.
500
501   * A new method ``get_row_for(record) -> jQuery(tr) | null`` has been
502     added to both ListView.List and ListView.Group, it can be called
503     from the list view to get the table row matching a record (if such
504     a row exists).
505
506 * :js:func:`~openerp.web.ListView.do_button_action`'s core behavior
507   has been split away to
508   :js:func:`~openerp.web.ListView.handle_button`. This allows bypassing
509   overrides of :js:func:`~openerp.web.ListView.do_button_action` in a
510   parent class.
511
512   Ideally, :js:func:`~openerp.web.ListView.handle_button` should not be
513   overridden.
514
515 * Modifiers handling has been improved (all modifiers information
516   should now be available through :js:func:`~Column.modifiers_for`,
517   not just ``invisible``)
518
519 * Changed some handling of the list view's record: a record may now
520   have no id, and the listview will handle that correctly (for new
521   records being created) as well as correctly handle the ``id`` being
522   set.
523
524 * Extended the internal collections structure of the list view with
525   `#find`_, `#succ`_ and `#pred`_.
526
527 .. _#find: http://underscorejs.org/#find
528
529 .. _#succ: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:succ
530
531 .. _#pred: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:pred