1. #1
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    98
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default [2.x] Ext.ux.data.PagingStore [v0.4]

    [2.x] Ext.ux.data.PagingStore [v0.4]


    Ext 2.2 natively only supports remote paging (the server needs to process the start and limit parameters).

    For local paging you can use the PagingMemoryProxy user extension, but it has some disadvantages:
    1. You have to write extra code to remote load the data for the proxy.
    2. query, filter and collect only work on the current page. You have to write extra code to use the PagingMemoryProxy filter support.
    3. Local sorting works, but you need to set remoteSort:true. There is no remote sorting support.
    4. Added and removed records are only remembered for the current page.
    5. Changing the page is relatively slow (PagingMemoryProxy reprocesses all data).

    All these problems can be solved by adding paging support to Store instead of MemoryProxy.

    Ext.ux.data.PagingStore is a drop-in replacement for Ext.data.Store. Local paging should work directly after replacing Store with PagingStore (there are also SimplePagingStore and JsonPagingStore replacements for SimpleStore and JsonStore).

    Example of a remote store:
    Code:
    var store = new Ext.ux.data.PagingSimpleStore({
        fields: [...],
        url: 'data.php',
        autoLoad: {params: {start: 0, limit: 10}}
    });
    Example of a local store:
    Code:
    var store = new Ext.ux.data.PagingSimpleStore({
        fields: [...],
        data: data,
        lastOptions: {params: {start: 0, limit: 10}}
    });
    Just one note:
    If you load a PagingStore it will ONLY request new data if any of the parameters (except start and limit) were changed from the previous load (otherwise it will just show a different page of the same data).
    If you want to force a load you need to delete the lastParams property before loading the store.

    Example: To make the refresh button of the paging toolbar do a forced reload you would need:
    Code:
    Ext.override(Ext.PagingToolbar, {
    	onClick : function(which){
    		var store = this.store;
    		switch(which){
    			case "first":
    				this.doLoad(0);
    			break;
    			case "prev":
    				this.doLoad(Math.max(0, this.cursor-this.pageSize));
    			break;
    			case "next":
    				this.doLoad(this.cursor+this.pageSize);
    			break;
    			case "last":
    				var total = store.getTotalCount();
    				var extra = total % this.pageSize;
    				var lastStart = extra ? (total - extra) : total-this.pageSize;
    				this.doLoad(lastStart);
    			break;
    			case "refresh":
    				delete store.lastParams;
    				this.doLoad(this.cursor);
    			break;
    		}
    	}
    });
    I put the PagingStore code together in just a few minutes and I haven't tested if thoroughly. I would appreciate any feedback.

    Note: I didn't create a PagingGroupingStore, because I don't think paging and grouping should be used together, but for those who want one, here is the code:
    Code:
    Ext.ux.data.PagingGroupingStore = Ext.extend(Ext.ux.data.PagingStore, {
    	remoteGroup: Ext.data.GroupingStore.prototype.remoteGroup,
    	groupOnSort: Ext.data.GroupingStore.prototype.groupOnSort,
    	clearGrouping: Ext.data.GroupingStore.prototype.clearGrouping,
    	groupBy: Ext.data.GroupingStore.prototype.groupBy,
    	applySort: Ext.data.GroupingStore.prototype.applySort,
    	applyGrouping: Ext.data.GroupingStore.prototype.applyGrouping,
    	getGroupState: Ext.data.GroupingStore.prototype.getGroupState
    });
    Update:
    v0.1: Initial version
    v0.2: Add support for local data
    v0.3: Fixed bug in SimplePagingStore and in getTotalCount (fixes PagingToolbar pagecount).
    v0.4: Fixed another bug in local paging

    The Ext 3.0 version can be found here.
    Attached Files
    Last edited by Condor; 25 Nov 2009 at 1:46 AM. Reason: v0.4

  2. #2
    Sencha User
    Join Date
    Apr 2008
    Location
    West Linton, Scotland
    Posts
    244
    Vote Rating
    0
    andycramb is on a distinguished road

      0  

    Default


    If i understand this correctly I could use this for paging on data that has its source locally
    For example I have an app that pulls in JSON from a javascript includes

    Snapshot of the data - see below
    Your extension should allow me to page through the data?

    I did try it but I could not get the paging working
    I got the grid to display the store fine and there were no errors
    The paging bar showed page 1 of 1 with the navigation icons greyed out
    Below is the copy of the store and grid code
    Should I be able to get this working for my set up?
    Thanks

    store:
    Code:
    	myApp.myStore = new Ext.ux.data.JsonPagingStore({
    		data: myApp.mydData,
    		baseParams: {params:{start: 0,limit: 5}},
    		root: 'rows',
    		id: 'id',
    	//	totalRecords : 5,
    		successProperty: 'success',
    		fields:[	
    			//{name:'id',type:'float'}
    			{name:'dueDate',type:'date',format:'d/m/y'}
    			,{name:'creationDate',type:'date',format:'d/m/y'}
    			,{name:'period'}//.....
    grid
    Code:
    //...
    		,listeners: {
    			render: function(g){
    				g.getSelectionModel().selectRow(0);
    			}
    			,delay: 500 // Allow rows to be rendered.
    		}
            ,bbar:new Ext.PagingToolbar({
                    store: myApp.myStore,
                    pageSize: 6,
                    displayInfo: true,
                    displayMsg: 'Displaying categories {0} - {1} of {2}',
                    emptyMsg: "No categories to display"
            })
    data
    Code:
    var myData = {
    			"records": 8,
    			"success": true,
    			rows:[{
    				"id": "1",
    				"dueDate": "Mon Jan 12 2009",
    				"creationDate": "Mon March 05 2010",
    				"period": "Q4 2008",
    				"type": "Sales",
    				"description": "Support the Vision tendering process",
    				"customer": "Callum Lindsay",
    				"performer": "Andy Cramb",
    				"community": "Vision",
    				"state": "Acknowledgment",
    				"lastAct": "Assert Complete",
    				"scope": "private",
    				"openClose": "open",
    				"comments": [{
    					"commentId": "1",
    					"person": "Andy Cramb",
    					"act": "New Promise",
    					"date": "16/12/2008 09:21",
    					"comment": "I aim to support the Vision tendering process"
    					},{//......

  3. #3
    Sencha User
    Join Date
    Apr 2008
    Location
    West Linton, Scotland
    Posts
    244
    Vote Rating
    0
    andycramb is on a distinguished road

      0  

    Default


    I uploaded it to http://cramb.org.uk/extjs/paging/main.html so that you can see what I am trying to describe

  4. #4
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    98
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    I originally planned PagingStore for remote data (with a proxy) and it didn't work for local data.

    I modified the code (v0.2) and your example should work now.

    ps. I would use lastOptions instead of baseParams (start and limit are dynamic, so they shouldn't be stored in baseParams).

  5. #5
    Sencha User
    Join Date
    Apr 2008
    Location
    West Linton, Scotland
    Posts
    244
    Vote Rating
    0
    andycramb is on a distinguished road

      0  

    Default


    Thanks I will give it a go when I get back from work tonight
    I guess I misunderstood how paging works out of the box with ExtJS
    For a normal paging toolbar this goes off to the server to get each set of paged records and informs the server of this be incrementing the params
    With your extension and the PagingMemoryProxy extension it still collects the data from the server but does it get the complete recordset in one go and what your extension does and the PagingMemoryProxy extension does is to then mange that store/daatset locally?
    Therefore there is no further calls to the server.

  6. #6
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    98
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    Correct, both PagingStore and PagingMemoryProxy load the entire dataset and return only the current page.

  7. #7
    Sencha User
    Join Date
    Apr 2008
    Location
    West Linton, Scotland
    Posts
    244
    Vote Rating
    0
    andycramb is on a distinguished road

      0  

    Default


    Thanks
    Added lastOptions instead of baseParams
    Could not getting paging to work onLoad
    When I clicked the refresh button it worked to a degree but the first page had 6 records when I had this specified

    Code:
    lastOptions: {params:{start: 0,limit: 4}},
    I uploaded the latest version to http://www.cramb.org.uk/extjs/paging/main.html

  8. #8
    Sencha User
    Join Date
    Mar 2007
    Posts
    580
    Vote Rating
    0
    dolittle is an unknown quantity at this point

      0  

    Default


    If I understand correctly, your extension loads the complete data and then pages through it locally. It is great and I have a feature request. What if we want to enjoy both worlds?

    Let's say you have 1,000 items on the server and it's expensive to load them all.
    You can load 100 items each time but have the page size set to 10 so the user gets much better user experience. When the user gets to page 10, the extension will automatically load the next 100 items from the server.

    It could be even better if there is a config option to load the next 100 items from the server when the current local page is:
    PHP Code:
    currentPage maxLocalPage tolerance 
    So if tolerance = 3, the proxy will load the next 100 items when the user gets to page 7 and the experience will be completely fluent.

    What do you think?

  9. #9
    Ext User
    Join Date
    Jul 2007
    Location
    Florida
    Posts
    9,996
    Vote Rating
    6
    mjlecomte will become famous soon enough mjlecomte will become famous soon enough

      0  

    Default


    What's the difference between that and livegrid extension then?

  10. #10
    Ext User tonedeaf's Avatar
    Join Date
    Dec 2007
    Posts
    137
    Vote Rating
    1
    tonedeaf is on a distinguished road

      0  

    Default


    Quote Originally Posted by mjlecomte View Post
    What's the difference between that and livegrid extension then?
    These come immediately to mind:
    • Separate Commercial License for livegrid (for commercial development)
    • Grid grouping features available for Condor's extension
    • A *LOT* less code and faster performance
    • Paging interface instead of scrolling (preferred in many circumstances)

    Really, I would choose it anyday over livegrid extension. Another vote for integrating features suggested by dolittle.