PDA

View Full Version : How to use list paging plugin?



keune
6 Sep 2011, 6:34 AM
I couldn't find any useful document on how to use list paging plugin. The pullrefresh plugin is easy to use, because, it will only load new data. But with list paging plugin, i want to configure my store somehow so that it knows how to load new set of data. But i don't know how to use it.

Has anyone here got this plugin working?

NickT
6 Sep 2011, 3:40 PM
First off, I needed to override ListPagingPlugin. It didnt work properly in terms of supporting next and previous paging. Here is my override. Also, no guarantees on the autoPaging. I did not get that to work satisfactorily, so i went with the manual paging links.


Ext.override(Ext.plugins.ListPagingPlugin, { loadPreviousText: 'Previous Page',
render : function() {
var list = this.list,
targetEl = list.getTargetEl(),
html = '',
phtml = '';


if (!this.autoPaging) {
html += '<div class="x-list-paging-msg">' + this.loadMoreText + '</div>';
phtml += '<div class="x-list-paging-msg">' + this.loadPreviousText + '</div>';
}


this.firstEl = targetEl.insertFirst({
cls: 'x-list-paging' + (this.autoPaging ? ' x-loading' : ''),
html: phtml + Ext.LoadingSpinner
});


this.el = targetEl.createChild({
cls: 'x-list-paging' + (this.autoPaging ? ' x-loading' : ''),
html: html + Ext.LoadingSpinner
});


if (this.autoPaging) {
this.mon(targetEl.getScrollParent(), 'scrollend', this.onScrollEnd, this);
}
else {
this.mon(this.el, 'tap', this.onPagingTap, this);
this.mon(this.firstEl, 'tap', this.onPreviousPagingTap, this);
}


this.rendered = true;
},


onPreviousPagingTap : function(e) {
if (!this.loading) {
this.loading = true;
this.list.store.previousPage();
this.firstEl.addCls('x-loading');
}
},
onListUpdate : function() {
if(!this.list.store){
return false;
}
if (!this.rendered) {
this.render();
}
if(!this.autoPaging){
var storeReader = this.list.store.proxy.reader;
var totalRecords = storeReader.jsonData[storeReader.totalProperty];
if (totalRecords <= (this.list.store.currentPage * this.list.store.pageSize)) {
}
else{
this.el.appendTo(this.list.getTargetEl());
this.el.removeCls('x-loading');
}
if(this.list.store.currentPage == 1){
}
else{
this.list.getTargetEl().insertFirst(this.firstEl);
this.firstEl.removeCls('x-loading');
}
}


this.loading = false;
},


onScrollEnd : function(scroller, pos) {
if (pos.y >= Math.abs(scroller.offsetBoundary.top)) {
this.loading = true;
this.list.store.nextPage();
}
else if(pos.y == 0){
this.loading = true;
this.list.store.previousPage();
}
}
});

I also extended the Select field, because it renders as a Picker on the mobile device, yet, I needed paging regardless of the device, so i needed a way to force the Select control to render as a List. Here is my extended class


Ext.namespace('Ext.ux.form');

Ext.ux.form.Select = Ext.extend(Ext.form.Select, {
listConfig: {},
pickerConfig:{},
forceList: false,
showComponent: function() {
if (Ext.is.Phone && !this.forceList) {
this.getPicker().show();
}
else {
var listPanel = this.getListPanel(),
index = this.store.findExact(this.valueField, this.value);


listPanel.showBy(this.el, 'fade', false);
listPanel.down('#list').getSelectionModel().select(index != -1 ? index: 0, false, true);
}
},
// @private
getPicker: function() {
if (!this.picker) {
this.picker = new Ext.Picker(Ext.apply({
slots: [{
align : 'center',
name : this.name,
valueField : this.valueField,
displayField: this.displayField,
value : this.getValue(),
store : this.store
}],
listeners: {
change: this.onPickerChange,
scope: this
}
},this.pickerConfig));
}


return this.picker;
},


// @private
getListPanel: function() {
if (!this.listPanel) {
var config = {
floating : true,
stopMaskTapEvent : false,
hideOnMaskTap : true,
cls : 'x-select-overlay',
scroll : 'vertical',
items: {
xtype: 'list',
store: this.store,
itemId: 'list',
scroll: false,
itemTpl : [
'<span class="x-list-label">{' + this.displayField + '}</span>',
'<span class="x-list-selected"></span>'
],
listeners: {
select : this.onListSelect,
scope : this
}
}
};
if(this.listConfig){
config.items = Ext.apply(config.items,this.listConfig);
}
this.listPanel = new Ext.Panel(config);
}


return this.listPanel;
}
});


Ext.reg('selectfield', Ext.ux.form.Select);


//<deprecated since=0.99>
//DEPRECATED - remove this in 1.0. See RC1 Release Notes for details
Ext.reg('select', Ext.ux.form.Select);
//</deprecated>

Here is my selectfield using the ListPagingPlugin for a List... Notice that i set forceList to true so that it always renders as a List regardless of device, and i am able to provide a listConfig which is applied to config used to create the List control. That is where the plugin is defined...


{ xtype: 'selectfield',
name:'accountlist',
label: 'Account',
forceList: true,
listConfig:{
plugins: [new Ext.plugins.ListPagingPlugin({loadPreviousText: 'Load Previous...', loadMoreText:'Load More...'})]
},
displayField : "businessEntity",
valueField : "accountID",
width: (Ext.is.Desktop ? 500 : '100%'),
store: vm.accounts
}

on the server side, you will have page, limit (and sort if you specified that in your store definition) available. You will want to obtain a total record count along with the page of data... here's a node.js get that is reasonably understandable that will give you a rough idea of what you have to work with and how you want to structure the response...


app.get('/readaccounts', function(req, res) { getRowcount(environ.dataModel.accounts, res, function(err, totalCount){
var totalRecords = totalCount[0]['count()'];
var page,limit,sort;
var pIndex = req.url.indexOf('?');
if(pIndex > -1){
var params = req.url.substring(pIndex+1);
var paramObj = querystring.parse(params);
page = paramObj.page;
limit = paramObj.limit;
sort = JSON.parse(paramObj.sort);
}
var query = buildSelectStatement(environ.dataModel.accounts, null, null, limit, limit*(page-1), sort);
executeSelect(query, res, function(err, accounts) {
if (err) {
responseWrite(res, {message: err}, true);
return;
}
var results = accounts || [];
res.writeHead(200, {'content-type': 'text/plain'});
res.write(JSON.stringify({totalRecords: totalRecords, data: results}));
res.end();
});
});
});

my store is routine. define pageSize and sorters as desired. Define your model with the field set, idProperty, etc...


this.accounts = new Ext.data.Store({ storeId: 'accountStore',
model: 'accounts',
pageSize: 10,
sorters:[
{
property:'businessEntity',
direction:'ASC'
}
],
autoLoad: false
});