Created
June 30, 2010 06:56
-
-
Save gjuggler/458337 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ext.override(Ext.grid.RowSelectionModel, { | |
initEvents: function() { | |
// Create an event which only fires after a selection is DONE changing in response | |
// to a user interaction (i.e., when we shift-click to select 10 items, this only fires ONCE). | |
this.addEvents('afterselectionchange'); | |
// Make the grid respond to click events. | |
this.grid.on('rowclick', this.handleMouseDown, this); | |
// Even if we're using drag and drop, respond to mouse-down events. | |
// if (!this.grid.enableDragDrop && !this.grid.enableDrag) { | |
this.grid.on('rowmousedown', this.handleMouseDown, this); | |
// } | |
this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), { | |
'up': function(e) { | |
this.keyNavMove(-1, e); | |
}, | |
'down': function(e) { | |
this.keyNavMove(1, e); | |
}, | |
'pageDown': function(e) { | |
var pageDistance = this.grid.getPageSize(); | |
this.keyNavMove(pageDistance, e); | |
}, | |
'pageUp': function(e) { | |
var pageDistance = this.grid.getPageSize(); | |
this.keyNavMove(-pageDistance, e); | |
}, | |
'j': function(e) { | |
this.keyNavMove(1, e); | |
}, | |
'k': function(e) { | |
this.keyNavMove(-1, e); | |
}, | |
'n': function(e) { | |
this.keyNavMove(1, e); | |
}, | |
'p': function(e) { | |
this.keyNavMove(-1, e); | |
}, | |
scope: this | |
}); | |
this.rowNav.keyToHandler['74'] = 'j'; | |
this.rowNav.keyToHandler['75'] = 'k'; | |
this.rowNav.keyToHandler['78'] = 'n'; | |
this.rowNav.keyToHandler['80'] = 'p'; | |
this.grid.getView().on({ | |
scope: this, | |
refresh: this.onRefresh, | |
rowupdated: this.onRowUpdated, | |
rowremoved: this.onRemove | |
}); | |
}, | |
keyNavMove: function(distance, e) { | |
if (!e.shiftKey || this.singleSelect) { | |
this.selectDistance(distance); | |
} else if (this.last !== false && this.lastActive !== false) { | |
var anchor = this.lastActive; | |
var cursor = this.constraintToGrid(this.last + distance); | |
this.selectRange(anchor, cursor); | |
this.grid.getView().focusRow(cursor); | |
this.last = cursor; | |
this.lastActive = anchor; | |
} else { | |
this.selectFirstRow(); | |
} | |
this.fireEvent('afterselectionchange', this); | |
}, | |
constraintToGrid: function(value) { | |
if (value < 0) { | |
value = 0; | |
} | |
if (value >= this.grid.store.getCount()) { | |
value = this.grid.store.getCount() - 1; | |
} | |
return value; | |
}, | |
selectDistance: function(dist, keepExisting) { | |
var cursor = this.constraintToGrid(this.last + dist); | |
this.selectRow(cursor, keepExisting); | |
this.grid.getView().focusRow(this.last); | |
return true; | |
}, | |
hasDistance: function(dist) { | |
return (this.last !== false && (this.last + dist) < this.grid.store.getCount() && (this.last + dist) >= 0); | |
}, | |
looksLikeDuplicateEvents: function(a, b) { | |
if (a !== undefined && b !== undefined && a.type === b.type && | |
a.target === b.target && | |
a.ctrlKey === b.ctrlKey && | |
a.shiftKey === b.shiftKey && | |
a.source === b.source && a.browserEvent === b.browserEvent) { | |
return true; | |
} else { | |
return false; | |
} | |
}, | |
cacheEvent: {}, | |
// private | |
handleMouseDown: function(g, rowIndex, e) { | |
if (e.button !== 0 || this.isLocked()) { | |
return; | |
} | |
// We cache a shallow copy of the most recent event and compare it to the current | |
// event to avoid handling duplicate events. | |
if (this.looksLikeDuplicateEvents(this.cacheEvent, e)) { | |
return; | |
} | |
Ext.apply(this.cacheEvent, e); // Store the cache by applying the event's properties to a hash. | |
var view = this.grid.getView(); | |
var isSelected = this.isSelected(rowIndex); | |
var type = e.type; | |
var ctrl = e.ctrlKey; | |
var shift = e.shiftKey; | |
if (shift) { | |
if (type === 'mousedown' && !this.singleSelect && this.last !== false) { | |
var last = this.last; | |
this.selectRange(last, rowIndex, ctrl); | |
this.last = last; // reset the cursor point. | |
view.focusRow(rowIndex); | |
} | |
} else if (ctrl) { | |
if (type === 'mousedown') { | |
if (isSelected) { | |
this.deselectRow(rowIndex); | |
} else { | |
this.selectRow(rowIndex, true); | |
view.focusRow(rowIndex); | |
} | |
} | |
} else { | |
if (type === 'mousedown' && !isSelected) { | |
this.selectRow(rowIndex, false); | |
view.focusRow(rowIndex); | |
} else { | |
if (isSelected) { | |
this.selectRow(rowIndex, false); | |
} | |
} | |
} | |
this.fireEvent('afterselectionchange', this); | |
}, | |
selectFirstRow: function() { | |
this.selectRow(0); | |
this.fireEvent('afterselectionchange', this); | |
}, | |
selectRow: function(index, keepExisting, preventViewNotify) { | |
if (this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))) { | |
return; | |
} | |
var r = this.grid.store.getAt(index); | |
if (r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false) { | |
if (!keepExisting || this.singleSelect) { | |
this.clearSelections(); | |
} | |
this.selections.add(r); | |
this.last = this.lastActive = index; | |
if (!preventViewNotify) { | |
this.grid.getView().onRowSelect(index); | |
} | |
this.fireEvent('rowselect', this, index, r); | |
this.fireEvent('selectionchange', this); | |
// Adding this here to always focus the view when the next row is selected -- TODO, check if this causes any unforeseen problems. | |
this.grid.getView().focusRow(index); | |
} | |
}, | |
onRefresh: function() { | |
this.suspendEvents(); | |
var ds = this.grid.store, | |
index; | |
var s = this.getSelections(); | |
this.clearSelections(true); | |
for (var i = 0, len = s.length; i < len; i++) { | |
var r = s[i]; | |
if ((index = ds.indexOfId(r.id)) != -1) { | |
this.selectRow(index, true); | |
} | |
} | |
this.resumeEvents(); | |
if (s.length != this.selections.getCount()) { | |
this.fireEvent('selectionchange', this); | |
this.fireEvent('afterselectionchange', this); | |
} | |
}, | |
selectAll: function() { | |
if (this.isLocked()) { | |
return; | |
} | |
this.clearSelections(true); | |
for (var i = 0, len = this.grid.store.getCount(); i < len; i++) { | |
this.selectRow(i, true); | |
} | |
this.fireEvent('afterselectionchange', this); | |
}, | |
clearSelections: function(fast) { | |
if (this.isLocked()) { | |
return; | |
} | |
if (fast !== true) { | |
var ds = this.grid.store; | |
var s = this.selections; | |
s.each(function(r) { | |
this.deselectRow(ds.indexOfId(r.id)); | |
}, | |
this); | |
s.clear(); | |
} else { | |
this.selections.clear(); | |
} | |
this.last = false; | |
// DO NOT fire an 'afterselectionchange' event here! | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment