Форк Rambox
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

/**
* 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>
}
});