3 * @extends Ext.view.AbstractView
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. <b>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.</b>
12 * The example below binds a DataView to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}.
14 * {@img Ext.DataView/Ext.DataView.png Ext.DataView component}
16 * Ext.regModel('Image', {
18 * {name:'src', type:'string'},
19 * {name:'caption', type:'string'}
23 * Ext.create('Ext.data.Store', {
27 * {src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & 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'}
34 * var imageTpl = new Ext.XTemplate(
35 * '<tpl for=".">',
36 * '<div style="thumb-wrap">',
37 * '<img src="{src}" />',
38 * '<br/><span>{caption}</span>',
43 * Ext.create('Ext.DataView', {
44 * store: Ext.data.StoreManager.lookup('imagesStore'),
46 * itemSelector: 'div.thumb-wrap',
47 * emptyText: 'No images available',
48 * renderTo: Ext.getBody()
53 Ext.define('Ext.view.View', {
54 extend: 'Ext.view.AbstractView',
55 alternateClassName: 'Ext.view.View',
56 alias: 'widget.dataview',
60 mousedown: 'MouseDown',
64 contextmenu: 'ContextMenu',
65 mouseover: 'MouseOver',
67 mouseenter: 'MouseEnter',
68 mouseleave: 'MouseLeave',
73 addCmpEvents: function() {
76 * @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
84 'beforeitemmousedown',
86 * @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
96 * @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
104 'beforeitemmouseenter',
106 * @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
114 'beforeitemmouseleave',
116 * @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
126 * @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
134 'beforeitemdblclick',
136 * @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
144 'beforeitemcontextmenu',
146 * @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.
156 * @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
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
176 * @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
186 * @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
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
206 * @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
216 * @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
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.
236 * @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
241 'beforecontainermousedown',
243 * @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
248 'beforecontainermouseup',
250 * @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
255 'beforecontainermouseover',
257 * @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
262 'beforecontainermouseout',
264 * @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
269 'beforecontainerclick',
271 * @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
276 'beforecontainerdblclick',
278 * @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
283 'beforecontainercontextmenu',
285 * @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.
290 'beforecontainerkeydown',
292 * @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
299 * @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
304 'containermouseover',
306 * @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
313 * @event containerclick
314 * Fires when the container is clicked.
315 * @param {Ext.view.View} this
316 * @param {Ext.EventObject} e The raw event object
320 * @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
327 * @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
332 'containercontextmenu',
334 * @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.
342 * @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
349 * @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
359 afterRender: function(){
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
377 me.mon(me.getTargetEl(), listeners);
380 me.bindStore(me.store, true);
384 handleEvent: function(e) {
385 if (this.processUIEvent(e) !== false) {
386 this.processSpecialEvent(e);
390 // Private template method
391 processItemEvent: Ext.emptyFn,
392 processContainerEvent: Ext.emptyFn,
393 processSpecialEvent: Ext.emptyFn,
396 * Returns true if this mouseover/out event is still over the overItem.
398 stillOverItem: function (event, overItem) {
401 // There is this weird bug when you hover over the border of a cell it is saying
402 // the target is the table.
403 // BrowserBug: IE6 & 7. If me.mouseOverItem has been removed and is no longer
404 // in the DOM then accessing .offsetParent will throw an "Unspecified error." exception.
405 // typeof'ng and checking to make sure the offsetParent is an object will NOT throw
406 // this hard exception.
407 if (overItem && typeof(overItem.offsetParent) === "object") {
408 // mouseout : relatedTarget == nowOver, target == wasOver
409 // mouseover: relatedTarget == wasOver, target == nowOver
410 nowOver = (event.type == 'mouseout') ? event.getRelatedTarget() : event.getTarget();
411 return Ext.fly(overItem).contains(nowOver);
417 processUIEvent: function(e) {
419 item = e.getTarget(me.getItemSelector(), me.getTargetEl()),
420 map = this.statics().EventMap,
423 overItem = me.mouseOverItem,
427 if (type == 'mouseover' && me.stillOverItem(e, overItem)) {
431 // Try to get the selected item to handle the keydown event, otherwise we'll just fire a container keydown event
432 if (type == 'keydown') {
433 record = me.getSelectionModel().getLastSelected();
435 item = me.getNode(record);
441 index = me.indexOf(item);
443 record = me.getRecord(item);
446 if (me.processItemEvent(record, item, index, e) === false) {
450 newType = me.isNewItemEvent(item, e);
451 if (newType === false) {
456 (me['onBeforeItem' + map[newType]](record, item, index, e) === false) ||
457 (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) ||
458 (me['onItem' + map[newType]](record, item, index, e) === false)
463 me.fireEvent('item' + newType, me, record, item, index, e);
467 (me.processContainerEvent(e) === false) ||
468 (me['onBeforeContainer' + map[type]](e) === false) ||
469 (me.fireEvent('beforecontainer' + type, me, e) === false) ||
470 (me['onContainer' + map[type]](e) === false)
475 me.fireEvent('container' + type, me, e);
481 isNewItemEvent: function (item, e) {
483 overItem = me.mouseOverItem,
488 if (item === overItem) {
491 me.mouseOverItem = item;
495 // If the currently mouseovered item contains the mouseover target, it's *NOT* a mouseleave
496 if (me.stillOverItem(e, overItem)) {
499 me.mouseOverItem = null;
506 onItemMouseEnter: function(record, item, index, e) {
507 if (this.trackOver) {
508 this.highlightItem(item);
513 onItemMouseLeave : function(record, item, index, e) {
514 if (this.trackOver) {
515 this.clearHighlight();
519 // @private, template methods
520 onItemMouseDown: Ext.emptyFn,
521 onItemMouseUp: Ext.emptyFn,
522 onItemClick: Ext.emptyFn,
523 onItemDblClick: Ext.emptyFn,
524 onItemContextMenu: Ext.emptyFn,
525 onItemKeyDown: Ext.emptyFn,
526 onBeforeItemMouseDown: Ext.emptyFn,
527 onBeforeItemMouseUp: Ext.emptyFn,
528 onBeforeItemMouseEnter: Ext.emptyFn,
529 onBeforeItemMouseLeave: Ext.emptyFn,
530 onBeforeItemClick: Ext.emptyFn,
531 onBeforeItemDblClick: Ext.emptyFn,
532 onBeforeItemContextMenu: Ext.emptyFn,
533 onBeforeItemKeyDown: Ext.emptyFn,
535 // @private, template methods
536 onContainerMouseDown: Ext.emptyFn,
537 onContainerMouseUp: Ext.emptyFn,
538 onContainerMouseOver: Ext.emptyFn,
539 onContainerMouseOut: Ext.emptyFn,
540 onContainerClick: Ext.emptyFn,
541 onContainerDblClick: Ext.emptyFn,
542 onContainerContextMenu: Ext.emptyFn,
543 onContainerKeyDown: Ext.emptyFn,
544 onBeforeContainerMouseDown: Ext.emptyFn,
545 onBeforeContainerMouseUp: Ext.emptyFn,
546 onBeforeContainerMouseOver: Ext.emptyFn,
547 onBeforeContainerMouseOut: Ext.emptyFn,
548 onBeforeContainerClick: Ext.emptyFn,
549 onBeforeContainerDblClick: Ext.emptyFn,
550 onBeforeContainerContextMenu: Ext.emptyFn,
551 onBeforeContainerKeyDown: Ext.emptyFn,
554 * Highlight a given item in the DataView. This is called by the mouseover handler if {@link #overItemCls}
555 * and {@link #trackOver} are configured, but can also be called manually by other code, for instance to
556 * handle stepping through the list via keyboard navigation.
557 * @param {HTMLElement} item The item to highlight
559 highlightItem: function(item) {
562 me.highlightedItem = item;
563 Ext.fly(item).addCls(me.overItemCls);
567 * Un-highlight the currently highlighted item, if any.
569 clearHighlight: function() {
571 highlighted = me.highlightedItem;
574 Ext.fly(highlighted).removeCls(me.overItemCls);
575 delete me.highlightedItem;
579 refresh: function() {
580 this.clearHighlight();
581 this.callParent(arguments);