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 * A mechanism for displaying data using custom layout templates and formatting.
18 * The View uses an {@link Ext.XTemplate} as its internal templating mechanism, and is bound to an
19 * {@link Ext.data.Store} so that as the data in the store changes the view is automatically updated
20 * to reflect the changes. The view also provides built-in behavior for many common events that can
21 * occur for its contained items including click, doubleclick, mouseover, mouseout, etc. as well as a
22 * built-in selection model. **In order to use these features, an {@link #itemSelector} config must
23 * be provided for the DataView to determine what nodes it will be working with.**
25 * The example below binds a View to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}.
28 * Ext.define('Image', {
29 * extend: 'Ext.data.Model',
31 * { name:'src', type:'string' },
32 * { name:'caption', type:'string' }
36 * Ext.create('Ext.data.Store', {
40 * { src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts' },
41 * { src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data' },
42 * { src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme' },
43 * { src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned' }
47 * var imageTpl = new Ext.XTemplate(
49 * '<div style="margin-bottom: 10px;" class="thumb-wrap">',
50 * '<img src="{src}" />',
51 * '<br/><span>{caption}</span>',
56 * Ext.create('Ext.view.View', {
57 * store: Ext.data.StoreManager.lookup('imagesStore'),
59 * itemSelector: 'div.thumb-wrap',
60 * emptyText: 'No images available',
61 * renderTo: Ext.getBody()
64 Ext.define('Ext.view.View', {
65 extend: 'Ext.view.AbstractView',
66 alternateClassName: 'Ext.DataView',
67 alias: 'widget.dataview',
71 mousedown: 'MouseDown',
75 contextmenu: 'ContextMenu',
76 mouseover: 'MouseOver',
78 mouseenter: 'MouseEnter',
79 mouseleave: 'MouseLeave',
85 addCmpEvents: function() {
88 * @event beforeitemmousedown
89 * Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
90 * @param {Ext.view.View} this
91 * @param {Ext.data.Model} record The record that belongs to the item
92 * @param {HTMLElement} item The item's element
93 * @param {Number} index The item's index
94 * @param {Ext.EventObject} e The raw event object
96 'beforeitemmousedown',
98 * @event beforeitemmouseup
99 * Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
100 * @param {Ext.view.View} this
101 * @param {Ext.data.Model} record The record that belongs to the item
102 * @param {HTMLElement} item The item's element
103 * @param {Number} index The item's index
104 * @param {Ext.EventObject} e The raw event object
108 * @event beforeitemmouseenter
109 * Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
110 * @param {Ext.view.View} this
111 * @param {Ext.data.Model} record The record that belongs to the item
112 * @param {HTMLElement} item The item's element
113 * @param {Number} index The item's index
114 * @param {Ext.EventObject} e The raw event object
116 'beforeitemmouseenter',
118 * @event beforeitemmouseleave
119 * Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
120 * @param {Ext.view.View} this
121 * @param {Ext.data.Model} record The record that belongs to the item
122 * @param {HTMLElement} item The item's element
123 * @param {Number} index The item's index
124 * @param {Ext.EventObject} e The raw event object
126 'beforeitemmouseleave',
128 * @event beforeitemclick
129 * Fires before the click event on an item is processed. Returns false to cancel the default action.
130 * @param {Ext.view.View} this
131 * @param {Ext.data.Model} record The record that belongs to the item
132 * @param {HTMLElement} item The item's element
133 * @param {Number} index The item's index
134 * @param {Ext.EventObject} e The raw event object
138 * @event beforeitemdblclick
139 * Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
140 * @param {Ext.view.View} this
141 * @param {Ext.data.Model} record The record that belongs to the item
142 * @param {HTMLElement} item The item's element
143 * @param {Number} index The item's index
144 * @param {Ext.EventObject} e The raw event object
146 'beforeitemdblclick',
148 * @event beforeitemcontextmenu
149 * Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
150 * @param {Ext.view.View} this
151 * @param {Ext.data.Model} record The record that belongs to the item
152 * @param {HTMLElement} item The item's element
153 * @param {Number} index The item's index
154 * @param {Ext.EventObject} e The raw event object
156 'beforeitemcontextmenu',
158 * @event beforeitemkeydown
159 * Fires before the keydown event on an item is processed. Returns false to cancel the default action.
160 * @param {Ext.view.View} this
161 * @param {Ext.data.Model} record The record that belongs to the item
162 * @param {HTMLElement} item The item's element
163 * @param {Number} index The item's index
164 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
168 * @event itemmousedown
169 * Fires when there is a mouse down on an item
170 * @param {Ext.view.View} this
171 * @param {Ext.data.Model} record The record that belongs to the item
172 * @param {HTMLElement} item The item's element
173 * @param {Number} index The item's index
174 * @param {Ext.EventObject} e The raw event object
179 * Fires when there is a mouse up on an item
180 * @param {Ext.view.View} this
181 * @param {Ext.data.Model} record The record that belongs to the item
182 * @param {HTMLElement} item The item's element
183 * @param {Number} index The item's index
184 * @param {Ext.EventObject} e The raw event object
188 * @event itemmouseenter
189 * Fires when the mouse enters an item.
190 * @param {Ext.view.View} this
191 * @param {Ext.data.Model} record The record that belongs to the item
192 * @param {HTMLElement} item The item's element
193 * @param {Number} index The item's index
194 * @param {Ext.EventObject} e The raw event object
198 * @event itemmouseleave
199 * Fires when the mouse leaves an item.
200 * @param {Ext.view.View} this
201 * @param {Ext.data.Model} record The record that belongs to the item
202 * @param {HTMLElement} item The item's element
203 * @param {Number} index The item's index
204 * @param {Ext.EventObject} e The raw event object
209 * Fires when an item is clicked.
210 * @param {Ext.view.View} this
211 * @param {Ext.data.Model} record The record that belongs to the item
212 * @param {HTMLElement} item The item's element
213 * @param {Number} index The item's index
214 * @param {Ext.EventObject} e The raw event object
218 * @event itemdblclick
219 * Fires when an item is double clicked.
220 * @param {Ext.view.View} this
221 * @param {Ext.data.Model} record The record that belongs to the item
222 * @param {HTMLElement} item The item's element
223 * @param {Number} index The item's index
224 * @param {Ext.EventObject} e The raw event object
228 * @event itemcontextmenu
229 * Fires when an item is right clicked.
230 * @param {Ext.view.View} this
231 * @param {Ext.data.Model} record The record that belongs to the item
232 * @param {HTMLElement} item The item's element
233 * @param {Number} index The item's index
234 * @param {Ext.EventObject} e The raw event object
239 * Fires when a key is pressed while an item is currently selected.
240 * @param {Ext.view.View} this
241 * @param {Ext.data.Model} record The record that belongs to the item
242 * @param {HTMLElement} item The item's element
243 * @param {Number} index The item's index
244 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
248 * @event beforecontainermousedown
249 * Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
250 * @param {Ext.view.View} this
251 * @param {Ext.EventObject} e The raw event object
253 'beforecontainermousedown',
255 * @event beforecontainermouseup
256 * Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
257 * @param {Ext.view.View} this
258 * @param {Ext.EventObject} e The raw event object
260 'beforecontainermouseup',
262 * @event beforecontainermouseover
263 * Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
264 * @param {Ext.view.View} this
265 * @param {Ext.EventObject} e The raw event object
267 'beforecontainermouseover',
269 * @event beforecontainermouseout
270 * Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
271 * @param {Ext.view.View} this
272 * @param {Ext.EventObject} e The raw event object
274 'beforecontainermouseout',
276 * @event beforecontainerclick
277 * Fires before the click event on the container is processed. Returns false to cancel the default action.
278 * @param {Ext.view.View} this
279 * @param {Ext.EventObject} e The raw event object
281 'beforecontainerclick',
283 * @event beforecontainerdblclick
284 * Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
285 * @param {Ext.view.View} this
286 * @param {Ext.EventObject} e The raw event object
288 'beforecontainerdblclick',
290 * @event beforecontainercontextmenu
291 * Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
292 * @param {Ext.view.View} this
293 * @param {Ext.EventObject} e The raw event object
295 'beforecontainercontextmenu',
297 * @event beforecontainerkeydown
298 * Fires before the keydown event on the container is processed. Returns false to cancel the default action.
299 * @param {Ext.view.View} this
300 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
302 'beforecontainerkeydown',
304 * @event containermouseup
305 * Fires when there is a mouse up on the container
306 * @param {Ext.view.View} this
307 * @param {Ext.EventObject} e The raw event object
311 * @event containermouseover
312 * Fires when you move the mouse over the container.
313 * @param {Ext.view.View} this
314 * @param {Ext.EventObject} e The raw event object
316 'containermouseover',
318 * @event containermouseout
319 * Fires when you move the mouse out of the container.
320 * @param {Ext.view.View} this
321 * @param {Ext.EventObject} e The raw event object
325 * @event containerclick
326 * Fires when the container is clicked.
327 * @param {Ext.view.View} this
328 * @param {Ext.EventObject} e The raw event object
332 * @event containerdblclick
333 * Fires when the container is double clicked.
334 * @param {Ext.view.View} this
335 * @param {Ext.EventObject} e The raw event object
339 * @event containercontextmenu
340 * Fires when the container is right clicked.
341 * @param {Ext.view.View} this
342 * @param {Ext.EventObject} e The raw event object
344 'containercontextmenu',
346 * @event containerkeydown
347 * Fires when a key is pressed while the container is focused, and no item is currently selected.
348 * @param {Ext.view.View} this
349 * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
354 * @event selectionchange
355 * Fires when the selected nodes change. Relayed event from the underlying selection model.
356 * @param {Ext.view.View} this
357 * @param {HTMLElement[]} selections Array of the selected nodes
361 * @event beforeselect
362 * Fires before a selection is made. If any handlers return false, the selection is cancelled.
363 * @param {Ext.view.View} this
364 * @param {HTMLElement} node The node to be selected
365 * @param {HTMLElement[]} selections Array of currently selected nodes
371 afterRender: function(){
380 * We need to make copies of this since some of the events fired here will end up triggering
381 * a new event to be called and the shared event object will be mutated. In future we should
382 * investigate if there are any issues with creating a new event object for each event that
386 click: me.handleEvent,
387 mousedown: me.handleEvent,
388 mouseup: me.handleEvent,
389 dblclick: me.handleEvent,
390 contextmenu: me.handleEvent,
391 mouseover: me.handleEvent,
392 mouseout: me.handleEvent,
393 keydown: me.handleEvent
396 me.mon(me.getTargetEl(), listeners);
399 me.bindStore(me.store, true);
403 handleEvent: function(e) {
404 if (this.processUIEvent(e) !== false) {
405 this.processSpecialEvent(e);
409 // Private template method
410 processItemEvent: Ext.emptyFn,
411 processContainerEvent: Ext.emptyFn,
412 processSpecialEvent: Ext.emptyFn,
415 * Returns true if this mouseover/out event is still over the overItem.
417 stillOverItem: function (event, overItem) {
420 // There is this weird bug when you hover over the border of a cell it is saying
421 // the target is the table.
422 // BrowserBug: IE6 & 7. If me.mouseOverItem has been removed and is no longer
423 // in the DOM then accessing .offsetParent will throw an "Unspecified error." exception.
424 // typeof'ng and checking to make sure the offsetParent is an object will NOT throw
425 // this hard exception.
426 if (overItem && typeof(overItem.offsetParent) === "object") {
427 // mouseout : relatedTarget == nowOver, target == wasOver
428 // mouseover: relatedTarget == wasOver, target == nowOver
429 nowOver = (event.type == 'mouseout') ? event.getRelatedTarget() : event.getTarget();
430 return Ext.fly(overItem).contains(nowOver);
436 processUIEvent: function(e) {
438 item = e.getTarget(me.getItemSelector(), me.getTargetEl()),
439 map = this.statics().EventMap,
442 overItem = me.mouseOverItem,
446 if (type == 'mouseover' && me.stillOverItem(e, overItem)) {
450 // Try to get the selected item to handle the keydown event, otherwise we'll just fire a container keydown event
451 if (type == 'keydown') {
452 record = me.getSelectionModel().getLastSelected();
454 item = me.getNode(record);
460 index = me.indexOf(item);
462 record = me.getRecord(item);
465 if (me.processItemEvent(record, item, index, e) === false) {
469 newType = me.isNewItemEvent(item, e);
470 if (newType === false) {
475 (me['onBeforeItem' + map[newType]](record, item, index, e) === false) ||
476 (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) ||
477 (me['onItem' + map[newType]](record, item, index, e) === false)
482 me.fireEvent('item' + newType, me, record, item, index, e);
486 (me.processContainerEvent(e) === false) ||
487 (me['onBeforeContainer' + map[type]](e) === false) ||
488 (me.fireEvent('beforecontainer' + type, me, e) === false) ||
489 (me['onContainer' + map[type]](e) === false)
494 me.fireEvent('container' + type, me, e);
500 isNewItemEvent: function (item, e) {
502 overItem = me.mouseOverItem,
507 if (item === overItem) {
510 me.mouseOverItem = item;
514 // If the currently mouseovered item contains the mouseover target, it's *NOT* a mouseleave
515 if (me.stillOverItem(e, overItem)) {
518 me.mouseOverItem = null;
525 onItemMouseEnter: function(record, item, index, e) {
526 if (this.trackOver) {
527 this.highlightItem(item);
532 onItemMouseLeave : function(record, item, index, e) {
533 if (this.trackOver) {
534 this.clearHighlight();
538 // @private, template methods
539 onItemMouseDown: Ext.emptyFn,
540 onItemMouseUp: Ext.emptyFn,
541 onItemFocus: Ext.emptyFn,
542 onItemClick: Ext.emptyFn,
543 onItemDblClick: Ext.emptyFn,
544 onItemContextMenu: Ext.emptyFn,
545 onItemKeyDown: Ext.emptyFn,
546 onBeforeItemMouseDown: Ext.emptyFn,
547 onBeforeItemMouseUp: Ext.emptyFn,
548 onBeforeItemFocus: Ext.emptyFn,
549 onBeforeItemMouseEnter: Ext.emptyFn,
550 onBeforeItemMouseLeave: Ext.emptyFn,
551 onBeforeItemClick: Ext.emptyFn,
552 onBeforeItemDblClick: Ext.emptyFn,
553 onBeforeItemContextMenu: Ext.emptyFn,
554 onBeforeItemKeyDown: Ext.emptyFn,
556 // @private, template methods
557 onContainerMouseDown: Ext.emptyFn,
558 onContainerMouseUp: Ext.emptyFn,
559 onContainerMouseOver: Ext.emptyFn,
560 onContainerMouseOut: Ext.emptyFn,
561 onContainerClick: Ext.emptyFn,
562 onContainerDblClick: Ext.emptyFn,
563 onContainerContextMenu: Ext.emptyFn,
564 onContainerKeyDown: Ext.emptyFn,
565 onBeforeContainerMouseDown: Ext.emptyFn,
566 onBeforeContainerMouseUp: Ext.emptyFn,
567 onBeforeContainerMouseOver: Ext.emptyFn,
568 onBeforeContainerMouseOut: Ext.emptyFn,
569 onBeforeContainerClick: Ext.emptyFn,
570 onBeforeContainerDblClick: Ext.emptyFn,
571 onBeforeContainerContextMenu: Ext.emptyFn,
572 onBeforeContainerKeyDown: Ext.emptyFn,
575 * Highlights a given item in the DataView. This is called by the mouseover handler if {@link #overItemCls}
576 * and {@link #trackOver} are configured, but can also be called manually by other code, for instance to
577 * handle stepping through the list via keyboard navigation.
578 * @param {HTMLElement} item The item to highlight
580 highlightItem: function(item) {
583 me.highlightedItem = item;
584 Ext.fly(item).addCls(me.overItemCls);
588 * Un-highlights the currently highlighted item, if any.
590 clearHighlight: function() {
592 highlighted = me.highlightedItem;
595 Ext.fly(highlighted).removeCls(me.overItemCls);
596 delete me.highlightedItem;
600 refresh: function() {
603 me.callParent(arguments);
604 if (!me.isFixedHeight()) {
605 me.doComponentLayout();