3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.view.View
17 * @extends Ext.view.AbstractView
19 * A mechanism for displaying data using custom layout templates and formatting. DataView uses an {@link Ext.XTemplate}
20 * as its internal templating mechanism, and is bound to an {@link Ext.data.Store}
21 * so that as the data in the store changes the view is automatically updated to reflect the changes. The view also
22 * provides built-in behavior for many common events that can occur for its contained items including click, doubleclick,
23 * mouseover, mouseout, etc. as well as a built-in selection model. <b>In order to use these features, an {@link #itemSelector}
24 * config must be provided for the DataView to determine what nodes it will be working with.</b>
26 * The example below binds a DataView to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}.
28 * {@img Ext.DataView/Ext.DataView.png Ext.DataView component}
30 * Ext.regModel('Image', {
32 * {name:'src', type:'string'},
33 * {name:'caption', type:'string'}
37 * Ext.create('Ext.data.Store', {
41 * {src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts'},
42 * {src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data'},
43 * {src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme'},
44 * {src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned'}
48 * var imageTpl = new Ext.XTemplate(
49 * '<tpl for=".">',
50 * '<div style="thumb-wrap">',
51 * '<img src="{src}" />',
52 * '<br/><span>{caption}</span>',
57 * Ext.create('Ext.DataView', {
58 * store: Ext.data.StoreManager.lookup('imagesStore'),
60 * itemSelector: 'div.thumb-wrap',
61 * emptyText: 'No images available',
62 * renderTo: Ext.getBody()
65 Ext.define('Ext.view.View', {
66 extend: 'Ext.view.AbstractView',
67 alternateClassName: 'Ext.DataView',
68 alias: 'widget.dataview',
72 mousedown: 'MouseDown',
76 contextmenu: 'ContextMenu',
77 mouseover: 'MouseOver',
79 mouseenter: 'MouseEnter',
80 mouseleave: 'MouseLeave',
86 addCmpEvents: function() {
89 * @event beforeitemmousedown
90 * Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
91 * @param {Ext.view.View} this
92 * @param {Ext.data.Model} record The record that belongs to the item
93 * @param {HTMLElement} item The item's element
94 * @param {Number} index The item's index
95 * @param {Ext.EventObject} e The raw event object
97 'beforeitemmousedown',
99 * @event beforeitemmouseup
100 * Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
101 * @param {Ext.view.View} this
102 * @param {Ext.data.Model} record The record that belongs to the item
103 * @param {HTMLElement} item The item's element
104 * @param {Number} index The item's index
105 * @param {Ext.EventObject} e The raw event object
109 * @event beforeitemmouseenter
110 * Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
111 * @param {Ext.view.View} this
112 * @param {Ext.data.Model} record The record that belongs to the item
113 * @param {HTMLElement} item The item's element
114 * @param {Number} index The item's index
115 * @param {Ext.EventObject} e The raw event object
117 'beforeitemmouseenter',
119 * @event beforeitemmouseleave
120 * Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
121 * @param {Ext.view.View} this
122 * @param {Ext.data.Model} record The record that belongs to the item
123 * @param {HTMLElement} item The item's element
124 * @param {Number} index The item's index
125 * @param {Ext.EventObject} e The raw event object
127 'beforeitemmouseleave',
129 * @event beforeitemclick
130 * Fires before the click event on an item is processed. Returns false to cancel the default action.
131 * @param {Ext.view.View} this
132 * @param {Ext.data.Model} record The record that belongs to the item
133 * @param {HTMLElement} item The item's element
134 * @param {Number} index The item's index
135 * @param {Ext.EventObject} e The raw event object
139 * @event beforeitemdblclick
140 * Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
141 * @param {Ext.view.View} this
142 * @param {Ext.data.Model} record The record that belongs to the item
143 * @param {HTMLElement} item The item's element
144 * @param {Number} index The item's index
145 * @param {Ext.EventObject} e The raw event object
147 'beforeitemdblclick',
149 * @event beforeitemcontextmenu
150 * Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
151 * @param {Ext.view.View} this
152 * @param {Ext.data.Model} record The record that belongs to the item
153 * @param {HTMLElement} item The item's element
154 * @param {Number} index The item's index
155 * @param {Ext.EventObject} e The raw event object
157 'beforeitemcontextmenu',
159 * @event beforeitemkeydown
160 * Fires before the keydown event on an item is processed. Returns false to cancel the default action.
161 * @param {Ext.view.View} this
162 * @param {Ext.data.Model} record The record that belongs to the item
163 * @param {HTMLElement} item The item's element
164 * @param {Number} index The item's index
165 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
169 * @event itemmousedown
170 * Fires when there is a mouse down on an item
171 * @param {Ext.view.View} this
172 * @param {Ext.data.Model} record The record that belongs to the item
173 * @param {HTMLElement} item The item's element
174 * @param {Number} index The item's index
175 * @param {Ext.EventObject} e The raw event object
180 * Fires when there is a mouse up on an item
181 * @param {Ext.view.View} this
182 * @param {Ext.data.Model} record The record that belongs to the item
183 * @param {HTMLElement} item The item's element
184 * @param {Number} index The item's index
185 * @param {Ext.EventObject} e The raw event object
189 * @event itemmouseenter
190 * Fires when the mouse enters an item.
191 * @param {Ext.view.View} this
192 * @param {Ext.data.Model} record The record that belongs to the item
193 * @param {HTMLElement} item The item's element
194 * @param {Number} index The item's index
195 * @param {Ext.EventObject} e The raw event object
199 * @event itemmouseleave
200 * Fires when the mouse leaves an item.
201 * @param {Ext.view.View} this
202 * @param {Ext.data.Model} record The record that belongs to the item
203 * @param {HTMLElement} item The item's element
204 * @param {Number} index The item's index
205 * @param {Ext.EventObject} e The raw event object
210 * Fires when an item is clicked.
211 * @param {Ext.view.View} this
212 * @param {Ext.data.Model} record The record that belongs to the item
213 * @param {HTMLElement} item The item's element
214 * @param {Number} index The item's index
215 * @param {Ext.EventObject} e The raw event object
219 * @event itemdblclick
220 * Fires when an item is double clicked.
221 * @param {Ext.view.View} this
222 * @param {Ext.data.Model} record The record that belongs to the item
223 * @param {HTMLElement} item The item's element
224 * @param {Number} index The item's index
225 * @param {Ext.EventObject} e The raw event object
229 * @event itemcontextmenu
230 * Fires when an item is right clicked.
231 * @param {Ext.view.View} this
232 * @param {Ext.data.Model} record The record that belongs to the item
233 * @param {HTMLElement} item The item's element
234 * @param {Number} index The item's index
235 * @param {Ext.EventObject} e The raw event object
240 * Fires when a key is pressed while an item is currently selected.
241 * @param {Ext.view.View} this
242 * @param {Ext.data.Model} record The record that belongs to the item
243 * @param {HTMLElement} item The item's element
244 * @param {Number} index The item's index
245 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
249 * @event beforecontainermousedown
250 * Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
251 * @param {Ext.view.View} this
252 * @param {Ext.EventObject} e The raw event object
254 'beforecontainermousedown',
256 * @event beforecontainermouseup
257 * Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
258 * @param {Ext.view.View} this
259 * @param {Ext.EventObject} e The raw event object
261 'beforecontainermouseup',
263 * @event beforecontainermouseover
264 * Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
265 * @param {Ext.view.View} this
266 * @param {Ext.EventObject} e The raw event object
268 'beforecontainermouseover',
270 * @event beforecontainermouseout
271 * Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
272 * @param {Ext.view.View} this
273 * @param {Ext.EventObject} e The raw event object
275 'beforecontainermouseout',
277 * @event beforecontainerclick
278 * Fires before the click event on the container is processed. Returns false to cancel the default action.
279 * @param {Ext.view.View} this
280 * @param {Ext.EventObject} e The raw event object
282 'beforecontainerclick',
284 * @event beforecontainerdblclick
285 * Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
286 * @param {Ext.view.View} this
287 * @param {Ext.EventObject} e The raw event object
289 'beforecontainerdblclick',
291 * @event beforecontainercontextmenu
292 * Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
293 * @param {Ext.view.View} this
294 * @param {Ext.EventObject} e The raw event object
296 'beforecontainercontextmenu',
298 * @event beforecontainerkeydown
299 * Fires before the keydown event on the container is processed. Returns false to cancel the default action.
300 * @param {Ext.view.View} this
301 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
303 'beforecontainerkeydown',
305 * @event containermouseup
306 * Fires when there is a mouse up on the container
307 * @param {Ext.view.View} this
308 * @param {Ext.EventObject} e The raw event object
312 * @event containermouseover
313 * Fires when you move the mouse over the container.
314 * @param {Ext.view.View} this
315 * @param {Ext.EventObject} e The raw event object
317 'containermouseover',
319 * @event containermouseout
320 * Fires when you move the mouse out of the container.
321 * @param {Ext.view.View} this
322 * @param {Ext.EventObject} e The raw event object
326 * @event containerclick
327 * Fires when the container is clicked.
328 * @param {Ext.view.View} this
329 * @param {Ext.EventObject} e The raw event object
333 * @event containerdblclick
334 * Fires when the container is double clicked.
335 * @param {Ext.view.View} this
336 * @param {Ext.EventObject} e The raw event object
340 * @event containercontextmenu
341 * Fires when the container is right clicked.
342 * @param {Ext.view.View} this
343 * @param {Ext.EventObject} e The raw event object
345 'containercontextmenu',
347 * @event containerkeydown
348 * Fires when a key is pressed while the container is focused, and no item is currently selected.
349 * @param {Ext.view.View} this
350 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
355 * @event selectionchange
356 * Fires when the selected nodes change. Relayed event from the underlying selection model.
357 * @param {Ext.view.View} this
358 * @param {Array} selections Array of the selected nodes
362 * @event beforeselect
363 * Fires before a selection is made. If any handlers return false, the selection is cancelled.
364 * @param {Ext.view.View} this
365 * @param {HTMLElement} node The node to be selected
366 * @param {Array} selections Array of currently selected nodes
372 afterRender: function(){
381 * We need to make copies of this since some of the events fired here will end up triggering
382 * a new event to be called and the shared event object will be mutated. In future we should
383 * investigate if there are any issues with creating a new event object for each event that
387 click: me.handleEvent,
388 mousedown: me.handleEvent,
389 mouseup: me.handleEvent,
390 dblclick: me.handleEvent,
391 contextmenu: me.handleEvent,
392 mouseover: me.handleEvent,
393 mouseout: me.handleEvent,
394 keydown: me.handleEvent
397 me.mon(me.getTargetEl(), listeners);
400 me.bindStore(me.store, true);
404 handleEvent: function(e) {
405 if (this.processUIEvent(e) !== false) {
406 this.processSpecialEvent(e);
410 // Private template method
411 processItemEvent: Ext.emptyFn,
412 processContainerEvent: Ext.emptyFn,
413 processSpecialEvent: Ext.emptyFn,
416 * Returns true if this mouseover/out event is still over the overItem.
418 stillOverItem: function (event, overItem) {
421 // There is this weird bug when you hover over the border of a cell it is saying
422 // the target is the table.
423 // BrowserBug: IE6 & 7. If me.mouseOverItem has been removed and is no longer
424 // in the DOM then accessing .offsetParent will throw an "Unspecified error." exception.
425 // typeof'ng and checking to make sure the offsetParent is an object will NOT throw
426 // this hard exception.
427 if (overItem && typeof(overItem.offsetParent) === "object") {
428 // mouseout : relatedTarget == nowOver, target == wasOver
429 // mouseover: relatedTarget == wasOver, target == nowOver
430 nowOver = (event.type == 'mouseout') ? event.getRelatedTarget() : event.getTarget();
431 return Ext.fly(overItem).contains(nowOver);
437 processUIEvent: function(e) {
439 item = e.getTarget(me.getItemSelector(), me.getTargetEl()),
440 map = this.statics().EventMap,
443 overItem = me.mouseOverItem,
447 if (type == 'mouseover' && me.stillOverItem(e, overItem)) {
451 // Try to get the selected item to handle the keydown event, otherwise we'll just fire a container keydown event
452 if (type == 'keydown') {
453 record = me.getSelectionModel().getLastSelected();
455 item = me.getNode(record);
461 index = me.indexOf(item);
463 record = me.getRecord(item);
466 if (me.processItemEvent(record, item, index, e) === false) {
470 newType = me.isNewItemEvent(item, e);
471 if (newType === false) {
476 (me['onBeforeItem' + map[newType]](record, item, index, e) === false) ||
477 (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) ||
478 (me['onItem' + map[newType]](record, item, index, e) === false)
483 me.fireEvent('item' + newType, me, record, item, index, e);
487 (me.processContainerEvent(e) === false) ||
488 (me['onBeforeContainer' + map[type]](e) === false) ||
489 (me.fireEvent('beforecontainer' + type, me, e) === false) ||
490 (me['onContainer' + map[type]](e) === false)
495 me.fireEvent('container' + type, me, e);
501 isNewItemEvent: function (item, e) {
503 overItem = me.mouseOverItem,
508 if (item === overItem) {
511 me.mouseOverItem = item;
515 // If the currently mouseovered item contains the mouseover target, it's *NOT* a mouseleave
516 if (me.stillOverItem(e, overItem)) {
519 me.mouseOverItem = null;
526 onItemMouseEnter: function(record, item, index, e) {
527 if (this.trackOver) {
528 this.highlightItem(item);
533 onItemMouseLeave : function(record, item, index, e) {
534 if (this.trackOver) {
535 this.clearHighlight();
539 // @private, template methods
540 onItemMouseDown: Ext.emptyFn,
541 onItemMouseUp: Ext.emptyFn,
542 onItemFocus: Ext.emptyFn,
543 onItemClick: Ext.emptyFn,
544 onItemDblClick: Ext.emptyFn,
545 onItemContextMenu: Ext.emptyFn,
546 onItemKeyDown: Ext.emptyFn,
547 onBeforeItemMouseDown: Ext.emptyFn,
548 onBeforeItemMouseUp: Ext.emptyFn,
549 onBeforeItemFocus: Ext.emptyFn,
550 onBeforeItemMouseEnter: Ext.emptyFn,
551 onBeforeItemMouseLeave: Ext.emptyFn,
552 onBeforeItemClick: Ext.emptyFn,
553 onBeforeItemDblClick: Ext.emptyFn,
554 onBeforeItemContextMenu: Ext.emptyFn,
555 onBeforeItemKeyDown: Ext.emptyFn,
557 // @private, template methods
558 onContainerMouseDown: Ext.emptyFn,
559 onContainerMouseUp: Ext.emptyFn,
560 onContainerMouseOver: Ext.emptyFn,
561 onContainerMouseOut: Ext.emptyFn,
562 onContainerClick: Ext.emptyFn,
563 onContainerDblClick: Ext.emptyFn,
564 onContainerContextMenu: Ext.emptyFn,
565 onContainerKeyDown: Ext.emptyFn,
566 onBeforeContainerMouseDown: Ext.emptyFn,
567 onBeforeContainerMouseUp: Ext.emptyFn,
568 onBeforeContainerMouseOver: Ext.emptyFn,
569 onBeforeContainerMouseOut: Ext.emptyFn,
570 onBeforeContainerClick: Ext.emptyFn,
571 onBeforeContainerDblClick: Ext.emptyFn,
572 onBeforeContainerContextMenu: Ext.emptyFn,
573 onBeforeContainerKeyDown: Ext.emptyFn,
576 * Highlight a given item in the DataView. This is called by the mouseover handler if {@link #overItemCls}
577 * and {@link #trackOver} are configured, but can also be called manually by other code, for instance to
578 * handle stepping through the list via keyboard navigation.
579 * @param {HTMLElement} item The item to highlight
581 highlightItem: function(item) {
584 me.highlightedItem = item;
585 Ext.fly(item).addCls(me.overItemCls);
589 * Un-highlight the currently highlighted item, if any.
591 clearHighlight: function() {
593 highlighted = me.highlightedItem;
596 Ext.fly(highlighted).removeCls(me.overItemCls);
597 delete me.highlightedItem;
601 refresh: function() {
604 me.callParent(arguments);
605 if (!me.isFixedHeight()) {
606 me.doComponentLayout();