Since the new views merge, a lot of design elements were broken. This was particularly impacting the fields in the editable list view; indeed the editable list view is not using an inline form view anymore so the fields in the list were not properly styled as the LESS was still defined assuming the form view environment (for example the invalid fields were red for o2m fields in form view but not in editable list view even though they got the right CSS class). This commit refactor the LESS following these rules: - No more division of non-layout and layout rules. Dividing LESS rules in x_layout.less and x.less was a mistake. Many rules can be considered to be layout and not layout at the same time, developers always have to switch from one file part to the other, many CSS selectors (and rules!) are duplicated for nothing, ... - Field style is extracted from x_view.less and put in the new fields.less file. As before, the fields_extra.less will contain the rules specific to community so that the enterprise repo can override those by replacing the whole file. - Many classes have been renamed so that o_form_x_y becomes o_x_y as many classes can now be applied outside of form view. These classes should not be used in templates anyway. The commit also changes the DOM of fields so that it is more minimalist (no useless parent div, etc). Input elements are not automatically styled anymore, they have to get the o_input class explicitely. This allows to fix lots of small style bugs of previous versions (required monetary field had not the proper style, readonly m2m tags appeared as editable, ...). This also improves the LESS code. The editable list view should also completely stop flickering on chrome and firefox. The commit also removes the orange outline on list view dirty cells. The commit also removes deprecated static xml, LESS and other code. Notice there are still styles to restore/fix and LESS to improve.
532 lines
18 KiB
ReStructuredText
532 lines
18 KiB
ReStructuredText
List View
|
|
=========
|
|
|
|
Style Hooks
|
|
-----------
|
|
|
|
The list view provides a few style hook classes for re-styling of list views in
|
|
various situations:
|
|
|
|
``.oe_list``
|
|
|
|
The root element of the list view, styling rules should be rooted
|
|
on that class.
|
|
|
|
``table.oe_list_content``
|
|
|
|
The root table for the listview, accessory components may be
|
|
generated or added outside this section, this is the list view
|
|
"proper".
|
|
|
|
``.oe_list_buttons``
|
|
|
|
The action buttons array for the list view, with its sub-elements
|
|
|
|
``.oe_list_add``
|
|
|
|
The default "Create"/"Add" button of the list view
|
|
|
|
``.oe_alternative``
|
|
|
|
The "alternative choice" for the list view, by default text
|
|
along the lines of "or import" with a link.
|
|
|
|
``.oe_list_field_cell``
|
|
|
|
The cell (``td``) for a given field of the list view, cells which
|
|
are *not* fields (e.g. name of a group, or number of items in a
|
|
group) will not have this class. The field cell can be further
|
|
specified:
|
|
|
|
``.oe_number``
|
|
|
|
Numeric cell types (integer and float)
|
|
|
|
``.oe_button``
|
|
|
|
Action button (``button`` tag in the view) inside the cell
|
|
|
|
``.o_readonly_modifier``
|
|
|
|
Readonly field cell
|
|
|
|
``.oe_list_field_$type``
|
|
|
|
Additional class for the precise type of the cell, ``$type``
|
|
is the field's @widget if there is one, otherwise it's the
|
|
field's type.
|
|
|
|
``.oe_list_record_selector``
|
|
|
|
Selector cells
|
|
|
|
Editable list view
|
|
++++++++++++++++++
|
|
|
|
The editable list view module adds a few supplementary style hook
|
|
classes, for edition situations:
|
|
|
|
``.o_list_editable``
|
|
|
|
Added to the ``.oe_list`` when the list is editable (however that
|
|
was done). The class may be removed on-the-fly if the list becomes
|
|
non-editable.
|
|
|
|
``.oe_editing``
|
|
|
|
Added to both ``.oe_list`` and ``.oe_list_button`` (as the
|
|
buttons may be outside of the list view) when a row of the list is
|
|
currently being edited.
|
|
|
|
``tr.oe_edition``
|
|
|
|
Class set on the row being edited itself. Note that the edition
|
|
form is *not* contained within the row, this allows for styling or
|
|
modifying the row while it's being edited separately. Mostly for
|
|
fields which can not be edited (e.g. read-only fields).
|
|
|
|
Columns display customization
|
|
-----------------------------
|
|
|
|
The list view provides a registry to
|
|
:js:class:`openerp.web.list.Column` objects allowing for the
|
|
customization of a column's display (e.g. so that a binary field is
|
|
rendered as a link to the binary file directly in the list view).
|
|
|
|
The registry is ``instance.web.list.columns``, the keys are of the
|
|
form ``tag.type`` where ``tag`` can be ``field`` or ``button``, and
|
|
``type`` can be either the field's type or the field's ``@widget`` (in
|
|
the view).
|
|
|
|
Most of the time, you'll want to define a ``tag.widget`` key
|
|
(e.g. ``field.progressbar``).
|
|
|
|
.. js:class:: openerp.web.list.Column(id, tag, attrs)
|
|
|
|
.. js:function:: openerp.web.list.Column.format(record_data, options)
|
|
|
|
Top-level formatting method, returns an empty string if the
|
|
column is invisible (unless the ``process_modifiers=false``
|
|
option is provided); returns ``options.value_if_empty`` or an
|
|
empty string if there is no value in the record for the
|
|
column.
|
|
|
|
Otherwise calls :js:func:`~openerp.web.list.Column._format`
|
|
and returns its result.
|
|
|
|
This method only needs to be overridden if the column has no
|
|
concept of values (and needs to bypass that check), for a
|
|
button for instance.
|
|
|
|
Otherwise, custom columns should generally override
|
|
:js:func:`~openerp.web.list.Column._format` instead.
|
|
|
|
:returns: String
|
|
|
|
.. js:function:: openerp.web.list.Column._format(record_data, options)
|
|
|
|
Never called directly, called if the column is visible and has
|
|
a value.
|
|
|
|
The default implementation calls
|
|
:js:func:`~openerp.web.format_value` and htmlescapes the
|
|
result (via ``_.escape``).
|
|
|
|
Note that the implementation of
|
|
:js:func:`~openerp.web.list.Column._format` *must* escape the
|
|
data provided to it, its output will *not* be escaped by
|
|
:js:func:`~openerp.web.list.Column.format`.
|
|
|
|
:returns: String
|
|
|
|
Editable list view
|
|
------------------
|
|
|
|
List view edition is an extension to the base listview providing the
|
|
capability of inline record edition by delegating to an embedded form
|
|
view.
|
|
|
|
Editability status
|
|
++++++++++++++++++
|
|
|
|
The editability status of a list view can be queried through the
|
|
:js:func:`~openerp.web.ListView.editable` method, will return a falsy
|
|
value if the listview is not currently editable.
|
|
|
|
The editability status is based on three flags:
|
|
|
|
``tree/@editable``
|
|
|
|
If present, can be either ``"top"`` or ``"bottom"``. Either will
|
|
make the list view editable, with new records being respectively
|
|
created at the top or at the bottom of the view.
|
|
|
|
``context.set_editable``
|
|
|
|
Boolean flag extracted from a search context (during the
|
|
:js:func:`~openerp.web.ListView.do_search`` handler), ``true``
|
|
will make the view editable (from the top), ``false`` or the
|
|
absence of the flag is a noop.
|
|
|
|
``defaults.editable``
|
|
|
|
Like ``tree/@editable``, one of absent (``null``)), ``"top"`` or
|
|
``"bottom"``, fallback for the list view if none of the previous
|
|
two flags are set.
|
|
|
|
These three flags can only *make* a listview editable, they can *not*
|
|
override a previously set flag. To do that, a listview user should
|
|
instead cancel :ref:`the edit:before event <listview-edit-before>`.
|
|
|
|
The editable list view module adds a number of methods to the list
|
|
view, on top of implementing the :js:class:`EditorDelegate` protocol:
|
|
|
|
Interaction Methods
|
|
+++++++++++++++++++
|
|
|
|
.. js:function:: openerp.web.ListView.ensure_saved
|
|
|
|
Attempts to resolve the pending edition, if any, by saving the
|
|
edited row's current state.
|
|
|
|
:returns: delegate resolving to all editions having been saved, or
|
|
rejected if a pending edition could not be saved
|
|
(e.g. validation failure)
|
|
|
|
.. js:function:: openerp.web.ListView.start_edition([record][, options])
|
|
|
|
Starts editing the provided record inline, through an overlay form
|
|
view of editable fields in the record.
|
|
|
|
If no record is provided, creates a new one according to the
|
|
editability configuration of the list view.
|
|
|
|
This method resolves any pending edition when invoked, before
|
|
starting a new edition.
|
|
|
|
:param record: record to edit, or null to create a new record
|
|
:type record: :js:class:`~openerp.web.list.Record`
|
|
:param EditOptions options:
|
|
:returns: delegate to the form used for the edition
|
|
|
|
.. js:function:: openerp.web.ListView.save_edition
|
|
|
|
Resolves the pending edition.
|
|
|
|
:returns: delegate to the save being completed, resolves to an
|
|
object with two attributes ``created`` (flag indicating
|
|
whether the saved record was just created or was
|
|
updated) and ``record`` the reloaded record having been
|
|
edited.
|
|
|
|
.. js:function:: openerp.web.ListView.cancel_edition([force=false])
|
|
|
|
Cancels pending edition, cleans up the list view in case of
|
|
creation (removes the empty record being created).
|
|
|
|
:param Boolean force: doesn't check if the user has added any
|
|
data, discards the edition unconditionally
|
|
|
|
Utility Methods
|
|
+++++++++++++++
|
|
|
|
.. js:function:: openerp.web.ListView.get_cells_for(row)
|
|
|
|
Extracts the cells from a listview row, and puts them in a
|
|
{fieldname: cell} mapping for analysis and manipulation.
|
|
|
|
:param jQuery row:
|
|
:rtype: Object
|
|
|
|
.. js:function:: openerp.web.ListView.with_event(event_name, event, action[, args][, trigger_params])
|
|
|
|
Executes ``action`` in the context of the view's editor,
|
|
bracketing it with cancellable event signals.
|
|
|
|
:param String event_name: base name for the bracketing event, will
|
|
be postfixed by ``:before`` and
|
|
``:after`` before being called
|
|
(respectively before and after
|
|
``action`` is executed)
|
|
:param Object event: object passed to the ``:before`` event
|
|
handlers.
|
|
:param Function action: function called with the view's editor as
|
|
its ``this``. May return a deferred.
|
|
:param Array args: arguments passed to ``action``
|
|
:param Array trigger_params: arguments passed to the ``:after``
|
|
event handler alongside the results
|
|
of ``action``
|
|
|
|
Behavioral Customizations
|
|
+++++++++++++++++++++++++
|
|
|
|
.. js:function:: openerp.web.ListView.handle_onwrite(record)
|
|
|
|
Implements the handling of the ``onwrite`` listview attribute:
|
|
calls the RPC methods specified by ``@onwrite``, and if that
|
|
method returns an array of ids loads or reloads the records
|
|
corresponding to those ids.
|
|
|
|
:param record: record being written having triggered the
|
|
``onwrite`` callback
|
|
:type record: openerp.web.list.Record
|
|
:returns: deferred to all reloadings being done
|
|
|
|
Events
|
|
++++++
|
|
|
|
For simpler interactions by/with external users of the listview, the
|
|
view provides a number of dedicated events to its lifecycle.
|
|
|
|
.. note:: if an event is defined as *cancellable*, it means its first
|
|
parameter is an object on which the ``cancel`` attribute can
|
|
be set. If the ``cancel`` attribute is set, the view will
|
|
abort its current behavior as soon as possible, and rollback
|
|
any state modification.
|
|
|
|
Generally speaking, an event should only be cancelled (by
|
|
setting the ``cancel`` flag to ``true``), uncancelling an
|
|
event is undefined as event handlers are executed on a
|
|
first-come-first-serve basis and later handlers may
|
|
re-cancel an uncancelled event.
|
|
|
|
.. _listview-edit-before:
|
|
|
|
``edit:before`` *cancellable*
|
|
|
|
Invoked before the list view starts editing a record.
|
|
|
|
Provided with an event object with a single property ``record``,
|
|
holding the attributes of the record being edited (``record`` is
|
|
empty *but not null* for a new record)
|
|
|
|
``edit:after``
|
|
|
|
Invoked after the list view has gone into an edition state,
|
|
provided with the attributes of the record being edited (see
|
|
``edit:before``) as first parameter and the form used for the
|
|
edition as second parameter.
|
|
|
|
``save:before`` *cancellable*
|
|
|
|
Invoked right before saving a pending edition, provided with an
|
|
event object holding the listview's editor (``editor``) and the
|
|
edition form (``form``)
|
|
|
|
``save:after``
|
|
|
|
Invoked after a save has been completed
|
|
|
|
``cancel:before`` *cancellable*
|
|
|
|
Invoked before cancelling a pending edition, provided with the
|
|
same information as ``save:before``.
|
|
|
|
``cancel:after``
|
|
|
|
Invoked after a pending edition has been cancelled.
|
|
|
|
DOM events
|
|
++++++++++
|
|
|
|
The list view has grown hooks for the ``keyup`` event on its edition
|
|
form (during edition): any such event bubbling out of the edition form
|
|
will be forwarded to a method ``keyup_EVENTNAME``, where ``EVENTNAME``
|
|
is the name of the key in ``$.ui.keyCode``.
|
|
|
|
The method will also get the event object (originally passed to the
|
|
``keyup`` handler) as its sole parameter.
|
|
|
|
The base editable list view has handlers for the ``ENTER`` and
|
|
``ESCAPE`` keys.
|
|
|
|
Editor
|
|
------
|
|
|
|
The list-edition modules does not generally interact with the embedded
|
|
formview, delegating instead to its
|
|
:js:class:`~openerp.web.list.Editor`.
|
|
|
|
.. js:class:: openerp.web.list.Editor(parent[, options])
|
|
|
|
The editor object provides a more convenient interface to form
|
|
views, and simplifies the usage of form views for semi-arbitrary
|
|
edition of stuff.
|
|
|
|
However, the editor does *not* task itself with being internally
|
|
consistent at this point: calling
|
|
e.g. :js:func:`~openerp.web.list.Editor.edit` multiple times in a
|
|
row without saving or cancelling each edit is undefined.
|
|
|
|
:param parent:
|
|
:type parent: :js:class:`~openerp.web.Widget`
|
|
:param EditorOptions options:
|
|
|
|
.. js:function:: openerp.web.list.Editor.is_editing([record_state])
|
|
|
|
Indicates whether the editor is currently in the process of
|
|
providing edition for a record.
|
|
|
|
Can be filtered by the state of the record being edited
|
|
(whether it's a record being *created* or a record being
|
|
*altered*), in which case it asserts both that an edition is
|
|
underway and that the record being edited respectively does
|
|
not yet exist in the database or already exists there.
|
|
|
|
:param record_state: state of the record being edited.
|
|
Either ``"new"`` or ``"edit"``.
|
|
:type record_state: String
|
|
:rtype: Boolean
|
|
|
|
.. js:function:: openerp.web.list.Editor.edit(record, configureField[, options])
|
|
|
|
Loads the provided record into the internal form view and
|
|
displays the form view.
|
|
|
|
Will also attempt to focus the first visible field of the form
|
|
view.
|
|
|
|
:param Object record: record to load into the form view
|
|
(key:value mapping similar to the result
|
|
of a ``read``)
|
|
:param configureField: function called with each field of the
|
|
form view right after the form is
|
|
displayed, lets whoever called this
|
|
method do some last-minute
|
|
configuration of form fields.
|
|
:type configureField: Function<String, openerp.web.form.Field>
|
|
:param EditOptions options:
|
|
:returns: jQuery delegate to the form object
|
|
|
|
.. js:function:: openerp.web.list.Editor.save
|
|
|
|
Attempts to save the internal form, then hide it
|
|
|
|
:returns: delegate to the record under edition (with ``id``
|
|
added for a creation). The record is not updated
|
|
from when it was passed in, aside from the ``id``
|
|
attribute.
|
|
|
|
.. js:function:: openerp.web.list.Editor.cancel([force=false])
|
|
|
|
Attemps to cancel the edition of the internal form, then hide
|
|
the form
|
|
|
|
:param Boolean force: unconditionally cancels the edition of
|
|
the internal form, even if the user has
|
|
already entered data in it.
|
|
:returns: delegate to the record under edition
|
|
|
|
.. js:class:: EditorOptions
|
|
|
|
.. js:attribute:: EditorOptions.formView
|
|
|
|
Form view (sub)-class to instantiate and delegate edition to.
|
|
|
|
By default, :js:class:`~openerp.web.FormView`
|
|
|
|
.. js:attribute:: EditorOptions.delegate
|
|
|
|
Object used to get various bits of information about how to
|
|
display stuff.
|
|
|
|
By default, uses the editor's parent widget. See
|
|
:js:class:`EditorDelegate` for the methods and attributes to
|
|
provide.
|
|
|
|
.. js:class:: EditorDelegate
|
|
|
|
Informal protocol defining the methods and attributes expected of
|
|
the :js:class:`~openerp.web.list.Editor`'s delegate.
|
|
|
|
.. js:attribute:: EditorDelegate.dataset
|
|
|
|
The dataset passed to the form view to synchronize the form
|
|
view and the outer widget.
|
|
|
|
.. js:function:: EditorDelegate.edition_view(editor)
|
|
|
|
Called by the :js:class:`~openerp.web.list.Editor` object to
|
|
get a form view (JSON) to pass along to the form view it
|
|
created.
|
|
|
|
The result should be a valid form view, see :doc:`Form Notes
|
|
<form_view>` for various peculiarities of the form view
|
|
format.
|
|
|
|
:param editor: editor object asking for the view
|
|
:type editor: :js:class:`~openerp.web.list.Editor`
|
|
:returns: form view
|
|
:rtype: Object
|
|
|
|
.. js:function:: EditorDelegate.prepends_on_create
|
|
|
|
By default, the :js:class:`~openerp.web.list.Editor` will
|
|
append the ids of newly created records to the
|
|
:js:attr:`EditorDelegate.dataset`. If this method returns
|
|
``true``, it will prepend these ids instead.
|
|
|
|
:returns: whether new records should be prepended to the
|
|
dataset (instead of appended)
|
|
:rtype: Boolean
|
|
|
|
|
|
.. js:class:: EditOptions
|
|
|
|
Options object optionally passed into a method starting an edition
|
|
to configure its setup and behavior
|
|
|
|
.. js:attribute:: focus_field
|
|
|
|
Name of the field to set focus on after setting up the edition
|
|
of the record.
|
|
|
|
If this option is not provided, or the requested field can not
|
|
be focused (invisible, readonly or not in the view), the first
|
|
visible non-readonly field is focused.
|
|
|
|
Changes from 6.1
|
|
----------------
|
|
|
|
* The editable listview behavior has been rewritten pretty much from
|
|
scratch, any code touching on editability will have to be modified
|
|
|
|
* The overloading of :js:class:`~openerp.web.ListView.Groups` and
|
|
:js:class:`~openerp.web.ListView.List` for editability has been
|
|
drastically simplified, and most of the behavior has been moved to
|
|
the list view itself. Only
|
|
:js:func:`~openerp.web.ListView.List.row_clicked` is still
|
|
overridden.
|
|
|
|
* A new method ``get_row_for(record) -> jQuery(tr) | null`` has been
|
|
added to both ListView.List and ListView.Group, it can be called
|
|
from the list view to get the table row matching a record (if such
|
|
a row exists).
|
|
|
|
* :js:func:`~openerp.web.ListView.do_button_action`'s core behavior
|
|
has been split away to
|
|
:js:func:`~openerp.web.ListView.handle_button`. This allows bypassing
|
|
overrides of :js:func:`~openerp.web.ListView.do_button_action` in a
|
|
parent class.
|
|
|
|
Ideally, :js:func:`~openerp.web.ListView.handle_button` should not be
|
|
overridden.
|
|
|
|
* Modifiers handling has been improved (all modifiers information
|
|
should now be available through :js:func:`~Column.modifiers_for`,
|
|
not just ``invisible``)
|
|
|
|
* Changed some handling of the list view's record: a record may now
|
|
have no id, and the listview will handle that correctly (for new
|
|
records being created) as well as correctly handle the ``id`` being
|
|
set.
|
|
|
|
* Extended the internal collections structure of the list view with
|
|
`#find`_, `#succ`_ and `#pred`_.
|
|
|
|
.. _#find: http://underscorejs.org/#find
|
|
|
|
.. _#succ: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:succ
|
|
|
|
.. _#pred: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:pred
|