macoslinuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-services
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
881 lines
32 KiB
881 lines
32 KiB
9 years ago
|
/**
|
||
|
* A mechanism for displaying data using custom layout templates and formatting.
|
||
|
*
|
||
|
* The View uses an {@link Ext.XTemplate} as its internal templating mechanism, and is bound to an
|
||
|
* {@link Ext.data.Store} so that as the data in the store changes the view is automatically updated
|
||
|
* to reflect the changes. The view also provides built-in behavior for many common events that can
|
||
|
* occur for its contained items including click, doubleclick, mouseover, mouseout, etc. as well as a
|
||
|
* built-in selection model. **In order to use these features, an {@link #itemSelector} config must
|
||
|
* be provided for the View to determine what nodes it will be working with.**
|
||
|
*
|
||
|
* The example below binds a View to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}.
|
||
|
*
|
||
|
* @example
|
||
|
* Ext.define('Image', {
|
||
|
* extend: 'Ext.data.Model',
|
||
|
* fields: [
|
||
|
* { name:'src', type:'string' },
|
||
|
* { name:'caption', type:'string' }
|
||
|
* ]
|
||
|
* });
|
||
|
*
|
||
|
* Ext.create('Ext.data.Store', {
|
||
|
* id:'imagesStore',
|
||
|
* model: 'Image',
|
||
|
* data: [
|
||
|
* { src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts' },
|
||
|
* { src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data' },
|
||
|
* { src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme' },
|
||
|
* { src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned' }
|
||
|
* ]
|
||
|
* });
|
||
|
*
|
||
|
* var imageTpl = new Ext.XTemplate(
|
||
|
* '<tpl for=".">',
|
||
|
* '<div style="margin-bottom: 10px;" class="thumb-wrap">',
|
||
|
* '<img src="{src}" />',
|
||
|
* '<br/><span>{caption}</span>',
|
||
|
* '</div>',
|
||
|
* '</tpl>'
|
||
|
* );
|
||
|
*
|
||
|
* Ext.create('Ext.view.View', {
|
||
|
* store: Ext.data.StoreManager.lookup('imagesStore'),
|
||
|
* tpl: imageTpl,
|
||
|
* itemSelector: 'div.thumb-wrap',
|
||
|
* emptyText: 'No images available',
|
||
|
* renderTo: Ext.getBody()
|
||
|
* });
|
||
|
*/
|
||
|
Ext.define('Ext.view.View', {
|
||
|
extend: 'Ext.view.AbstractView',
|
||
|
alternateClassName: 'Ext.DataView',
|
||
|
alias: 'widget.dataview',
|
||
|
|
||
|
inputTagRe: /^textarea$|^input$/i,
|
||
|
keyEventRe: /^key/,
|
||
|
|
||
|
inheritableStatics: {
|
||
|
EventMap: {
|
||
|
longpress: 'LongPress',
|
||
|
mousedown: 'MouseDown',
|
||
|
mouseup: 'MouseUp',
|
||
|
click: 'Click',
|
||
|
dblclick: 'DblClick',
|
||
|
contextmenu: 'ContextMenu',
|
||
|
mouseover: 'MouseOver',
|
||
|
mouseout: 'MouseOut',
|
||
|
mouseenter: 'MouseEnter',
|
||
|
mouseleave: 'MouseLeave',
|
||
|
keydown: 'KeyDown',
|
||
|
keyup: 'KeyUp',
|
||
|
keypress: 'KeyPress',
|
||
|
focus: 'Focus'
|
||
|
},
|
||
|
TouchEventMap: {
|
||
|
touchstart: 'mousedown',
|
||
|
touchend: 'mouseup',
|
||
|
tap: 'click',
|
||
|
doubletap: 'dblclick'
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemmousedown
|
||
|
* Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemmouseup
|
||
|
* Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemmouseenter
|
||
|
* Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemmouseleave
|
||
|
* Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemclick
|
||
|
* Fires before the click event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemdblclick
|
||
|
* Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemcontextmenu
|
||
|
* Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemkeydown
|
||
|
* Fires before the keydown event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemkeyup
|
||
|
* Fires before the keyup event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeitemkeypress
|
||
|
* Fires before the keypress event on an item is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemmousedown
|
||
|
* Fires when there is a mouse down on an item
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemmouseup
|
||
|
* Fires when there is a mouse up on an item
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemmouseenter
|
||
|
* Fires when the mouse enters an item.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemmouseleave
|
||
|
* Fires when the mouse leaves an item.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemclick
|
||
|
* Fires when an item is clicked.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemdblclick
|
||
|
* Fires when an item is double clicked.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemcontextmenu
|
||
|
* Fires when an item is right clicked.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemkeydown
|
||
|
* Fires when a key is pressed down while an item is currently selected.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemkeyup
|
||
|
* Fires when a key is released while an item is currently selected.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event itemkeypress
|
||
|
* Fires when a key is pressed while an item is currently selected.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.data.Model} record The record that belongs to the item
|
||
|
* @param {HTMLElement} item The item's element
|
||
|
* @param {Number} index The item's index
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainermousedown
|
||
|
* Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainermouseup
|
||
|
* Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainermouseover
|
||
|
* Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainermouseout
|
||
|
* Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainerclick
|
||
|
* Fires before the click event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainerdblclick
|
||
|
* Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainercontextmenu
|
||
|
* Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainerkeydown
|
||
|
* Fires before the keydown event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainerkeyup
|
||
|
* Fires before the keyup event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforecontainerkeypress
|
||
|
* Fires before the keypress event on the container is processed. Returns false to cancel the default action.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containermousedown
|
||
|
* Fires when there is a mousedown on the container
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containermouseup
|
||
|
* Fires when there is a mouseup on the container
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containermouseover
|
||
|
* Fires when you move the mouse over the container.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containermouseout
|
||
|
* Fires when you move the mouse out of the container.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containerclick
|
||
|
* Fires when the container is clicked.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containerdblclick
|
||
|
* Fires when the container is double clicked.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containercontextmenu
|
||
|
* Fires when the container is right clicked.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containerkeydown
|
||
|
* Fires when a key is pressed down while the container is focused, and no item is currently selected.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containerkeyup
|
||
|
* Fires when a key is released while the container is focused, and no item is currently selected.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event containerkeypress
|
||
|
* Fires when a key is pressed while the container is focused, and no item is currently selected.
|
||
|
* @param {Ext.view.View} this
|
||
|
* @param {Ext.event.Event} e The raw event object. Use {@link Ext.event.Event#getKey getKey()} to retrieve the key that was pressed.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event selectionchange
|
||
|
* @inheritdoc Ext.selection.DataViewModel#selectionchange
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforeselect
|
||
|
* @inheritdoc Ext.selection.DataViewModel#beforeselect
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event beforedeselect
|
||
|
* @inheritdoc Ext.selection.DataViewModel#beforedeselect
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event select
|
||
|
* @inheritdoc Ext.selection.DataViewModel#select
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event deselect
|
||
|
* @inheritdoc Ext.selection.DataViewModel#deselect
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event focuschange
|
||
|
* @inheritdoc Ext.selection.DataViewModel#focuschange
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event highlightitem
|
||
|
* Fires when a node is highlighted using keyboard navigation, or mouseover.
|
||
|
* @param {Ext.view.View} view This View Component.
|
||
|
* @param {Ext.dom.Element} node The highlighted node.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @event unhighlightitem
|
||
|
* Fires when a node is unhighlighted using keyboard navigation, or mouseout.
|
||
|
* @param {Ext.view.View} view This View Component.
|
||
|
* @param {Ext.dom.Element} node The previously highlighted node.
|
||
|
*/
|
||
|
|
||
|
afterRender: function() {
|
||
|
var me = this;
|
||
|
|
||
|
me.callParent();
|
||
|
me.mon(me.el, {
|
||
|
scope: me,
|
||
|
click: me.handleEvent,
|
||
|
longpress: me.handleEvent,
|
||
|
mousedown: me.handleEvent,
|
||
|
mouseup: me.handleEvent,
|
||
|
dblclick: me.handleEvent,
|
||
|
contextmenu: me.handleEvent,
|
||
|
keydown: me.handleEvent,
|
||
|
keyup: me.handleEvent,
|
||
|
keypress: me.handleEvent,
|
||
|
mouseover: me.handleMouseOver,
|
||
|
mouseout: me.handleMouseOut
|
||
|
});
|
||
|
},
|
||
|
|
||
|
// Can be overridden by features or anything that needs to use a specific selector as a target.
|
||
|
getTargetSelector: function () {
|
||
|
return this.dataRowSelector || this.itemSelector;
|
||
|
},
|
||
|
|
||
|
handleMouseOver: function(e) {
|
||
|
var me = this,
|
||
|
// this.getTargetSelector() can be used as a template method, e.g., in features.
|
||
|
itemSelector = me.getTargetSelector(),
|
||
|
item = e.getTarget(itemSelector);
|
||
|
|
||
|
// If mouseover/out handling is buffered, view might have been destyroyed during buffer time.
|
||
|
if (!me.isDestroyed) {
|
||
|
if (item) {
|
||
|
if (me.mouseOverItem !== item && me.el.contains(item)) {
|
||
|
me.mouseOverItem = e.item = item;
|
||
|
e.newType = 'mouseenter';
|
||
|
me.handleEvent(e);
|
||
|
}
|
||
|
} else {
|
||
|
// We're not over an item, so handle a container event.
|
||
|
me.handleEvent(e);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
handleMouseOut: function (e) {
|
||
|
var itemSelector = this.getTargetSelector(),
|
||
|
item = e.getTarget(itemSelector),
|
||
|
computedRelatedTarget = e.getRelatedTarget(itemSelector),
|
||
|
sourceView;
|
||
|
|
||
|
// We can only exit early when mousing within the same row, but we can't simply do an equality check
|
||
|
// since it's valid for both item and computedRelatedTarget to be null!
|
||
|
if ((item === computedRelatedTarget) && !(item === null && computedRelatedTarget === null)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Note that a mouseout event can trigger either an item event or a container event.
|
||
|
// If mouseover/out handling is buffered, view might have been destroyed during buffer time.
|
||
|
if (!this.isDestroyed) {
|
||
|
// Yes, this is an assignment.
|
||
|
if (item && (sourceView = this.self.getBoundView(item))) {
|
||
|
e.item = item;
|
||
|
e.newType = 'mouseleave';
|
||
|
sourceView.handleEvent(e);
|
||
|
sourceView.mouseOverItem = null;
|
||
|
} else {
|
||
|
// We're not over an item, so handle a container event.
|
||
|
this.handleEvent(e);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
handleEvent: function(e) {
|
||
|
var me = this,
|
||
|
isKeyEvent = me.keyEventRe.test(e.type),
|
||
|
nm = me.getNavigationModel();
|
||
|
|
||
|
e.view = me;
|
||
|
|
||
|
if (isKeyEvent) {
|
||
|
e.item = nm.getItem();
|
||
|
e.record = nm.getRecord();
|
||
|
}
|
||
|
|
||
|
// If the key event was fired programatically, it will not have triggered the focus
|
||
|
// so the NavigationModel will not have this information.
|
||
|
if (!e.item) {
|
||
|
e.item = e.getTarget(me.itemSelector);
|
||
|
}
|
||
|
if (e.item && !e.record) {
|
||
|
e.record = me.getRecord(e.item);
|
||
|
}
|
||
|
|
||
|
if (me.processUIEvent(e) !== false) {
|
||
|
me.processSpecialEvent(e);
|
||
|
}
|
||
|
|
||
|
// We need to prevent default action on navigation keys
|
||
|
// that can cause View element scroll unless the event is from an input field.
|
||
|
// We MUST prevent browser's default action on SPACE which is to focus the event's target element.
|
||
|
// Focusing causes the browser to attempt to scroll the element into view.
|
||
|
if (isKeyEvent && !Ext.fly(e.target).isInputField()) {
|
||
|
if (e.getKey() === e.SPACE || e.isNavKeyPress(true)) {
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// Private template method
|
||
|
processItemEvent: Ext.emptyFn,
|
||
|
processContainerEvent: Ext.emptyFn,
|
||
|
processSpecialEvent: Ext.emptyFn,
|
||
|
|
||
|
processUIEvent: function(e) {
|
||
|
|
||
|
// If the target event has been removed from the body (data update causing view DOM to be updated),
|
||
|
// do not process. isAncestor uses native methods to check.
|
||
|
if (!Ext.getBody().isAncestor(e.target)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var me = this,
|
||
|
item = e.item,
|
||
|
self = me.self,
|
||
|
map = self.EventMap,
|
||
|
touchMap = self.TouchEventMap,
|
||
|
index,
|
||
|
record = e.record,
|
||
|
type = e.type,
|
||
|
newType = type;
|
||
|
|
||
|
// If the event is a mouseover/mouseout event converted to a mouseenter/mouseleave,
|
||
|
// use that event type.
|
||
|
if (e.newType) {
|
||
|
newType = e.newType;
|
||
|
}
|
||
|
|
||
|
if (item) {
|
||
|
newType = touchMap[newType] || newType;
|
||
|
index = e.recordIndex = me.indexInStore ? me.indexInStore(record) : me.indexOf(item);
|
||
|
|
||
|
// It is possible for an event to arrive for which there is no record... this
|
||
|
// can happen with dblclick where the clicks are on removal actions (think a
|
||
|
// grid w/"delete row" action column) or if the record was in a page that was
|
||
|
// pruned by a buffered store.
|
||
|
if (!record || me.processItemEvent(record, item, index, e) === false) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
(me['onBeforeItem' + map[newType]](record, item, index, e) === false) ||
|
||
|
(me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) ||
|
||
|
(me['onItem' + map[newType]](record, item, index, e) === false)
|
||
|
) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
me.fireEvent('item' + newType, me, record, item, index, e);
|
||
|
}
|
||
|
else {
|
||
|
type = touchMap[type] || type;
|
||
|
if (
|
||
|
(me.processContainerEvent(e) === false) ||
|
||
|
(me['onBeforeContainer' + map[type]](e) === false) ||
|
||
|
(me.fireEvent('beforecontainer' + type, me, e) === false) ||
|
||
|
(me['onContainer' + map[type]](e) === false)
|
||
|
) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
me.fireEvent('container' + type, me, e);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
},
|
||
|
|
||
|
// @private
|
||
|
onItemMouseEnter: function(record, item, index, e) {
|
||
|
if (this.trackOver) {
|
||
|
this.highlightItem(item);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// @private
|
||
|
onItemMouseLeave : function(record, item, index, e) {
|
||
|
if (this.trackOver) {
|
||
|
this.clearHighlight();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// private, template methods
|
||
|
onItemMouseDown: Ext.emptyFn,
|
||
|
onItemLongPress: Ext.emptyFn,
|
||
|
onItemMouseUp: Ext.emptyFn,
|
||
|
onItemFocus: Ext.emptyFn,
|
||
|
onItemClick: Ext.emptyFn,
|
||
|
onItemDblClick: Ext.emptyFn,
|
||
|
onItemContextMenu: Ext.emptyFn,
|
||
|
onItemKeyDown: Ext.emptyFn,
|
||
|
onItemKeyUp: Ext.emptyFn,
|
||
|
onItemKeyPress: Ext.emptyFn,
|
||
|
onBeforeItemLongPress: Ext.emptyFn,
|
||
|
onBeforeItemMouseDown: Ext.emptyFn,
|
||
|
onBeforeItemMouseUp: Ext.emptyFn,
|
||
|
onBeforeItemFocus: Ext.emptyFn,
|
||
|
onBeforeItemMouseEnter: Ext.emptyFn,
|
||
|
onBeforeItemMouseLeave: Ext.emptyFn,
|
||
|
onBeforeItemClick: Ext.emptyFn,
|
||
|
onBeforeItemDblClick: Ext.emptyFn,
|
||
|
onBeforeItemContextMenu: Ext.emptyFn,
|
||
|
onBeforeItemKeyDown: Ext.emptyFn,
|
||
|
onBeforeItemKeyUp: Ext.emptyFn,
|
||
|
onBeforeItemKeyPress: Ext.emptyFn,
|
||
|
|
||
|
// private, template methods
|
||
|
onContainerMouseDown: Ext.emptyFn,
|
||
|
onContainerLongPress: Ext.emptyFn,
|
||
|
onContainerMouseUp: Ext.emptyFn,
|
||
|
onContainerMouseOver: Ext.emptyFn,
|
||
|
onContainerMouseOut: Ext.emptyFn,
|
||
|
onContainerClick: Ext.emptyFn,
|
||
|
onContainerDblClick: Ext.emptyFn,
|
||
|
onContainerContextMenu: Ext.emptyFn,
|
||
|
onContainerKeyDown: Ext.emptyFn,
|
||
|
onContainerKeyUp: Ext.emptyFn,
|
||
|
onContainerKeyPress: Ext.emptyFn,
|
||
|
onBeforeContainerMouseDown: Ext.emptyFn,
|
||
|
onBeforeContainerLongPress: Ext.emptyFn,
|
||
|
onBeforeContainerMouseUp: Ext.emptyFn,
|
||
|
onBeforeContainerMouseOver: Ext.emptyFn,
|
||
|
onBeforeContainerMouseOut: Ext.emptyFn,
|
||
|
onBeforeContainerClick: Ext.emptyFn,
|
||
|
onBeforeContainerDblClick: Ext.emptyFn,
|
||
|
onBeforeContainerContextMenu: Ext.emptyFn,
|
||
|
onBeforeContainerKeyDown: Ext.emptyFn,
|
||
|
onBeforeContainerKeyUp: Ext.emptyFn,
|
||
|
onBeforeContainerKeyPress: Ext.emptyFn,
|
||
|
|
||
|
// @private
|
||
|
|
||
|
setHighlightedItem: function(item){
|
||
|
var me = this,
|
||
|
highlighted = me.highlightedItem,
|
||
|
overItemCls = me.overItemCls;
|
||
|
|
||
|
if (highlighted !== item){
|
||
|
if (highlighted) {
|
||
|
Ext.fly(highlighted).removeCls(overItemCls);
|
||
|
//<feature legacyBrowser>
|
||
|
// Work around for an issue in IE8 where the focus/over/selected borders do not
|
||
|
// get updated where applied using adjacent sibling selectors.
|
||
|
if (Ext.isIE8) {
|
||
|
me.repaintBorder(highlighted);
|
||
|
me.repaintBorder(highlighted.nextSibling);
|
||
|
}
|
||
|
//</feature>
|
||
|
if (me.hasListeners.unhighlightitem) {
|
||
|
me.fireEvent('unhighlightitem', me, highlighted);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
me.highlightedItem = item;
|
||
|
|
||
|
if (item) {
|
||
|
Ext.fly(item).addCls(me.overItemCls);
|
||
|
//<feature legacyBrowser>
|
||
|
// Work around for an issue in IE8 where the focus/over/selected borders do not
|
||
|
// get updated where applied using adjacent sibling selectors.
|
||
|
if (Ext.isIE8) {
|
||
|
me.repaintBorder(item.nextSibling);
|
||
|
}
|
||
|
//</feature>
|
||
|
if (me.hasListeners.highlightitem) {
|
||
|
me.fireEvent('highlightitem', me, item);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Highlights a given item in the View. This is called by the mouseover handler if {@link #overItemCls}
|
||
|
* and {@link #trackOver} are configured, but can also be called manually by other code, for instance to
|
||
|
* handle stepping through the list via keyboard navigation.
|
||
|
* @param {HTMLElement} item The item to highlight
|
||
|
*/
|
||
|
highlightItem: function(item) {
|
||
|
this.setHighlightedItem(item);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Un-highlights the currently highlighted item, if any.
|
||
|
*/
|
||
|
clearHighlight: function() {
|
||
|
this.setHighlightedItem(undefined);
|
||
|
},
|
||
|
|
||
|
handleUpdate: function(store, record){
|
||
|
var me = this,
|
||
|
node,
|
||
|
newNode,
|
||
|
highlighted;
|
||
|
|
||
|
if (me.viewReady) {
|
||
|
node = me.getNode(record);
|
||
|
newNode = me.callParent(arguments);
|
||
|
highlighted = me.highlightedItem;
|
||
|
|
||
|
if (highlighted && highlighted === node) {
|
||
|
delete me.highlightedItem;
|
||
|
if (newNode) {
|
||
|
me.highlightItem(newNode);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
refresh: function() {
|
||
|
this.clearHighlight();
|
||
|
this.callParent(arguments);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Focuses a node in the view.
|
||
|
* @param {Ext.data.Model} rec The record associated to the node that is to be focused.
|
||
|
*/
|
||
|
focusNode: function(rec){
|
||
|
var me = this,
|
||
|
node = me.getNode(rec),
|
||
|
el = me.el,
|
||
|
adjustmentY = 0,
|
||
|
adjustmentX = 0,
|
||
|
elRegion = el.getRegion(),
|
||
|
nodeRegion;
|
||
|
|
||
|
// Viewable region must not include scrollbars, so use
|
||
|
// DOM client dimensions
|
||
|
elRegion.bottom = elRegion.top + el.dom.clientHeight;
|
||
|
elRegion.right = elRegion.left + el.dom.clientWidth;
|
||
|
if (node) {
|
||
|
nodeRegion = Ext.fly(node).getRegion();
|
||
|
// node is above
|
||
|
if (nodeRegion.top < elRegion.top) {
|
||
|
adjustmentY = nodeRegion.top - elRegion.top;
|
||
|
// node is below
|
||
|
} else if (nodeRegion.bottom > elRegion.bottom) {
|
||
|
adjustmentY = nodeRegion.bottom - elRegion.bottom;
|
||
|
}
|
||
|
|
||
|
// node is left
|
||
|
if (nodeRegion.left < elRegion.left) {
|
||
|
adjustmentX = nodeRegion.left - elRegion.left;
|
||
|
// node is right
|
||
|
} else if (nodeRegion.right > elRegion.right) {
|
||
|
adjustmentX = nodeRegion.right - elRegion.right;
|
||
|
}
|
||
|
|
||
|
if (adjustmentX || adjustmentY) {
|
||
|
me.scrollBy(adjustmentX, adjustmentY, false);
|
||
|
}
|
||
|
|
||
|
// Poke on a tabIndex to make the node focusable.
|
||
|
Ext.fly(node).set({
|
||
|
tabIndex: -1
|
||
|
});
|
||
|
|
||
|
node.focus();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
bindStore: function (store, initial, propertyName) {
|
||
|
// There could be different data sources (store or dataSource), so figure that out here.
|
||
|
var me = this,
|
||
|
dataSource = me[propertyName],
|
||
|
selModel = me.getSelectionModel();
|
||
|
|
||
|
// Note that configured features with stores will already have been processed by this point,
|
||
|
// so let's not do it again when coming online!
|
||
|
if (dataSource && dataSource.isFeatureStore && me.rendered) {
|
||
|
selModel.bindStore(dataSource.store);
|
||
|
selModel.bindComponent(me);
|
||
|
// Feature stores will call their own implementation of .bindStore().
|
||
|
//
|
||
|
// The passed 'store' function arg will be one of two types depending on the caller.
|
||
|
// 1. regular data store
|
||
|
// 2. grid feature store (data store is bound to it in featureStore.store).
|
||
|
if (store.isFeatureStore) {
|
||
|
// The store listeners need to be bound to the feature store.
|
||
|
me.bindStoreListeners(store);
|
||
|
// Pass in the regular data store.
|
||
|
dataSource.bindStore(dataSource.store);
|
||
|
} else {
|
||
|
dataSource.bindStore(store);
|
||
|
}
|
||
|
} else {
|
||
|
me.callParent([store, initial, propertyName]);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
privates: {
|
||
|
//<feature legacyBrowser>
|
||
|
// Work around for an issue in IE8 where the focus/over/selected borders do not
|
||
|
// get updated where applied using adjacent sibling selectors.
|
||
|
repaintBorder: function(rowIdx) {
|
||
|
var node = this.getNode(rowIdx);
|
||
|
|
||
|
if (node) {
|
||
|
node.className = node.className;
|
||
|
}
|
||
|
}
|
||
|
//</feature>
|
||
|
}
|
||
|
});
|