* Improve the looks and behaviors of the view, and the fit within
OpenERP Web's new design.
-The faceted search is implemented through a monkey-patched
+The internal structure of the faceted search is inspired by
`VisualSearch <http://documentcloud.github.com/visualsearch/>`_
-[#]_. VisualSearch is based on `Backbone
-<http://documentcloud.github.com/backbone/>`_ and makes significant
-use of Backbone's models and views. As a result, understanding the
-implementation of the OpenERP Web 6.2 search view also requires a
-basic understanding of Backbone.
+[#previous]_.
+
+As does VisualSearch, the new search view is based on `Backbone`_ and
+makes significant use of Backbone's models and collections (OpenERP
+Web's widgets make a good replacement for Backbone's own views). As a
+result, understanding the implementation details of the OpenERP Web 7
+search view also requires a basic understanding of Backbone's models,
+collections and events.
.. note::
This document may mention *fetching* data. This is a shortcut for
- "returning a deferred to [whatever is being fetched]". Unless
- further noted, the function or method may opt to return nothing by
- fetching ``null`` (which can easily be done by returning
- ``$.when(null)``, which simply wraps the ``null`` in a Deferred).
-
-Interaction between the Search View and VisualSearch
-----------------------------------------------------
-
-The core data abstraction in VisualSearch is
-:js:class:`VS.model.SearchQuery`, a backbone Collection holding
-instances of the :js:class:`VS.model.SearchFacet` backbone Model.
-
-Backbone models can hold any number of informal properties interacted
-with through the :js:func:`~Backbone.Model.get` and
-:js:func:`~Backbone.Model.set` methods. VisualSearch reserves three
-such properties for its behavior, these properties *must* be correctly
-set on all search facets created programmatically:
-
-``app``
- a reference to the VisualSearch instance using this facet. In the
- search view, this instance is available as the
- :js:attr:`~openerp.web.SearchView.vs` attribute to the searchview
- instance.
-
-``category``
- the *name* of the facet, displayed in the first section of a facet
- view. The category *may* be ``null``.
-
-``value``
- the *displayed value* of the facet, it is directly printed to the
- right of the category.
-
-The search view uses additional keys to store state and data it needs
-to associate with facet objects:
-
-``field``
- the search field instance which created the facet, optional. May or
- may not be inferrable from ``category``.
-
-``json``
- the "logical" value of the facet, can be absent if the logical and
- "printable" values of the facet are the same (e.g. for a basic text
- field).
-
- This value may be a complex javascript object such as an array or an
- object (the name stands for json-compatible value, it is not
- JSON-encoded).
+ "returning a :js:class:`Deferred` to [whatever is being
+ fetched]". Unless further noted, the function or method may opt to
+ return nothing by fetching ``null`` (which can easily be done by
+ returning ``$.when(null)``, which simply wraps the ``null`` in a
+ Deferred).
+
+Working with the search view: creating new inputs
+-------------------------------------------------
+
+The primary component of search views, as with all other OpenERP
+views, are inputs. The search view has two types of inputs — filters
+and fields — but only one is easly customizable: fields.
-.. note::
+The mapping from OpenERP field types (and widgets) to search view
+objects is stored in the ``openerp.web.search.fields``
+:js:class:`~openerp.web.Registry` where new field types and widgets
+can be added.
- in order to simplify getting the logical value of a search facet
- model, :js:class:`VS.model.SearchFacet` has been extended with a
- :js:func:`~VS.model.SearchFacet.value` method
+Search view inputs have four main roles:
-Extensions and patches to VisualSearch
-++++++++++++++++++++++++++++++++++++++
+Loading defaults
+++++++++++++++++
-.. js:function:: VS.model.SearchFacet.value()
+Once the search view has initialized all its inputs, it will call
+:js:func:`~openerp.web.search.Input.facet_for_defaults` on each input,
+passing it a mapping (a javascript object) of ``name:value`` extracted
+from the action's context.
- Bundles the logic of selecting between ``json`` and ``value`` in
- order to get the logical value of a facet.
+This method should fetch a :js:class:`~openerp.web.search.Facet` (or
+an equivalent object) for the field's default value if applicable (if
+a default value for the field is found in the ``defaults`` mapping).
-.. js:attribute:: VS.options.callbacks.make_facet
+A default implementation is provided which checks if ``defaults``
+contains a non-falsy value for the field's ``@name`` and calls
+:js:func:`openerp.web.search.Input.facet_for` with that value.
- Called by :js:class:`VS.ui.SearchBox` when it needs to create a
- new search facet *view*. By default this is not supported by
- VisualSearch, and requires monkey-patching
- :js:func:`VS.ui.SearchBox.renderFacet`.
+There is no default implementation of
+:js:func:`openerp.web.search.Input.facet_for` [#no_impl]_, but
+:js:class:`openerp.web.search.Field` provides one, which uses the
+value as-is to fetch a :js:class:`~openerp.web.search.Facet`.
- This patch should not alter any behavior if
- :js:attr:`~VS.options.callbacks.make_facet` is not used.
+Providing completions
++++++++++++++++++++++
-.. js:attribute:: VS.options.callbacks.make_input
+An important component of the new search view is the auto-completion
+pane, and the task of providing completion items is delegated to
+inputs through the :js:func:`~openerp.web.search.Input.complete`
+method.
- Similar to :js:attr:`~VS.options.callbacks.make_facet`, but called
- when the :js:class:`~VS.ui.SearchBox` needs to create a search
- input view. It requires monkey-patching
- :js:func:`VS.ui.SearchBox.renderSearchInput`.
+This method should take a single argument (the string being typed by
+the user) and should fetch an ``Array`` of possible completions
+[#completion]_.
-Finally, :js:func:`VS.ui.SearchBox.searchEvent` is monkey-patched to
-get rid of its serialize/load round-tripping of facet data: the
-additional attributes needed by the search view don't round-trip (at
-all) so VisualSearch must not load any data from its (fairly
-simplistic) text-serialization format.
+A default implementation is provided which fetches nothing.
-.. note::
+A completion item is a javascript object with two keys (technically it
+can have any number of keys, but only these two will be used by the
+search view):
- a second issue is that — as of `commit 3fca87101d`_ — VisualSearch
- correctly serializes facet categories containing spaces but is
- unable to load them back in. It also does not handle facets with
- *empty* categories correctly.
-
-Loading Defaults
-----------------
-
-After loading the view data, the SearchView will call
-:js:func:`openerp.web.search.Input.facet_for_defaults` with the
-``defaults`` mapping of key:values (where each key corresponds to an
-input). This method should look into the ``defaults`` mapping and
-fetch the field's default value as a
-:js:class:`~VS.models.SearchFacet` if applicable.
-
-The default implementation is to check if there is a default value for
-the current input's name (via
-:js:attr:`openerp.web.search.Input.attrs.name`) and if there is to
-convert this value to a :js:class:`~VS.models.SearchFacet` by calling
-:js:func:`openerp.web.search.Input.facet_for`.
-
-There is no built-in (default) implementation of
-:js:func:`openerp.web.search.Input.facet_for`. This method should
-fetch the :js:class:`~VS.models.SearchFacet` corresponding to the
-"raw" value passed as argument.
-
-Providing auto-completion
--------------------------
-
-An important component of the unified search view is the faceted
-autocompletion pane. In order to provide good user and developer
-experiences, this pane is pluggable (value-wise): each and every
-control of the search view can check for (and provide) categorized
-auto-completions for a given value being typed by the user.
-
-This is done by implementing
-:js:func:`openerp.web.search.Input.complete`: the method is provided
-with a value to complete, and should fetch an ``Array`` of completion
-values. These completion values will then be provided to the global
-autocompletion list, implemented via `jquery-ui autocomplete
-<http://jqueryui.com/demos/autocomplete/>`_.
-
-Because the search view uses a custom renderer for its completion, it
-was possible to fix some incompatibilities between the attributes of
-completion items and VisualSearch's facet model:
-
-Actual completion items
-+++++++++++++++++++++++
-
-These are selectable items, and upon selection are turned into actual
-search facet objects. They should have all the properties of a search
-facet (as described above) and can have one more optional property:
-``label``.
-
-When rendering an item in the list, the renderer will first try to use
-the ``label`` property if it exists (``label`` can contain HTML and
-will be inserted as-is, so it can bold or emphasize some of its
-elements), if it does not it'll use the ``value`` property.
-
-.. note:: the ``app`` key should not be specified on completion item,
- it will be set automatically when the search view creates
- the facet from the item.
-
-Section titles
-++++++++++++++
+``label``
+
+ The string which will be displayed in the completion pane. It may
+ be formatted using HTML (inline only), as a result if ``value`` is
+ interpolated into it it *must* be escaped. ``_.escape`` can be
+ used for this.
+
+``facet``
+
+ Either a :js:class:`~openerp.web.search.Facet` object or (more
+ commonly) the corresponding attributes object. This is the facet
+ which will be inserted into the search query if the completion
+ item is selected by the user.
+
+If the ``facet`` is not provided (not present, ``null``, ``undefined``
+or any other falsy value), the completion item will not be selectable
+and will act as a section title of sort (the ``label`` will be
+formatted differently). If an input *may* fetch multiple completion
+items, it *should* prefix those with a section title using its own
+name. This has no technical consequence but is clearer for users.
+
+Providing drawer/supplementary UI
++++++++++++++++++++++++++++++++++
+
+For some inputs (fields or not), interaction via autocompletion may be
+awkward or even impossible.
+
+These may opt to being rendered in a "drawer" as well or instead. In
+that case, they will undergo the normal widget lifecycle and be
+rendered inside the drawer.
+
+.. Found no good type-based way to handle this, since there is no MI
+ (so no type-tagging) and it's possible for both Field and non-Field
+ input to be put into the drawer, for whatever reason (e.g. some
+ sort of auto-detector completion item for date widgets, but a
+ second more usual calendar widget in the drawer for more
+ obvious/precise interactions)
+
+Any input can note its desire to be rendered in the drawer by
+returning a truthy value from
+:js:func:`~openerp.web.search.Input.in_drawer`.
+
+By default, :js:func:`~openerp.web.search.Input.in_drawer` returns the
+value of :js:attr:`~openerp.web.search.Input._in_drawer`, which is
+``false``. The behavior can be toggled either by redefining the
+attribute to ``true`` (either on the class or on the input), or by
+overriding :js:func:`~openerp.web.search.Input.in_drawer` itself.
+
+The input will be rendered in the full width of the drawer, it will be
+started only once (per view).
+
+.. todo:: drawer API (if a widget wants to close the drawer in some
+ way), part of the low-level SearchView API/interactions?
+
+
+.. todo:: handle filters and filter groups via a "driver" input which
+ dynamically collects, lays out and renders filters? =>
+ exercises drawer thingies
+
+Programmatic interactions: internal model
+-----------------------------------------
+
+This new searchview is built around an instance of
+:js:class:`~openerp.web.search.SearchQuery` available as
+:js:attr:`openerp.web.SearchView.query`.
+
+The query is a `backbone collection`_ of
+:js:class:`~openerp.web.search.Facet` objects, which can be interacted
+with directly by external objects or search view controls
+(e.g. widgets displayed in the drawer).
+
+.. js:class:: openerp.web.search.SearchQuery
+
+ The current search query of the search view, provides convenience
+ behaviors for manipulating :js:class:`~openerp.web.search.Facet`
+ on top of the usual `backbone collection`_ methods.
+
+ The query ensures all of its facets contain at least one
+ :js:class:`~openerp.web.search.FacetValue` instance. Otherwise,
+ the facet is automatically removed from the query.
+
+ .. js:function:: openerp.web.search.SearchQuery.add(values, options)
+
+ Overridden from the base ``add`` method so that adding a facet
+ which is *already* in the collection will merge the value of
+ the new facet into the old one rather than add a second facet
+ with different values.
+
+ :param values: facet, facet attributes or array thereof
+ :returns: the collection itself
+
+ .. js:function:: openerp.web.search.SearchQuery.toggle(value, options)
+
+ Convenience method for toggling facet values in a query:
+ removes the values (through the facet itself) if they are
+ present, adds them if they are not. If the facet itself is not
+ in the collection, adds it automatically.
+
+ A toggling is atomic: only one change event will be triggered
+ on the facet regardless of the number of values added to or
+ removed from the facet (if the facet already exists), and the
+ facet is only removed from the query if it has no value *at
+ the end* of the toggling.
+
+ :param value: facet or facet attributes
+ :returns: the collection
+
+.. js:class:: openerp.web.search.Facet
+
+ A `backbone model`_ representing a single facet of the current
+ research. May map to a search field, or to a more complex or
+ fuzzier input (e.g. a custom filter or an advanced search).
+
+ .. js:attribute:: category
+
+ The displayed name of the facet, as a ``String``. This is a
+ backbone model attribute.
+
+ .. js:attribute:: field
+
+ The :js:class:`~openerp.web.search.Input` instance which
+ originally created the facet [#facet-field]_, used to delegate
+ some operations (such as serializing the facet's values to
+ domains and contexts). This is a backbone model attribute.
+
+ .. js:attribute:: values
+
+ :js:class:`~openerp.web.search.FacetValues` as a javascript
+ attribute, stores all the values for the facet and helps
+ propagate their events to the facet. Is also available as a
+ backbone attribute (via ``#get`` and ``#set``) in which cases
+ it serializes to and deserializes from javascript arrays (via
+ ``Collection#toJSON`` and ``Collection#reset``).
+
+ .. js:attribute:: [icon]
+
+ optional, a single ASCII letter (a-z or A-Z) mapping to the
+ bundled mnmliconsRegular icon font.
+
+ When a facet with an ``icon`` attribute is rendered, the icon
+ is displayed (in the icon font) in the first section of the
+ facet instead of the ``category``.
+
+ By default, only filters make use of this facility.
+
+.. js:class:: openerp.web.search.FacetValues
+
+ `Backbone collection`_ of
+ :js:class:`~openerp.web.search.FacetValue` instances.
+
+.. js:class:: openerp.web.search.FacetValue
-A second option is to use section titles. Section titles are similar
-to completion items but only have a ``category`` property. They will
-be rendered in a different style and can not be selected in the
-auto-completion (they will be skipped).
+ `Backbone model`_ representing a single value within a facet,
+ represents a pair of (displayed name, logical value).
+
+ .. js:attribute:: label
+
+ Backbone model attribute storing the "displayable"
+ representation of the value, visually output to the
+ user. Must be a string.
+
+ .. js:attribute:: value
+
+ Backbone model attribute storing the logical/internal value
+ (of itself), will be used by
+ :js:class:`~openerp.web.search.Input` to serialize to domains
+ and contexts.
+
+ Can be of any type.
+
+Converting from facet objects
+-----------------------------
+
+Ultimately, the point of the search view is to allow searching. In
+OpenERP this is done via :ref:`domains <openerpserver:domains>`. On
+the other hand, the OpenERP Web 7 search view's state is modelled
+after a collection of :js:class:`~openerp.web.search.Facet`, and each
+field of a search view may have special requirements when it comes to
+the domains it produces [#special]_.
+
+So there needs to be some way of mapping
+:js:class:`~openerp.web.search.Facet` objects to OpenERP search data.
+
+This is done via an input's
+:js:func:`~openerp.web.search.Input.get_domain` and
+:js:func:`~openerp.web.search.Input.get_context`. Each takes a
+:js:class:`~openerp.web.search.Facet` and returns whatever it's
+supposed to generate (a domain or a context, respectively). Either can
+return ``null`` if the current value does not map to a domain or
+context, and can throw an :js:class:`~openerp.web.search.Invalid`
+exception if the value is not valid at all for the field.
.. note::
- Technically, section title items can have any property they want
- *as long as they do not have a value property*. A ``value``
- property set to ``false``, ``null`` or ``undefined`` is **not**
- equivalent to not having a ``value`` property.
+ The :js:class:`~openerp.web.search.Facet` object can have any
+ number of values (from 1 upwards)
-If an input *may* fetch more than one completion item, it *should*
-prepend a section title (using its own name) to the completion items.
+.. note::
+
+ There is a third conversion method,
+ :js:func:`~openerp.web.search.Input.get_groupby`, which returns an
+ ``Array`` of groupby domains rather than a single context. At this
+ point, it is only implemented on (and used by) filters.
-Converting to and from facet objects
-------------------------------------
+Field services
+++++++++++++++
+
+:js:class:`~openerp.web.search.Field` provides a default
+implementation of :js:func:`~openerp.web.search.Input.get_domain` and
+:js:func:`~openerp.web.search.Input.get_context` taking care of most
+of the peculiarities pertaining to OpenERP's handling of fields in
+search views. It also provides finer hooks to let developers of new
+fields and widgets customize the behavior they want without
+necessarily having to reimplement all of
+:js:func:`~openerp.web.search.Input.get_domain` or
+:js:func:`~openerp.web.search.Input.get_context`:
+
+.. js:function:: openerp.web.search.Field.get_context(facet)
+
+ If the field has no ``@context``, simply returns
+ ``null``. Otherwise, calls
+ :js:func:`~openerp.web.search.Field.value_from` once for each
+ :js:class:`~openerp.web.search.FacetValue` of the current
+ :js:class:`~openerp.web.search.Facet` (in order to extract the
+ basic javascript object from the
+ :js:class:`~openerp.web.search.FacetValue` then evaluates
+ ``@context`` with each of these values set as ``self``, and
+ returns the union of all these contexts.
+
+ :param facet:
+ :type facet: openerp.web.search.Facet
+ :returns: a context (literal or compound)
+
+.. js:function:: openerp.web.search.Field.get_domain(facet)
+
+ If the field has no ``@filter_domain``, calls
+ :js:func:`~openerp.web.search.Field.make_domain` once with each
+ :js:class:`~openerp.web.search.FacetValue` of the current
+ :js:class:`~openerp.web.search.Facet` as well as the field's
+ ``@name`` and either its ``@operator`` or
+ :js:attr:`~openerp.web.search.Field.default_operator`.
+
+ If the field has an ``@filter_value``, calls
+ :js:func:`~openerp.web.search.Field.value_from` once per
+ :js:class:`~openerp.web.search.FacetValue` and evaluates
+ ``@filter_value`` with each of these values set as ``self``.
+
+ In either case, "ors" all of the resulting domains (using ``|``)
+ if there is more than one
+ :js:class:`~openerp.web.search.FacetValue` and returns the union
+ of the result.
+
+ :param facet:
+ :type facet: openerp.web.search.Facet
+ :returns: a domain (literal or compound)
+
+.. js:function:: openerp.web.search.Field.make_domain(name, operator, facetValue)
+
+ Builds a literal domain from the provided data. Calls
+ :js:func:`~openerp.web.search.Field.value_from` on the
+ :js:class:`~openerp.web.search.FacetValue` and evaluates and sets
+ it as the domain's third value, uses the other two parameters as
+ the first two values.
+
+ Can be overridden to build more complex default domains.
+
+ :param String name: the field's name
+ :param String operator: the operator to use in the field's domain
+ :param facetValue:
+ :type facetValue: openerp.web.search.FacetValue
+ :returns: Array<(String, String, Object)>
+
+.. js:function:: openerp.web.search.Field.value_from(facetValue)
+
+ Extracts a "bare" javascript value from the provided
+ :js:class:`~openerp.web.search.FacetValue`, and returns it.
+
+ The default implementation will simply return the ``value``
+ backbone property of the argument.
+
+ :param facetValue:
+ :type facetValue: openerp.web.search.FacetValue
+ :returns: Object
+
+.. js:attribute:: openerp.web.search.Field.default_operator
+
+ Operator used to build a domain when a field has no ``@operator``
+ or ``@filter_domain``. ``"="`` for
+ :js:class:`~openerp.web.search.Field`
+
+Arbitrary data storage
+++++++++++++++++++++++
+
+:js:class:`~openerp.web.search.Facet` and
+:js:class:`~openerp.web.search.FacetValue` objects (and structures)
+provided by your widgets should never be altered by the search view
+(or an other widget). This means you are free to add arbitrary fields
+in these structures if you need to (because you have more complex
+needs than the attributes described in this document).
+
+Ideally this should be avoided, but the possibility remains.
Changes
-------
-.. todo:: merge in changelog instead
+.. todo:: merge in changelog instead?
The displaying of the search view was significantly altered from
-OpenERP Web 6.1 to OpenERP Web 6.2.
+OpenERP Web 6.1 to OpenERP Web 7.
As a result, while the external API used to interact with the search
-view does not change the internal details — including the interaction
-between the search view and its widgets — is significantly altered:
+view does not change many internal details — including the interaction
+between the search view and its widgets — were significantly altered:
+
+Internal operations
++++++++++++++++++++
+
+* :js:func:`openerp.web.SearchView.do_clear` has been removed
+* :js:func:`openerp.web.SearchView.do_toggle_filter` has been removed
Widgets API
+++++++++++
* :js:func:`openerp.web.search.Widget.render` has been removed
+* :js:func:`openerp.web.search.Widget.make_id` has been removed
+
* Search field objects are not openerp widgets anymore, their
``start`` is not generally called
+* :js:func:`~openerp.web.search.Input.clear` has been removed since
+ clearing the search view now simply consists of removing all search
+ facets
+
+* :js:func:`~openerp.web.search.Input.get_domain` and
+ :js:func:`~openerp.web.search.Input.get_context` now take a
+ :js:class:`~openerp.web.search.Facet` as parameter, from which it's
+ their job to get whatever value they want
+
+* :js:func:`~openerp.web.search.Input.get_groupby` has been added. It returns
+ an :js:class:`Array` of context-like constructs. By default, it does not do
+ anything in :js:class:`~openerp.web.search.Field` and it returns the various
+ contexts of its enabled filters in
+ :js:class:`~openerp.web.search.FilterGroup`.
+
Filters
+++++++
* :js:func:`openerp.web.search.Filter.is_enabled` has been removed
+* :js:class:`~openerp.web.search.FilterGroup` instances are still
+ rendered (and started) in the "advanced search" drawer.
+
+Fields
+++++++
+
+* ``get_value`` has been replaced by
+ :js:func:`~openerp.web.search.Field.value_from` as it now takes a
+ :js:class:`~openerp.web.search.FacetValue` argument (instead of no
+ argument). It provides a default implementation returning the
+ ``value`` property of its argument.
+
+* The third argument to
+ :js:func:`~openerp.web.search.Field.make_domain` is now a
+ :js:class:`~openerp.web.search.FacetValue` so child classes have all
+ the information they need to derive the "right" resulting domain.
+
+Custom filters
+++++++++++++++
+
+Instead of being an intrinsic part of the search view, custom filters
+are now a special case of filter groups. They are treated specially
+still, but much less so than they used to be.
+
Many To One
+++++++++++
:js:func:`openerp.web.search.ManyToOneField.setup_autocomplete` has
been removed.
-.. [#] the library code is untouched, all patching is performed in the
- Search view's implementation module. Changes to the
- VisualSearch code should only update the library to new
- revisions or releases.
+Advanced Search
++++++++++++++++
+
+* The advanced search is now a more standard
+ :js:class:`~openerp.web.search.Input` configured to be rendered in
+ the drawer.
+
+* :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` are
+ now standard widgets, with the "right" behaviors (they don't rebind
+ their ``$element`` in ``start()``)
+
+* The ad-hoc optional setting of the openerp field descriptor on a
+ :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` has
+ been removed, the field descriptor is now passed as second argument
+ to the
+ :js:class:`~openerp.web.search.ExtendedSearchProposition.Field`'s
+ constructor, and bound to its
+ :js:attr:`~openerp.web.search.ExtendedSearchProposition.Field.field`.
+
+* Instead of its former domain triplet ``(field, operator, value)``,
+ :js:func:`~openerp.web.search.ExtendedSearchProposition.get_proposition`
+ now returns an object with two fields ``label`` and ``value``,
+ respectively a human-readable version of the proposition and the
+ corresponding domain triplet for the proposition.
+
+.. [#previous]
+
+ the original view was implemented on top of a monkey-patched
+ VisualSearch, but as our needs diverged from VisualSearch's goal
+ this made less and less sense ultimately leading to a clean-room
+ reimplementation
+
+.. [#no_impl]
+
+ In case you are extending the search view with a brand new type of
+ input
+
+.. [#completion]
+
+ Ideally this array should not hold more than about 10 items, but
+ the search view does not put any constraint on this at the
+ moment. Note that this may change.
+
+.. [#facet-field]
+
+ ``field`` does not actually need to be an instance of
+ :js:class:`~openerp.web.search.Input`, nor does it need to be what
+ created the facet, it just needs to provide the three
+ facet-serialization methods
+ :js:func:`~openerp.web.search.Input.get_domain`,
+ :js:func:`~openerp.web.search.Input.get_context` and
+ :js:func:`~openerp.web.search.Input.get_gropuby`, existing
+ :js:class:`~openerp.web.search.Input` subtypes merely provide
+ convenient base implementation for those methods.
+
+ Complex search view inputs (especially those living in the drawer)
+ may prefer using object literals with the right slots returning
+ closed-over values or some other scheme un-bound to an actual
+ :js:class:`~openerp.web.search.Input`, as
+ :js:class:`~openerp.web.search.CustomFilters` and
+ :js:class:`~openerp.web.search.Advanced` do.
+
+.. [#special]
+
+ search view fields may also bundle context data to add to the
+ search context
+
+.. _Backbone:
+ http://documentcloud.github.com/backbone/
+
+.. _Backbone.Collection:
+.. _Backbone collection:
+ http://documentcloud.github.com/backbone/#Collection
+
+.. _Backbone model:
+ http://documentcloud.github.com/backbone/#Model
+
.. _commit 3fca87101d:
- https://github.com/documentcloud/visualsearch/commit/3fca87101d
+ https://github.com/documentcloud/visualsearch/commit/3fca87101d