telegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinboxwhatsappicloudtweetdeckhipchat
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.
880 lines
32 KiB
880 lines
32 KiB
/** |
|
* 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> |
|
} |
|
});
|
|
|