4 OpenERP Web 6.2 implements a unified facets-based search view instead
5 of the previous form-like search view (composed of buttons and
6 multiple fields). The goal for this change is twofold:
8 * Avoid the common issue of users confusing the search view with a
9 form view and trying to create their records through it (or entering
10 all their data, hitting the ``Create`` button expecting their record
11 to be created and losing everything).
13 * Improve the looks and behaviors of the view, and the fit within
14 OpenERP Web's new design.
16 The faceted search is implemented through a monkey-patched
17 `VisualSearch <http://documentcloud.github.com/visualsearch/>`_
18 [#]_. VisualSearch is based on `Backbone
19 <http://documentcloud.github.com/backbone/>`_ and makes significant
20 use of Backbone's models and views. As a result, understanding the
21 implementation of the OpenERP Web 6.2 search view also requires a
22 basic understanding of Backbone.
26 This document may mention *fetching* data. This is a shortcut for
27 "returning a deferred to [whatever is being fetched]". Unless
28 further noted, the function or method may opt to return nothing by
29 fetching ``null`` (which can easily be done by returning
30 ``$.when(null)``, which simply wraps the ``null`` in a Deferred).
32 Interaction between the Search View and VisualSearch
33 ----------------------------------------------------
35 The core data abstraction in VisualSearch is
36 :js:class:`VS.model.SearchQuery`, a backbone Collection holding
37 instances of the :js:class:`VS.model.SearchFacet` backbone Model.
39 Backbone models can hold any number of informal properties interacted
40 with through the :js:func:`~Backbone.Model.get` and
41 :js:func:`~Backbone.Model.set` methods. VisualSearch reserves three
42 such properties for its behavior, these properties *must* be correctly
43 set on all search facets created programmatically:
46 a reference to the VisualSearch instance using this facet. In the
47 search view, this instance is available as the
48 :js:attr:`~openerp.web.SearchView.vs` attribute to the searchview
52 the *name* of the facet, displayed in the first section of a facet
56 the *displayed value* of the facet, it is directly printed to the
57 right of the category.
59 The search view uses additional keys to store state and data it needs
60 to associate with facet objects:
63 the search field instance which created the facet, used when the
64 search view needs to serialize the facets.
67 the "logical" value of the facet, can be absent if the logical and
68 "printable" values of the facet are the same (e.g. for a basic text
71 This value may be a complex javascript object such as an array (the
72 name stands for json-compatible value, it is not a JSON-encoded
77 in order to simplify getting the logical value of a search facet
78 model, :js:class:`VS.model.SearchFacet` has been extended with a
79 :js:func:`~VS.model.SearchFacet.value` method
81 Extensions and patches to VisualSearch
82 ++++++++++++++++++++++++++++++++++++++
84 .. js:function:: VS.model.SearchFacet.value()
86 Bundles the logic of selecting between ``json`` and ``value`` in
87 order to get the logical value of a facet.
89 .. js:attribute:: VS.options.callbacks.make_facet
91 Called by :js:class:`VS.ui.SearchBox` when it needs to create a
92 new search facet *view*. By default this is not supported by
93 VisualSearch, and requires monkey-patching
94 :js:func:`VS.ui.SearchBox.renderFacet`.
96 This patch should not alter any behavior if
97 :js:attr:`~VS.options.callbacks.make_facet` is not used.
99 .. js:attribute:: VS.options.callbacks.make_input
101 Similar to :js:attr:`~VS.options.callbacks.make_facet`, but called
102 when the :js:class:`~VS.ui.SearchBox` needs to create a search
103 input view. It requires monkey-patching
104 :js:func:`VS.ui.SearchBox.renderSearchInput`.
106 Finally, :js:func:`VS.ui.SearchBox.searchEvent` is monkey-patched to
107 get rid of its serialize/load round-tripping of facet data: the
108 additional attributes needed by the search view don't round-trip (at
109 all) so VisualSearch must not load any data from its (fairly
110 simplistic) text-serialization format.
114 a second issue is that — as of `commit 3fca87101d`_ — VisualSearch
115 correctly serializes facet categories containing spaces but is
116 unable to load them back in. It also does not handle facets with
117 *empty* categories correctly.
122 After loading the view data, the SearchView will call
123 :js:func:`openerp.web.search.Input.facet_for_defaults` on each of its
124 inputs with the ``defaults`` mapping of key:values (where each key
125 corresponds to an input). This method should look into the
126 ``defaults`` mapping and fetch the field's default value as a
127 :js:class:`~VS.models.SearchFacet` if applicable.
129 The default implementation is to check if there is a default value for
130 the current input's name (via
131 :js:attr:`openerp.web.search.Input.attrs.name`) and if there is to
132 convert this value to a :js:class:`~VS.models.SearchFacet` by calling
133 :js:func:`openerp.web.search.Input.facet_for`.
135 There is no built-in (default) implementation of
136 :js:func:`openerp.web.search.Input.facet_for`. This method should
137 fetch the :js:class:`~VS.models.SearchFacet` corresponding to the
138 "raw" value passed as argument.
140 Providing auto-completion
141 -------------------------
143 An important component of the unified search view is the faceted
144 autocompletion pane. In order to provide good user and developer
145 experiences, this pane is pluggable (value-wise): each and every
146 control of the search view can check for (and provide) categorized
147 auto-completions for a given value being typed by the user.
149 This is done by implementing
150 :js:func:`openerp.web.search.Input.complete`: the method is provided
151 with a value to complete, and should fetch an ``Array`` of completion
152 values. These completion values will then be provided to the global
153 autocompletion list, implemented via `jquery-ui autocomplete
154 <http://jqueryui.com/demos/autocomplete/>`_.
156 Because the search view uses a custom renderer for its completion, it
157 was possible to fix some incompatibilities between the attributes of
158 completion items and VisualSearch's facet model:
160 Actual completion items
161 +++++++++++++++++++++++
163 These are selectable items, and upon selection are turned into actual
164 search facet objects. They should have all the properties of a search
165 facet (as described above) and can have one more optional property:
168 When rendering an item in the list, the renderer will first try to use
169 the ``label`` property if it exists (``label`` can contain HTML and
170 will be inserted as-is, so it can bold or emphasize some of its
171 elements), if it does not the ``value`` property will be used.
173 .. note:: the ``app`` key should not be specified on completion item,
174 it will be set automatically when the search view creates
175 the facet from the item.
180 A second kind of completion values is the section titles. Section
181 titles are similar to completion items but only have a ``category``
182 property. They will be rendered in a different style and can not be
183 selected in the auto-completion (they will be skipped).
187 Technically, section title items can have any property they want
188 *as long as they do not have a value property*. A ``value``
189 property set to ``false``, ``null`` or ``undefined`` is **not**
190 equivalent to not having a ``value`` property.
192 If an input *may* fetch more than one completion item, it *should*
193 prepend a section title (using its own name) to the completion items.
195 Converting from facet objects
196 -----------------------------
198 Ultimately, the point of the search view is to allow searching. In
199 OpenERP this is done via :ref:`domains <openerpserver:domains>`. On
200 the other hand, the OpenERP Web 6.2 search view's state is modelled
201 after a collection of :js:class:`~VS.model.SearchFacet`, and each
202 field of a search view may have special requirements when it comes to
203 the domains it produces [#]_.
205 So there needs to be some way of mapping
206 :js:class:`~VS.model.SearchFacet` objects to OpenERP search data.
208 This is done via an input's
209 :js:func:`~openerp.web.search.Input.get_domain` and
210 :js:func:`~openerp.web.search.Input.get_context`. Each takes a
211 :js:class:`~VS.model.SearchFacet` and returns whatever it's supposed
212 to generate (a domain or a context, respectively). Either can return
213 ``null`` if the current value does not map to a domain or context, and
214 can throw an :js:class:`~openerp.web.search.Invalid` exception if the
215 value is not valid at all for the field.
217 Converting to facet objects
218 ---------------------------
223 .. todo:: merge in changelog instead
225 The displaying of the search view was significantly altered from
226 OpenERP Web 6.1 to OpenERP Web 6.2.
228 As a result, while the external API used to interact with the search
229 view does not change many internal details — including the interaction
230 between the search view and its widgets — were significantly altered:
235 * :js:func:`openerp.web.SearchView.do_clear` has been removed
236 * :js:func:`openerp.web.SearchView.do_toggle_filter` has been removed
241 * :js:func:`openerp.web.search.Widget.render` has been removed
243 * :js:func:`openerp.web.search.Widget.make_id` has been removed
245 * Search field objects are not openerp widgets anymore, their
246 ``start`` is not generally called
248 * :js:func:`~openerp.web.search.Input.clear` has been removed since
249 clearing the search view now simply consists of removing all search
250 facets from VisualSearch
252 * :js:func:`~openerp.web.search.Input.get_domain` and
253 :js:func:`~openerp.web.search.Input.get_context` now take a
254 :js:class:`~VS.model.SearchFacet` as parameter, from which it's
255 their job to get whatever value they want
257 * :js:func:`~openerp.web.search.Input.get_groupby` has been added. It returns
258 an :js:class:`Array` of context-like constructs. By default, it does not do
259 anything in :js:class:`~openerp.web.search.Field` and it returns the various
260 contexts of its enabled filters in
261 :js:class:`~openerp.web.search.FilterGroup`.
266 * :js:func:`openerp.web.search.Filter.is_enabled` has been removed
268 * :js:class:`~openerp.web.search.FilterGroup` instances are still
269 rendered (and started) in the "advanced search" drawer.
274 * ``get_value`` now takes a :js:class:`~VS.model.SearchFacet` (instead
275 of taking no argument).
277 A default implementation is provided as
278 :js:func:`openerp.web.search.Field.get_value` and simply calls
279 :js:func:`VS.model.SearchFacet.value`.
281 * The third argument to
282 :js:func:`~openerp.web.search.Field.make_domain` is now the
283 :js:class:`~VS.model.SearchFacet` received by
284 :js:func:`~openerp.web.search.Field.get_domain`, so child classes
285 have all the information they need to derive the "right" resulting
291 Instead of being an intrinsic part of the search view, custom filters
292 are now a special case of filter groups. They are treated specially
293 still, but much less so than they used to be.
298 * Because the autocompletion service is now provided by the search
300 :js:func:`openerp.web.search.ManyToOneField.setup_autocomplete` has
303 .. [#] the library code is untouched, all patching is performed in the
304 Search view's implementation module. Changes to the
305 VisualSearch code should only update the library to new
306 revisions or releases.
307 .. [#] search view fields may also bundle context data to add to the
310 .. _commit 3fca87101d:
311 https://github.com/documentcloud/visualsearch/commit/3fca87101d