PDA

View Full Version : Ext.ux.GridKeyNav



RWaters
28 Apr 2009, 11:28 AM
Updated for Ext 3.x, was actually a very minor change. See 2.x version here: http://extjs.com/forum/showthread.php?t=66898



/**
* @class Ext.ux.GridKeyNav
* Simple plugin to implement basic keyboard navigation for Ext 2.x grids that have a
* paging toolbar (required). Adds: Page Down/Page Up/Right Arrow/Left Arrow/Home/End,
* also adds functionality to the selection model to see if Down is pressed at the last record
* of a page or Up is pressed at the first record of the page and attempts to move a page
* in the proper direction.
*/
Ext.ux.GridKeyNav = function() {}
Ext.ux.GridKeyNav.prototype = {
/**
* @cfg {Boolean} bottomBar
* Look for the paging toolbar within the grids bbar, set to true to pull from tbar (defaults to true)
*/
bottomBar: true,
/**
* @cfg {Ext.PagingToolbar} toolbar
* Manually pass in a toolbar instead of pulling from bbar/tbar of the grid (in case it is rendered elsewhere)
*/
toolbar: null,

init: function(grid) {
this.grid = grid;
this.grid.on({
render: this.onRender,
destroy: this.onDestroy,
scope: this
});
},

onRender : function() {
this.nav = new Ext.KeyNav(this.grid.getGridEl(),{
left: this.pagingNav.createDelegate(this,['prev']),
right: this.pagingNav.createDelegate(this,['next']),
pageDown: this.pagingNav.createDelegate(this,['next']),
pageUp: this.pagingNav.createDelegate(this, ['prev']),
home: this.pagingNav.createDelegate(this,['first']),
end: this.pagingNav.createDelegate(this,['last'])
});

this.pt = this.toolbar||((this.bottomBar)?this.grid.getBottomToolbar():this.grid.getTopToolbar());
this.sm = this.grid.getSelectionModel();
this.sm.selectNext = this.sm.selectNext.createInterceptor(this.beforeNext, this);
this.sm.selectPrevious = this.sm.selectPrevious.createInterceptor(this.beforePrevious, this);
},

onDestroy: function() {
this.nav.disable();
delete this.nav;
},

pagingNav: function(page) {
if (!this.pt[page].disabled) {
this.pt.onClick(this.pt[page]);
if (page === 'last') {
this.forceSelectLastRow();
}
} else {
// Is all the data on a single page? If so let home/end work
if (this.pt.pageSize >= this.grid.getStore().data.length) {
if (page == 'first') {
this.sm.selectFirstRow();
} else if (page == 'last') {
this.sm.selectLastRow();
}
}
}
},

beforeNext: function() {
if (!this.sm.hasNext()) {
this.pagingNav('next');
return false;
}
},

beforePrevious: function() {
if (!this.sm.hasPrevious()) {
this.pagingNav('prev');
this.forceSelectLastRow();
return false;
}
},

forceSelectLastRow: function() {
this.grid.getStore().on('load', function() {
this.sm.selectLastRow();
}, this, {single: true});
}
}


Usage:


new Ext.grid.GridPanel({
// store, cm, etc.
bbar: new Ext.PagingToolbar({
// store, pagesize etc
}),
plugins: [new Ext.ux.GridKeyNav()]
});

jay@moduscreate.com
29 Apr 2009, 10:13 AM
Awesome to see this ported over. :)

raphac
26 May 2009, 11:56 AM
forceSelectFirstRow: function() {
this.grid.getStore().on('load',
function() {
this.sm.selectFirstRow();
},
this, {
single: true
});
},

beforeNext: function() {
if (!this.sm.hasNext()) {
this.pagingNav('next');
this.forceSelectFirstRow();
return false;
}
},

pagingNav: function(page) {
if (!this.pt[page].disabled) {
this.pt.onClick(this.pt[page]);
if (page === 'last') {
this.forceSelectLastRow();
} else {
this.forceSelectFirstRow();
}
} else {
// Is all the data on a single page? If so let home/end work
if (this.pt.pageSize >= this.grid.getStore().data.length) {
if (page == 'first') {
this.sm.selectFirstRow();
} else if (page == 'last') {
this.sm.selectLastRow();
}
}
}
},

raphac
6 Aug 2009, 10:29 AM
Version with DelayedTask and enter key




