PDA

View Full Version : Grid numeric pager



warstar
8 Aug 2007, 11:43 PM
Hi everyone,

You all know the toolbar pager for the grid i asume. Well it's good but on great for what i needed so with a bit of copy pasting and (a very small part of) brains i created the following numeric pager. I'm sure it can be made better but i don't have the time or know how about ExtJs. Hope some one finds this usefull.

Good luck to everyone

/*
* NumberPagingToolbar (Extends Toolbar)
*
* Created on: 28 jun 2007
* Created by: Warnar Boekkooi
*/
Ext.NumberPagingToolbar=function(el,ds,config){
Ext.NumberPagingToolbar.superclass.constructor.call(this, el, null, config);
this.ds = ds;
this.pageIndex = 0;
this.renderNumbers(this.el);
this.bind(ds);
}
Ext.extend(Ext.NumberPagingToolbar, Ext.Toolbar, {
/**
* @cfg {Number} pageSize
* The number of records to display per page (defaults to 20)
*/
pageSize: 20,
/**
* @cfg {Number} maxLinks
* max. number of links to show on one page (default: 5)
*/
maxLinks: 5,
/**
* @cfg {Boolean} showFirst
* Show go to first page link (default: false)
*/
showFirst: false,
/**
* @cfg {String} firstText
* Text for go to first page (defaults to "First Page")
*/
firstText: "<<<",
/**
* @cfg {Boolean} showLast
* Show go to last page link (default: false)
*/
showLast: false,
/**
* @cfg {String} lastText
* Text for go to last page (defaults to "First Page")
*/
lastText : ">>>",

renderNumbers: function(el) {
Ext.NumberPagingToolbar.superclass.render.call(this, el);
this.field = Ext.get(this.addDom({
tag: "div",
cls: "x-grid-page-numbers"
}).el);
},
setMaxLinks: function(amount) {
amount = Number(amount);
if(!isNaN(amount)) {
this.maxLinks = amount;
}
},
//build the pager
onLoad : function(ds, r, o){
var dh = Ext.DomHelper;

//clear number items
this.field.dom.innerHTML = "";

// get the currentPage and the total numberOfPages
var d = this.getPageData();
var currentPage= d.activePage;
var numberOfPages=d.pages;

// hide numbers if there is only 1 page
if(numberOfPages == 1) {
return;
}

// how mutch links maybe on the left and how mutch on the right
var amount_l = 0;
var amount_r = 0
if (this.maxLinks % 2 == 0) {
amount_l = (this.maxLinks / 2 ) - 1;
amount_r = this.maxLinks / 2;
} else {
amount_l = amount_r = (this.maxLinks - 1) / 2;
}

//how validate the left and right amounts
if(numberOfPages <= this.maxLinks) { // do we need to slide?
amount_l = 0;
amount_r = numberOfPages-1;
} else if(currentPage == 0) { //is this the first page?
amount_l = 0;
amount_r = this.maxLinks-1;
} else {
var dif = 0;
if(0 > (currentPage - amount_l)) { //to far left?
amount_l = currentPage+(amount_l-currentPage);
amount_r = this.maxLinks-amount_l;
}
if((numberOfPages-1) < (currentPage + amount_r)) { //to far right?
amount_r = (numberOfPages-1) - currentPage;
amount_l = this.maxLinks-amount_r-1;
}
}

// now create the links
if(this.showFirst) {
if(currentPage != 0) {
var el = dh.append(this.field,
{
tag:'div',
cls: "x-grid-page-first",
children:[
{tag:'a' ,href:'javascript:void(0);',html:this.firstText, cls:'x-grid-page-first-link'}
]
},
true);
el.on("click",this.onClick.createDelegate(this, ["first"]));
} else {
var el = dh.append(this.field,
{
tag: 'div',
html: this.firstText,
cls: "x-grid-page-first"
},
true);
}
}
for (i = (currentPage - amount_l); i <= (currentPage + amount_r); i++) {
//number page
var el = dh.append(this.field,
{
tag:'div',
cls: "x-grid-page-number",
children:[
{tag:'a' ,href:'javascript:void(0);',html:i+1, cls:'x-grid-page-link'}
]
},
true);
if(i == currentPage){
el.addClass("x-grid-page-number-current");
}
el.on("click",this.onClick.createDelegate(this, [i]));
}
if(this.showLast) {
if(currentPage != (numberOfPages-1)) {
var el = dh.append(this.field,
{
tag:'div',
cls: "x-grid-page-last",
children:[
{tag:'a' ,href:'javascript:void(0);',html:this.lastText, cls:'x-grid-page-last-link'}
]
},
true);
el.on("click",this.onClick.createDelegate(this, ["last"]));
} else {
var el = dh.append(this.field,
{
tag: 'div',
html: this.lastText,
cls: "x-grid-page-last"
},
true);
}
}
},
//called on the page number click
onClick:function(which){
pageNum = Number(which);
if(!isNaN(pageNum)) {
var ds = this.ds;
this.pageIndex = pageNum;
ds.load({params:{start: (this.pageIndex)*this.pageSize, limit: this.pageSize}});
return;
}
switch(which){
case "first":
this.pageIndex = 0;
this.ds.load({params:{start: 0, limit: this.pageSize}});
break;
case "last":
this.pageIndex = this.getPageData().pages-1;
this.ds.load({params:{start: (this.pageIndex)*this.pageSize, limit: this.pageSize}});
break;
}
},
// private
getPageData : function(){
var total = this.ds.getTotalCount();
return {
total : total,
activePage : this.pageIndex,
pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
};
},
/**
* Unbinds the paging toolbar from the specified {@link Ext.data.Store}
* @param {Ext.data.Store} store The data store to unbind
*/
unbind : function(ds){
ds.un("load", this.onLoad, this);
this.ds = undefined;
},

/**
* Binds the paging toolbar to the specified {@link Ext.data.Store}
* @param {Ext.data.Store} store The data store to bind
*/
bind : function(ds){
ds.on("load", this.onLoad, this);
this.ds = ds;
}
});

