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