Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / docs / source / View3.html
1 <!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-view.View'>/**
2 </span> * @class Ext.view.View
3  * @extends Ext.view.AbstractView
4  *
5  * A mechanism for displaying data using custom layout templates and formatting. DataView uses an {@link Ext.XTemplate}
6  * as its internal templating mechanism, and is bound to an {@link Ext.data.Store}
7  * so that as the data in the store changes the view is automatically updated to reflect the changes.  The view also
8  * provides built-in behavior for many common events that can occur for its contained items including click, doubleclick,
9  * mouseover, mouseout, etc. as well as a built-in selection model. &lt;b&gt;In order to use these features, an {@link #itemSelector}
10  * config must be provided for the DataView to determine what nodes it will be working with.&lt;/b&gt;
11  *
12  * The example below binds a DataView to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}.
13  *
14  * {@img Ext.DataView/Ext.DataView.png Ext.DataView component}
15  *
16  *     Ext.regModel('Image', {
17  *         Fields: [
18  *             {name:'src', type:'string'},
19  *             {name:'caption', type:'string'}
20  *         ]
21  *     });
22  *     
23  *     Ext.create('Ext.data.Store', {
24  *         id:'imagesStore',
25  *         model: 'Image',
26  *         data: [
27  *             {src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing &amp; Charts'},
28  *             {src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data'},
29  *             {src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme'},
30  *             {src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned'}            
31  *         ]
32  *     });
33  *     
34  *     var imageTpl = new Ext.XTemplate(
35  *         '&amp;lt;tpl for=&quot;.&quot;&amp;gt;',
36  *             '&amp;lt;div style=&quot;thumb-wrap&quot;&amp;gt;',
37  *               '&amp;lt;img src=&quot;{src}&quot; /&amp;gt;',
38  *               '&amp;lt;br/&amp;gt;&amp;lt;span&amp;gt;{caption}&amp;lt;/span&amp;gt;',
39  *             '&amp;lt;/div&amp;gt;',
40  *         '&amp;lt;/tpl&amp;gt;'
41  *     );
42  *     
43  *     Ext.create('Ext.DataView', {
44  *         store: Ext.data.StoreManager.lookup('imagesStore'),
45  *         tpl: imageTpl,
46  *         itemSelector: 'div.thumb-wrap',
47  *         emptyText: 'No images available',
48  *         renderTo: Ext.getBody()
49  *     });
50  *
51  * @xtype dataview
52  */
53 Ext.define('Ext.view.View', {
54     extend: 'Ext.view.AbstractView',
55     alternateClassName: 'Ext.view.View',
56     alias: 'widget.dataview',
57     
58     inheritableStatics: {
59         EventMap: {
60             mousedown: 'MouseDown',
61             mouseup: 'MouseUp',
62             click: 'Click',
63             dblclick: 'DblClick',
64             contextmenu: 'ContextMenu',
65             mouseover: 'MouseOver',
66             mouseout: 'MouseOut',
67             mouseenter: 'MouseEnter',
68             mouseleave: 'MouseLeave',
69             keydown: 'KeyDown'
70         }
71     },
72     
73     addCmpEvents: function() {
74         this.addEvents(
75 <span id='Ext-view.View-event-beforeitemmousedown'>            /**
76 </span>             * @event beforeitemmousedown
77              * Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
78              * @param {Ext.view.View} this
79              * @param {Ext.data.Model} record The record that belongs to the item
80              * @param {HTMLElement} item The item's element
81              * @param {Number} index The item's index
82              * @param {Ext.EventObject} e The raw event object
83              */
84             'beforeitemmousedown',
85 <span id='Ext-view.View-event-beforeitemmouseup'>            /**
86 </span>             * @event beforeitemmouseup
87              * Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
88              * @param {Ext.view.View} this
89              * @param {Ext.data.Model} record The record that belongs to the item
90              * @param {HTMLElement} item The item's element
91              * @param {Number} index The item's index
92              * @param {Ext.EventObject} e The raw event object
93              */
94             'beforeitemmouseup',
95 <span id='Ext-view.View-event-beforeitemmouseenter'>            /**
96 </span>             * @event beforeitemmouseenter
97              * Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
98              * @param {Ext.view.View} this
99              * @param {Ext.data.Model} record The record that belongs to the item
100              * @param {HTMLElement} item The item's element
101              * @param {Number} index The item's index
102              * @param {Ext.EventObject} e The raw event object
103              */
104             'beforeitemmouseenter',
105 <span id='Ext-view.View-event-beforeitemmouseleave'>            /**
106 </span>             * @event beforeitemmouseleave
107              * Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
108              * @param {Ext.view.View} this
109              * @param {Ext.data.Model} record The record that belongs to the item
110              * @param {HTMLElement} item The item's element
111              * @param {Number} index The item's index
112              * @param {Ext.EventObject} e The raw event object
113              */
114             'beforeitemmouseleave',
115 <span id='Ext-view.View-event-beforeitemclick'>            /**
116 </span>             * @event beforeitemclick
117              * Fires before the click event on an item is processed. Returns false to cancel the default action.
118              * @param {Ext.view.View} this
119              * @param {Ext.data.Model} record The record that belongs to the item
120              * @param {HTMLElement} item The item's element
121              * @param {Number} index The item's index
122              * @param {Ext.EventObject} e The raw event object
123              */
124             'beforeitemclick',
125 <span id='Ext-view.View-event-beforeitemdblclick'>            /**
126 </span>             * @event beforeitemdblclick
127              * Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
128              * @param {Ext.view.View} this
129              * @param {Ext.data.Model} record The record that belongs to the item
130              * @param {HTMLElement} item The item's element
131              * @param {Number} index The item's index
132              * @param {Ext.EventObject} e The raw event object
133              */
134             'beforeitemdblclick',
135 <span id='Ext-view.View-event-beforeitemcontextmenu'>            /**
136 </span>             * @event beforeitemcontextmenu
137              * Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
138              * @param {Ext.view.View} this
139              * @param {Ext.data.Model} record The record that belongs to the item
140              * @param {HTMLElement} item The item's element
141              * @param {Number} index The item's index
142              * @param {Ext.EventObject} e The raw event object
143              */
144             'beforeitemcontextmenu',
145 <span id='Ext-view.View-event-beforeitemkeydown'>            /**
146 </span>             * @event beforeitemkeydown
147              * Fires before the keydown event on an item is processed. Returns false to cancel the default action.
148              * @param {Ext.view.View} this
149              * @param {Ext.data.Model} record The record that belongs to the item
150              * @param {HTMLElement} item The item's element
151              * @param {Number} index The item's index
152              * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
153              */
154             'beforeitemkeydown',
155 <span id='Ext-view.View-event-itemmousedown'>            /**
156 </span>             * @event itemmousedown
157              * Fires when there is a mouse down on an item
158              * @param {Ext.view.View} this
159              * @param {Ext.data.Model} record The record that belongs to the item
160              * @param {HTMLElement} item The item's element
161              * @param {Number} index The item's index
162              * @param {Ext.EventObject} e The raw event object
163              */
164             'itemmousedown',
165 <span id='Ext-view.View-event-itemmouseup'>            /**
166 </span>             * @event itemmouseup
167              * Fires when there is a mouse up on an item
168              * @param {Ext.view.View} this
169              * @param {Ext.data.Model} record The record that belongs to the item
170              * @param {HTMLElement} item The item's element
171              * @param {Number} index The item's index
172              * @param {Ext.EventObject} e The raw event object
173              */
174             'itemmouseup',
175 <span id='Ext-view.View-event-itemmouseenter'>            /**
176 </span>             * @event itemmouseenter
177              * Fires when the mouse enters an item.
178              * @param {Ext.view.View} this
179              * @param {Ext.data.Model} record The record that belongs to the item
180              * @param {HTMLElement} item The item's element
181              * @param {Number} index The item's index
182              * @param {Ext.EventObject} e The raw event object
183              */
184             'itemmouseenter',
185 <span id='Ext-view.View-event-itemmouseleave'>            /**
186 </span>             * @event itemmouseleave
187              * Fires when the mouse leaves an item.
188              * @param {Ext.view.View} this
189              * @param {Ext.data.Model} record The record that belongs to the item
190              * @param {HTMLElement} item The item's element
191              * @param {Number} index The item's index
192              * @param {Ext.EventObject} e The raw event object
193              */
194             'itemmouseleave',
195 <span id='Ext-view.View-event-itemclick'>            /**
196 </span>             * @event itemclick
197              * Fires when an item is clicked.
198              * @param {Ext.view.View} this
199              * @param {Ext.data.Model} record The record that belongs to the item
200              * @param {HTMLElement} item The item's element
201              * @param {Number} index The item's index
202              * @param {Ext.EventObject} e The raw event object
203              */
204             'itemclick',
205 <span id='Ext-view.View-event-itemdblclick'>            /**
206 </span>             * @event itemdblclick
207              * Fires when an item is double clicked.
208              * @param {Ext.view.View} this
209              * @param {Ext.data.Model} record The record that belongs to the item
210              * @param {HTMLElement} item The item's element
211              * @param {Number} index The item's index
212              * @param {Ext.EventObject} e The raw event object
213              */
214             'itemdblclick',
215 <span id='Ext-view.View-event-itemcontextmenu'>            /**
216 </span>             * @event itemcontextmenu
217              * Fires when an item is right clicked.
218              * @param {Ext.view.View} this
219              * @param {Ext.data.Model} record The record that belongs to the item
220              * @param {HTMLElement} item The item's element
221              * @param {Number} index The item's index
222              * @param {Ext.EventObject} e The raw event object
223              */
224             'itemcontextmenu',
225 <span id='Ext-view.View-event-itemkeydown'>            /**
226 </span>             * @event itemkeydown
227              * Fires when a key is pressed while an item is currently selected.
228              * @param {Ext.view.View} this
229              * @param {Ext.data.Model} record The record that belongs to the item
230              * @param {HTMLElement} item The item's element
231              * @param {Number} index The item's index
232              * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
233              */
234             'itemkeydown',
235 <span id='Ext-view.View-event-beforecontainermousedown'>            /**
236 </span>             * @event beforecontainermousedown
237              * Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
238              * @param {Ext.view.View} this
239              * @param {Ext.EventObject} e The raw event object
240              */
241             'beforecontainermousedown',
242 <span id='Ext-view.View-event-beforecontainermouseup'>            /**
243 </span>             * @event beforecontainermouseup
244              * Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
245              * @param {Ext.view.View} this
246              * @param {Ext.EventObject} e The raw event object
247              */
248             'beforecontainermouseup',
249 <span id='Ext-view.View-event-beforecontainermouseover'>            /**
250 </span>             * @event beforecontainermouseover
251              * Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
252              * @param {Ext.view.View} this
253              * @param {Ext.EventObject} e The raw event object
254              */
255             'beforecontainermouseover',
256 <span id='Ext-view.View-event-beforecontainermouseout'>            /**
257 </span>             * @event beforecontainermouseout
258              * Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
259              * @param {Ext.view.View} this
260              * @param {Ext.EventObject} e The raw event object
261              */
262             'beforecontainermouseout',
263 <span id='Ext-view.View-event-beforecontainerclick'>            /**
264 </span>             * @event beforecontainerclick
265              * Fires before the click event on the container is processed. Returns false to cancel the default action.
266              * @param {Ext.view.View} this
267              * @param {Ext.EventObject} e The raw event object
268              */
269             'beforecontainerclick',
270 <span id='Ext-view.View-event-beforecontainerdblclick'>            /**
271 </span>             * @event beforecontainerdblclick
272              * Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
273              * @param {Ext.view.View} this
274              * @param {Ext.EventObject} e The raw event object
275              */
276             'beforecontainerdblclick',
277 <span id='Ext-view.View-event-beforecontainercontextmenu'>            /**
278 </span>             * @event beforecontainercontextmenu
279              * Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
280              * @param {Ext.view.View} this
281              * @param {Ext.EventObject} e The raw event object
282              */
283             'beforecontainercontextmenu',
284 <span id='Ext-view.View-event-beforecontainerkeydown'>            /**
285 </span>             * @event beforecontainerkeydown
286              * Fires before the keydown event on the container is processed. Returns false to cancel the default action.
287              * @param {Ext.view.View} this
288              * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
289              */
290             'beforecontainerkeydown',
291 <span id='Ext-view.View-event-containermouseup'>            /**
292 </span>             * @event containermouseup
293              * Fires when there is a mouse up on the container
294              * @param {Ext.view.View} this
295              * @param {Ext.EventObject} e The raw event object
296              */
297             'containermouseup',
298 <span id='Ext-view.View-event-containermouseover'>            /**
299 </span>             * @event containermouseover
300              * Fires when you move the mouse over the container.
301              * @param {Ext.view.View} this
302              * @param {Ext.EventObject} e The raw event object
303              */
304             'containermouseover',
305 <span id='Ext-view.View-event-containermouseout'>            /**
306 </span>             * @event containermouseout
307              * Fires when you move the mouse out of the container.
308              * @param {Ext.view.View} this
309              * @param {Ext.EventObject} e The raw event object
310              */
311             'containermouseout',
312 <span id='Ext-view.View-event-containerclick'>            /**
313 </span>             * @event containerclick
314              * Fires when the container is clicked.
315              * @param {Ext.view.View} this
316              * @param {Ext.EventObject} e The raw event object
317              */
318             'containerclick',
319 <span id='Ext-view.View-event-containerdblclick'>            /**
320 </span>             * @event containerdblclick
321              * Fires when the container is double clicked.
322              * @param {Ext.view.View} this
323              * @param {Ext.EventObject} e The raw event object
324              */
325             'containerdblclick',
326 <span id='Ext-view.View-event-containercontextmenu'>            /**
327 </span>             * @event containercontextmenu
328              * Fires when the container is right clicked.
329              * @param {Ext.view.View} this
330              * @param {Ext.EventObject} e The raw event object
331              */
332             'containercontextmenu',
333 <span id='Ext-view.View-event-containerkeydown'>            /**
334 </span>             * @event containerkeydown
335              * Fires when a key is pressed while the container is focused, and no item is currently selected.
336              * @param {Ext.view.View} this
337              * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
338              */
339             'containerkeydown',
340             
341 <span id='Ext-view.View-event-selectionchange'>            /**
342 </span>             * @event selectionchange
343              * Fires when the selected nodes change. Relayed event from the underlying selection model.
344              * @param {Ext.view.View} this
345              * @param {Array} selections Array of the selected nodes
346              */
347             'selectionchange',
348 <span id='Ext-view.View-event-beforeselect'>            /**
349 </span>             * @event beforeselect
350              * Fires before a selection is made. If any handlers return false, the selection is cancelled.
351              * @param {Ext.view.View} this
352              * @param {HTMLElement} node The node to be selected
353              * @param {Array} selections Array of currently selected nodes
354              */
355             'beforeselect'
356         );
357     },
358     // private
359     afterRender: function(){
360         var me = this, 
361             listeners;
362         
363         me.callParent();
364
365         listeners = {
366             scope: me,
367             click: me.handleEvent,
368             mousedown: me.handleEvent,
369             mouseup: me.handleEvent,
370             dblclick: me.handleEvent,
371             contextmenu: me.handleEvent,
372             mouseover: me.handleEvent,
373             mouseout: me.handleEvent,
374             keydown: me.handleEvent
375         };
376         
377         me.mon(me.getTargetEl(), listeners);
378         
379         if (me.store) {
380             me.bindStore(me.store, true);
381         }
382     },
383     
384     handleEvent: function(e) {
385         if (this.processUIEvent(e) !== false) {
386             this.processSpecialEvent(e);
387         }
388     },
389     
390     // Private template method
391     processItemEvent: Ext.emptyFn,
392     processContainerEvent: Ext.emptyFn,
393     processSpecialEvent: Ext.emptyFn,
394     
395     processUIEvent: function(e, type) {
396         type = type || e.type;
397         var me = this,
398             item = e.getTarget(me.getItemSelector(), me.getTargetEl()),
399             map = this.statics().EventMap,
400             index, record;
401         
402         if (!item) {
403             // There is this weird bug when you hover over the border of a cell it is saying
404             // the target is the table.
405             // BrowserBug: IE6 &amp; 7. If me.mouseOverItem has been removed and is no longer
406             // in the DOM then accessing .offsetParent will throw an &quot;Unspecified error.&quot; exception.
407             // typeof'ng and checking to make sure the offsetParent is an object will NOT throw
408             // this hard exception.
409             if (type == 'mouseover' &amp;&amp; me.mouseOverItem &amp;&amp; typeof me.mouseOverItem.offsetParent === &quot;object&quot; &amp;&amp; Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint())) {
410                 item = me.mouseOverItem;
411             }
412             
413             // Try to get the selected item to handle the keydown event, otherwise we'll just fire a container keydown event
414             if (type == 'keydown') {
415                 record = me.getSelectionModel().getLastSelected();
416                 if (record) {
417                     item = me.getNode(record);
418                 }
419             }
420         }
421         
422         if (item) {
423             index = me.indexOf(item);
424             if (!record) {
425                 record = me.getRecord(item);
426             }
427             
428             if (me.processItemEvent(type, record, item, index, e) === false) {
429                 return false;
430             }
431             
432             type = me.isNewItemEvent(type, item, e);
433             if (type === false) {
434                 return false;
435             }
436             
437             if (
438                 (me['onBeforeItem' + map[type]](record, item, index, e) === false) ||
439                 (me.fireEvent('beforeitem' + type, me, record, item, index, e) === false) ||
440                 (me['onItem' + map[type]](record, item, index, e) === false)
441             ) { 
442                 return false;
443             }
444             
445             me.fireEvent('item' + type, me, record, item, index, e);
446         } 
447         else {
448             if (
449                 (me.processContainerEvent(type, e) === false) ||
450                 (me['onBeforeContainer' + map[type]](e) === false) ||
451                 (me.fireEvent('beforecontainer' + type, me, e) === false) ||
452                 (me['onContainer' + map[type]](e) === false)
453             ) {
454                 return false;
455             }
456             
457             me.fireEvent('container' + type, me, e);
458         }
459         
460         return true;
461     },
462     
463     isNewItemEvent: function(type, item, e) {
464         var me = this,
465             overItem = me.mouseOverItem,
466             contains,
467             isItem;
468             
469         switch (type) {
470             case 'mouseover':
471                 if (item === overItem) {
472                     return false;
473                 }
474                 me.mouseOverItem = item;
475                 return 'mouseenter';
476             break;
477             
478             case 'mouseout':
479                /*
480                 * Need an extra check here to see if it's the parent element. See the
481                 * comment re: the browser bug at the start of processUIEvent
482                 */
483                 if (overItem &amp;&amp; typeof overItem.offsetParent === &quot;object&quot;) {
484                     contains = Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint());
485                     isItem = Ext.fly(e.getTarget()).hasCls(me.itemSelector);
486                     if (contains &amp;&amp; isItem) {
487                         return false;
488                     }
489                 }
490                 me.mouseOverItem = null;
491                 return 'mouseleave';
492             break;
493         }
494         return type;
495     },
496     
497     // private
498     onItemMouseEnter: function(record, item, index, e) {
499         if (this.trackOver) {
500             this.highlightItem(item);
501         }
502     },
503
504     // private
505     onItemMouseLeave : function(record, item, index, e) {
506         if (this.trackOver) {
507             this.clearHighlight();
508         }
509     },
510
511     // @private, template methods
512     onItemMouseDown: Ext.emptyFn,
513     onItemMouseUp: Ext.emptyFn,
514     onItemClick: Ext.emptyFn,
515     onItemDblClick: Ext.emptyFn,
516     onItemContextMenu: Ext.emptyFn,
517     onItemKeyDown: Ext.emptyFn,
518     onBeforeItemMouseDown: Ext.emptyFn,
519     onBeforeItemMouseUp: Ext.emptyFn,
520     onBeforeItemMouseEnter: Ext.emptyFn,
521     onBeforeItemMouseLeave: Ext.emptyFn,
522     onBeforeItemClick: Ext.emptyFn,
523     onBeforeItemDblClick: Ext.emptyFn,
524     onBeforeItemContextMenu: Ext.emptyFn,
525     onBeforeItemKeyDown: Ext.emptyFn,
526     
527     // @private, template methods
528     onContainerMouseDown: Ext.emptyFn,
529     onContainerMouseUp: Ext.emptyFn,
530     onContainerMouseOver: Ext.emptyFn,
531     onContainerMouseOut: Ext.emptyFn,
532     onContainerClick: Ext.emptyFn,
533     onContainerDblClick: Ext.emptyFn,
534     onContainerContextMenu: Ext.emptyFn,
535     onContainerKeyDown: Ext.emptyFn,
536     onBeforeContainerMouseDown: Ext.emptyFn,
537     onBeforeContainerMouseUp: Ext.emptyFn,
538     onBeforeContainerMouseOver: Ext.emptyFn,
539     onBeforeContainerMouseOut: Ext.emptyFn,
540     onBeforeContainerClick: Ext.emptyFn,
541     onBeforeContainerDblClick: Ext.emptyFn,
542     onBeforeContainerContextMenu: Ext.emptyFn,
543     onBeforeContainerKeyDown: Ext.emptyFn,
544     
545 <span id='Ext-view.View-method-highlightItem'>    /**
546 </span>     * Highlight a given item in the DataView. This is called by the mouseover handler if {@link #overItemCls}
547      * and {@link #trackOver} are configured, but can also be called manually by other code, for instance to
548      * handle stepping through the list via keyboard navigation.
549      * @param {HTMLElement} item The item to highlight
550      */
551     highlightItem: function(item) {
552         var me = this;
553         me.clearHighlight();
554         me.highlightedItem = item;
555         Ext.fly(item).addCls(me.overItemCls);
556     },
557
558 <span id='Ext-view.View-method-clearHighlight'>    /**
559 </span>     * Un-highlight the currently highlighted item, if any.
560      */
561     clearHighlight: function() {
562         var me = this,
563             highlighted = me.highlightedItem;
564             
565         if (highlighted) {
566             Ext.fly(highlighted).removeCls(me.overItemCls);
567             delete me.highlightedItem;
568         }
569     },
570
571     refresh: function() {
572         this.clearHighlight();
573         this.callParent(arguments);
574     }
575 });</pre></pre></body></html>