/**
* @class Ext.ux.GridKeyNav
* Simple plugin to implement basic keyboard navigation for Ext 2.x grids that have a
* paging toolbar (required). Adds: Page Down/Page Up/Right Arrow/Left Arrow/Home/End,
* also adds functionality to the selection model to see if Down is pressed at the last record
* of a page or Up is pressed at the first record of the page and attempts to move a page
* in the proper direction.
*/
Ext.ux.grid.KeyNav = function() {}
Ext.ux.grid.KeyNav.prototype = {
/**
* @cfg {Boolean} bottomBar
* Look for the paging toolbar within the grids bbar, set to true to pull from tbar (defaults to true)
*/
bottomBar: true,
/**
* @cfg {Ext.PagingToolbar} toolbar
* Manually pass in a toolbar instead of pulling from bbar/tbar of the grid (in case it is rendered elsewhere)
*/
toolbar: null,
/**
* @cfg {integer} delayPagNav
* DelayedTask
*/
delayPagNav: 500,
init: function(grid) {
this.grid = grid;
this.grid.on({
render: this.onRender,
destroy: this.onDestroy,
scope: this
});
this.beforePagingNav = new Ext.util.DelayedTask(function(page) {
if(page == 'enter')
this.enterNav();
else
this.pagingNav(page);
}, this);
},
onRender: function() {
this.nav = new Ext.KeyNav(this.grid.getGridEl(), {
'left': function(e) { this.beforePagingNav.delay(this.delayPagNav, null, null, ['prev']) },
'right': function(e) { this.beforePagingNav.delay(this.delayPagNav, null, null, ['next']) },
'pageDown': function(e) { this.beforePagingNav.delay(this.delayPagNav, null, null, ['next']) },
'pageUp': function(e) { this.beforePagingNav.delay(this.delayPagNav, null, null, ['prev']) },
'home': function(e) { this.beforePagingNav.delay(this.delayPagNav, null, null, ['first']) },
'end': function(e) { this.beforePagingNav.delay(this.delayPagNav, null, null, ['last']) },
'enter': function(e) { this.beforePagingNav.delay(this.delayPagNav, null, null, ['enter']) },
scope: this
});

this.pt = this.toolbar || ((this.bottomBar) ? this.grid.getBottomToolbar() : this.grid.getTopToolbar());
this.sm = this.grid.getSelectionModel();
this.sm.selectNext = this.sm.selectNext.createInterceptor(this.beforeNext, this);
this.sm.selectPrevious = this.sm.selectPrevious.createInterceptor(this.beforePrevious, this);
},
onDestroy: function() {
if(this.nav) {
this.nav.disable();
delete this.nav;
}
},
enterNav: function() {
if(this.grid.hasListener('rowdblclick')) this.grid.fireEvent('rowdblclick', this.grid);
},
pagingNav: function(page) {
if (!this.pt[page].disabled) {
switch(page) {
case 'next':
this.pt.moveNext(); break;
case 'prev':
this.pt.movePrevious(); break;
case 'first':
this.pt.moveFirst(); break;
case 'last':
this.pt.moveLast(); break;
}
if (page === 'last')
this.forceSelectLastRow();
else
this.forceSelectFirstRow();
} else {
// Is all the data on a single page? If so let home/end work
if (this.pt.pageSize >= this.grid.getStore().data.length) {
if (page == 'first') {
this.sm.selectFirstRow();
} else if (page == 'last') {
this.sm.selectLastRow();
}
}
}
},
beforeNext: function() {
if (!this.sm.hasNext()) {
this.beforePagingNav.delay(this.delayPagNav, null, null, ['next']);
this.forceSelectFirstRow();
return false;
}
},
beforePrevious: function() {
if (!this.sm.hasPrevious()) {
this.beforePagingNav.delay(this.delayPagNav, null, null, ['prev']);
this.forceSelectLastRow();
return false;
}
},
forceSelectFirstRow: function() {
this.grid.getStore().on('load',
function() {
this.sm.selectFirstRow();
this.grid.getView().focusEl.focus();
},
this, {
single: true
});
},
forceSelectLastRow: function() {
this.grid.getStore().on('load',
function() {
this.sm.selectLastRow();
this.grid.getView().focusEl.focus();
},
this, {
single: true
});
}
}

simon1118
10 Aug 2009, 1:59 AM
Great work, nice!