4 .. js:class:: openerp.web.Widget
6 This is the base class for all visual components. It corresponds to an MVC
7 view. It provides a number of services to handle a section of a page:
11 * Parenting-child relations
13 * Life-cycle management (including facilitating children destruction when a
14 parent object is removed)
16 * DOM insertion, via jQuery-powered insertion methods. Insertion targets can
17 be anything the corresponding jQuery method accepts (generally selectors,
18 DOM nodes and jQuery objects):
20 :js:func:`~openerp.web.Widget.appendTo`
21 Renders the widget and inserts it as the last child of the target, uses
24 :js:func:`~openerp.web.Widget.prependTo`
25 Renders the widget and inserts it as the first child of the target, uses
28 :js:func:`~openerp.web.Widget.insertAfter`
29 Renders the widget and inserts it as the preceding sibling of the target,
30 uses `.insertAfter()`_
32 :js:func:`~openerp.web.Widget.insertBefore`
33 Renders the widget and inserts it as the following sibling of the target,
34 uses `.insertBefore()`_
36 * Backbone-compatible shortcuts
43 A :js:class:`~openerp.web.Widget` is responsible for a section of the
44 page materialized by the DOM root of the widget. The DOM root is
45 available via the :js:attr:`~openerp.web.Widget.el` and
46 :js:attr:`~openerp.web.Widget.$el` attributes, which are
47 respectively the raw DOM Element and the jQuery wrapper around the DOM
50 There are two main ways to define and generate this DOM root:
52 .. js:attribute:: openerp.web.Widget.template
54 Should be set to the name of a QWeb template (a
55 :js:class:`String`). If set, the template will be rendered after
56 the widget has been initialized but before it has been
57 started. The root element generated by the template will be set as
58 the DOM root of the widget.
60 .. js:attribute:: openerp.web.Widget.tagName
62 Used if the widget has no template defined. Defaults to ``div``,
63 will be used as the tag name to create the DOM element to set as
64 the widget's DOM root. It is possible to further customize this
65 generated DOM root with the following attributes:
67 .. js:attribute:: openerp.web.Widget.id
69 Used to generate an ``id`` attribute on the generated DOM
72 .. js:attribute:: openerp.web.Widget.className
74 Used to generate a ``class`` attribute on the generated DOM root.
76 .. js:attribute:: openerp.web.Widget.attributes
78 Mapping (object literal) of attribute names to attribute
79 values. Each of these k:v pairs will be set as a DOM attribute
80 on the generated DOM root.
82 None of these is used in case a template is specified on the widget.
84 The DOM root can also be defined programmatically by overridding
86 .. js:function:: openerp.web.Widget.renderElement
88 Renders the widget's DOM root and sets it. The default
89 implementation will render a set template or generate an element
90 as described above, and will call
91 :js:func:`~openerp.web.Widget.setElement` on the result.
93 Any override to :js:func:`~openerp.web.Widget.renderElement` which
94 does not call its ``_super`` **must** call
95 :js:func:`~openerp.web.Widget.setElement` with whatever it
96 generated or the widget's behavior is undefined.r
100 The default :js:func:`~openerp.web.Widget.renderElement` can
101 be called repeatedly, it will *replace* the previous DOM root
102 (using ``replaceWith``). However, this requires that the
103 widget correctly sets and unsets its events (and children
105 :js:func:`~openerp.web.Widget.renderElement` should not be
106 called repeatedly unless the widget advertizes this feature.
108 Accessing DOM content
109 ~~~~~~~~~~~~~~~~~~~~~
111 Because a widget is only responsible for the content below its DOM
112 root, there is a shortcut for selecting sub-sections of a widget's
115 .. js:function:: openerp.web.Widget.$(selector)
117 Applies the CSS selector specified as parameter to the widget's
120 .. code-block:: javascript
124 is functionally identical to:
126 .. code-block:: javascript
128 this.$el.find(selector);
130 :param String selector: CSS selector
131 :returns: jQuery object
133 .. note:: this helper method is compatible with
136 Resetting the DOM root
137 ~~~~~~~~~~~~~~~~~~~~~~
139 .. js:function:: openerp.web.Widget.setElement(element)
141 Re-sets the widget's DOM root to the provided element, also
142 handles re-setting the various aliases of the DOM root as well as
143 unsetting and re-setting delegated events.
145 :param Element element: a DOM element or jQuery object to set as
146 the widget's DOM root
148 .. note:: should be mostly compatible with `Backbone's
154 A widget will generally need to respond to user action within its
155 section of the page. This entails binding events to DOM elements.
157 To this end, :js:class:`~openerp.web.Widget` provides an shortcut:
159 .. js:attribute:: openerp.web.Widget.events
161 Events are a mapping of ``event selector`` (an event name and a
162 CSS selector separated by a space) to a callback. The callback can
163 be either a method name in the widget or a function. In either
164 case, the ``this`` will be set to the widget:
166 .. code-block:: javascript
169 'click p.oe_some_class a': 'some_method',
170 'change input': function (e) {
175 The selector is used for jQuery's `event delegation`_, the
176 callback will only be triggered for descendants of the DOM root
177 matching the selector [0]_. If the selector is left out (only an
178 event name is specified), the event will be set directly on the
181 .. js:function:: openerp.web.Widget.delegateEvents
183 This method is in charge of binding
184 :js:attr:`~openerp.web.Widget.events` to the DOM. It is
185 automatically called after setting the widget's DOM root.
187 It can be overridden to set up more complex events than the
188 :js:attr:`~openerp.web.Widget.events` map allows, but the parent
189 should always be called (or :js:attr:`~openerp.web.Widget.events`
190 won't be handled correctly).
192 .. js:function:: openerp.web.Widget.undelegateEvents
194 This method is in charge of unbinding
195 :js:attr:`~openerp.web.Widget.events` from the DOM root when the
196 widget is destroyed or the DOM root is reset, in order to avoid
197 leaving "phantom" events.
199 It should be overridden to un-set any event set in an override of
200 :js:func:`~openerp.web.Widget.delegateEvents`.
202 .. note:: this behavior should be compatible with `Backbone's
203 delegateEvents`_, apart from not accepting any argument.
208 :js:class:`~openerp.base.Widget` is subclassed in the standard manner (via the
209 :js:func:`~openerp.base.Class.extend` method), and provides a number of
210 abstract properties and concrete methods (which you may or may not want to
211 override). Creating a subclass looks like this:
213 .. code-block:: javascript
215 var MyWidget = openerp.base.Widget.extend({
216 // QWeb template to use when rendering the object
217 template: "MyQWebTemplate",
219 init: function(parent) {
221 // insert code to execute before rendering, for object
226 // post-rendering initialization code, at this point
227 // ``this.$element`` has been initialized
228 this.$element.find(".my_button").click(/* an example of event binding * /);
230 // if ``start`` is asynchronous, return a promise object so callers
231 // know when the object is done initializing
232 return this.rpc(/* … */)
236 The new class can then be used in the following manner:
238 .. code-block:: javascript
240 // Create the instance
241 var my_widget = new MyWidget(this);
242 // Render and insert into DOM
243 my_widget.appendTo(".some-div");
245 After these two lines have executed (and any promise returned by ``appendTo``
246 has been resolved if needed), the widget is ready to be used.
248 .. note:: the insertion methods will start the widget themselves, and will
249 return the result of :js:func:`~openerp.base.Widget.start()`.
251 If for some reason you do not want to call these methods, you will
252 have to first call :js:func:`~openerp.base.Widget.render()` on the
253 widget, then insert it into your DOM and start it.
255 If the widget is not needed anymore (because it's transient), simply terminate
258 .. code-block:: javascript
262 will unbind all DOM events, remove the widget's content from the DOM and
263 destroy all widget data.
265 .. [0] not all DOM events are compatible with events delegation
268 http://api.jquery.com/appendTo/
271 http://api.jquery.com/prependTo/
274 http://api.jquery.com/insertAfter/
277 http://api.jquery.com/insertBefore/
279 .. _event delegation:
280 http://api.jquery.com/delegate/
282 .. _Backbone's setElement:
283 http://backbonejs.org/#View-setElement
285 .. _Backbone's delegateEvents:
286 http://backbonejs.org/#View-delegateEvents