violinista
9 Aug 2007, 11:59 PM
Could you post some screenshots? Thanks.

warstar
10 Aug 2007, 2:01 AM
Hope this helps (sorry i don't use the standard ext styles)

galdaka
10 Aug 2007, 3:07 AM
Live example for test?

Thanks in advance,

violinista
10 Aug 2007, 3:17 AM
One small suggestion: try to put "first page" and "last page" links, along with "next page" and "previous page".Somewhat example:


<< < 2 3 4 5 6 > >>

rodiniz
10 Aug 2007, 3:20 AM
Very similar to my sample...
http://www.rodrigodiniz.qsh.eu/YahooGrid.aspx

warstar
10 Aug 2007, 3:32 AM
galdaka: Sorry no live example yet I will create one the weekend

violinista: Sounds good i will also do that in combo with the example.

rodiniz: uhh where is that pager??

galdaka
10 Aug 2007, 3:38 AM
@rodiniz: Your example not works in IE6. See Image.

@warstar: Try to put a more configurable options (like text for first & last & next & previous labels) in your component for make robust.

Animal
10 Aug 2007, 3:50 AM
Why not just extend what's already there?



Ext.namespace("Ext.ux");

Ext.ux.NumericPagingToolbar = function() {
Ext.ux.NumericPagingToolbar.superclass.constructor.apply(this, arguments);
}

Ext.extend(Ext.ux.NumericPagingToolbar, Ext.PagingToolbar, {
renderButtons : function(el){
Ext.PagingToolbar.prototype.renderButtons.apply(this, arguments);
this.preceding = [];
for (var i = 0; i < 3; i++) {
this.preceding[i] = this.insertButton(i + 4, {
handler: this.onPageNumberClick,
scope: this
});
this.preceding[i].el.setVisibilityMode(Ext.Element.DISPLAY);
this.preceding[i].el.child(".x-btn-text").setStyle({
"font-weight":"bold",
"color":"#083772"
});
}
this.following = [];
for (var i = 0; i < 3; i++) {
this.following[i] = this.insertButton(i + 8, {
handler: this.onPageNumberClick,
scope: this
});
this.following[i].el.setVisibilityMode(Ext.Element.DISPLAY);
this.following[i].el.child(".x-btn-text").setStyle({
"font-weight":"bold",
"color":"#083772"
});
}
},

onPageNumberClick: function(b, e) {
var pageNum = parseInt(b.el.child(".x-btn-text").dom.innerHTML, 10);
var d = this.getPageData();
if (!isNaN(pageNum) && (pageNum > 0) && (pageNum <= d.pages)) {
this.field.dom.value = pageNum;
pageNum--;
this.ds.load({params:{start: pageNum * this.pageSize, limit: this.pageSize}});
}
},

updateInfo : function(){
Ext.PagingToolbar.prototype.updateInfo.apply(this, arguments);
var d = this.getPageData();
var p = d.activePage - 3;
for (var i = 0; i < 3; i++, p++) {
if (p < 1) {
this.preceding[i].el.hide();
} else {
this.preceding[i].el.show();
this.preceding[i].el.child(".x-btn-text").dom.innerHTML = p;
}
}
p = d.activePage + 1;
for (var i = 0; i < 3; i++, p++) {
if (p > d.pages) {
this.following[i].el.hide();
} else {
this.following[i].el.show();
this.following[i].el.child(".x-btn-text").dom.innerHTML = p;
}
}
}
});

rodiniz
10 Aug 2007, 4:25 AM
galdaka: Sorry no live example yet I will create one the weekend

violinista: Sounds good i will also do that in combo with the example.

rodiniz: uhh where is that pager??

the pager was not visible cause there wasn't enough data ... but that is fixed now.

rodiniz
10 Aug 2007, 4:46 AM
@rodiniz: Your example not works in IE6. See Image.

@warstar: Try to put a more configurable options (like text for first & last & next & previous labels) in your component for make robust.
Thanks for reporting...I am fixing the sample now... It will not work for now.

warstar
10 Aug 2007, 4:51 AM
Uhh because i'm new to Ext i think. But i will also take a look at that this weekend

rodiniz
10 Aug 2007, 5:23 AM
The sample in my website is fixed.
@animal... I will certainly look into your code.
In my defense ..my NumberPagingToolbar was born before the PagingToolbar.
Off-course my code now is re factored to extend the PagingToolbar, but not like yours.

ravikumarg17
15 Oct 2008, 1:51 AM
The sample in my website is fixed.
@animal... I will certainly look into your code.
In my defense ..my NumberPagingToolbar was born before the PagingToolbar.
Off-course my code now is re factored to extend the PagingToolbar, but not like yours.

I am new to Ext JS, and trying to extend PagingToolbar to have page number links. For e.g. if the user is on page 10 then I would show him 3 prev page number links and 3 next page number links (number of links will be configurable).
Any help in this regard will be highly appreciated.