Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    gwt-ext type of pagination

    Is there anybody working on the gwt-ext type of ListGrid with server side pagination (lazy loading)?
    Because I have tried out the scrolling pagination with RestDataSource, it doesn't work for me because of some strange behaviors I met.
    1. When I scroll to the bottom of ListGrid and submit my SearchForm criteria, the ListGrid call twice to my server, 1st to get the last page records, 2nd to get the first page records no matter how big I set for my PageSize.
    2. When the ListGrid already loaded records 1-15, I removed record 10 and 11, then I scroll down to second page of the ListGrid to fetch the rest of the records 16-30, ListGrid only show records 16-28, because my totalRecord currently is 28 instead of 30, when I scroll to the top, the records 10 and 11 are still there.

    I think that never happened when I used gwt-ext on my previous project.
    Anyway, my system requirement is very simple, in order not to overload our server, we keep the page size small for the user, mostly 15 records per page. But somehow, I think ListGrid (e.g. live grid sample), is very difficult to behave in such a small PageSize.

    Currently, I am trying to come out my own gwt-ext alike Grid lazy loading pagination based on the gridPager sample found in this Forum. The gridPager if I am not mistaken is a client based pagination, which we need to retrieve all the records at first load. The PagedGrid I am trying to develop is seems like not as straight forward as I think, because I need to take care not just the pagination alone, the sorting and searchForm or any other parameter criteria also need to be taken care of.

    So, I am hoping maybe someone out there are working on this, and can give me a guideline or two, to let me know whether I am heading a right direction. Or simply there is a better and easier way to achieve my system requirement.

    Thank you.
    Last edited by yapning; 29 Apr 2009, 19:26.

    #2
    You had bugs in your RestDataSource server implementation. The first problem sounds like an off-by-one with startRow and endRow (be sure to read the docs very closely to understand what these indices mean), the second sounds like incorrect return values for removal (you need to return the primary keys of the removed record). No need to abandon RestDataSource, just fix your server code.

    Comment


      #3
      Thanks for replying. Actually I posted the 1st problem to this forum before without any solution at the end. Anyway, following is the flow which I just tested:

      1. first load, ListGrid send _startRow=[0],_endRow=[15] : so I return 16 records from 0-15 with <startRow> 0, <endRow> 15 and <totalRows> 36.
      2. when I scroll down pass record no. 16, ListGrid send _startRow=[16],_endRow=[31] : so I return 16 records from 16-31 with <startRow> 16, <endRow> 31 and <totalRows> 36.
      3. when I scroll down pass record no. 32, ListGrid send _startRow=[32],_endRow=[47] : so I return last 4 records from 32-35 with <startRow> 32, <endRow> 35 and <totalRows> 36.
      4. I click on my searchForm search button, to call fetchData on listGrid, ListGrid send _startRow=[23],_endRow=[38] : so I return 13 records from 23-35 with <startRow> 23, <endRow> 35 and <totalRows> 36.
      5. Then ListGrid continue to send _startRow=[0],_endRow=[15] : so I return 16 records from 0-15 with <startRow> 0, <endRow> 15 and <totalRows> 36.

      Step 4 and 5 is abit funny, the ListGrid not suppose to send the unecessary _startRow=[23],_endRow=[38], because at the end of the search, only the top few records from (0-15) is visible.

      I am not sure whether you can simulate that or not. I am using SmartClient_70beta_LGPL.

      According to the document, I believe the startRow and endRow are zero-based index and totalRows are starting from 1. Is my understanding of startRow and endRow and totalRows incorrect?

      Code:
      isc.SearchForm.create({
      	ID:"searchForm",
      	position:"relative",
      	width:"40%",
      	colWidths:["*","*"],
      	numCols:5,
      	titleAlign:"left",
      	fields: [
      		{name:"searchName", title:"Name"},
      		{type:"spacer", width:50},
      		{name:"searchCountryCode", title:"Country" />",
      			type: "comboBox",
      			valueField: "code",
      			displayField: "name",
      			optionDataSource:"countryList"},
      		{type:"toolbar", align:"center", width:450, colSpan:5, buttons: [
      			{title:"Search", click:"form.doFetch()", extraSpace:15},
      			{title:"Reset", click:"form.reset()", extraSpace:15},
      			{title:"Add New Record", click:"form.reset()"}
      		]}
      	],
      	doFetch: function()
      	{
      		if (typeof myGrid.data.invalidateCache == 'function') 
      			myGrid.data.invalidateCache();
      		myGrid.fetchData(searchForm.getValuesAsCriteria());
      	}
      });
      Code:
      isc.RestDataSource.create({
      	ID:"myList",
      	dataFormat:"xml",
      	fetchDataURL:"http://localhost:8080/myprj/myList",
      	fields:[
      		{name:"name"},
      		{name:"address1"},
      		{name:"address2"},
      		{name:"address3"},
      		{name:"postcode"}
      	]
      });
      Code:
      isc.ListGrid.create({
      	ID:"myGrid",
      	position:"relative",
      	width:"98%",
      	height:400,
      	alternateRecordStyles:true,
      	autoFetchData:true,
      	dataPageSize:15,
      	drawAllMaxCells:0,
      	drawAheadRatio:1,
      	scrollRedrawDelay:20,
      	sortFieldNum:0,
      	dataSource:"myList"
      });
      Anyway, the second problem is the remove record on server side problem.
      I don't quite understand by "the second sounds like incorrect return values for removal (you need to return the primary keys of the removed record)".
      Do I need to let the ListGrid know all the records on the ListGrid first page that had been removed in the server when scrolling down the second page to fetch data? I don't think that is logical if I am not mistaken. Or I understand your reply wrongly.
      Last edited by yapning; 6 May 2009, 03:54.

      Comment


        #4
        For case 2, if you are seeing the records being visually removed then cache sync is working. What you may not understand is that this is assumed to renumber all rows, eg, if 10 and 11 are removed, what was previously row 14 is now row 12. Likewise for new records.

        For case 1, you mention that you changed the search criteria, but the total results seem to be exactly the same - is this correct?

        As far as scrolling position, do you want the scrolling position to jump to the top on re-filter, or try to keep the same position if the dataset is long enough.

        Finally, did you know there's a complete example of doing link-based paging posted here?

        Comment


          #5
          Originally posted by Isomorphic
          For case 2, if you are seeing the records being visually removed then cache sync is working. What you may not understand is that this is assumed to renumber all rows, eg, if 10 and 11 are removed, what was previously row 14 is now row 12. Likewise for new records.
          Sorry, I don't understand how does ListGrid knows row 10 and 11 had been removed in the first place? Because it may be removed at the server side or removed by other user in other part of the world which the ListGrid may not be aware of.

          For case 1, you mention that you changed the search criteria, but the total results seem to be exactly the same - is this correct?
          Yes, let say that's the case. Some how the search criteria changed, but the records return are exactly the same as previous, that's one of the possibility.

          As far as scrolling position, do you want the scrolling position to jump to the top on re-filter, or try to keep the same position if the dataset is long enough.
          Jump to top, because the records returned may be a lot less after searching.

          Finally, did you know there's a complete example of doing link-based paging posted here?
          Yes, I had already digged through the forum and google twice or more. Because I don't have much time on hand, sometime I just briefly look through the topic. The gridPager is the sample that I refer to when building my own gwt-ext like pagination for ListGrid (2 buttons at the left one goto text field two buttons on the right). The gridPager as I mentioned before, it will need the server to return all records at first load if I am not mistaken, which is not ideal, and the presentation of the pagination is not as user friendly as the gwt-ext pagination IMHO.

          Actually, my gridPager is almost half way done, I got the basic look and feel and layout of the buttons, textfield and label done, just the logic part to handle not just the pagination part, also together with the integration of the Sorting and SearchForm. However, it getting more and more complicated considering I just started my SmartClient experience 2 to 3 weeks back. Anyway, I finally decided to start this topic before I go further, seeing that I have not much time also to complete my gwt-ext type of gridPager.

          Comment


            #6
            Sorry, I don't understand how does ListGrid knows row 10 and 11 had been removed in the first place? Because it may be removed at the server side or removed by other user in other part of the world which the ListGrid may not be aware of.
            If you are talking about records removed via the ListGrid, this renumbers rows as previously described.

            If you are talking about externally removed records (eg other users), yes you can miss records. This is also the case with interfaces like GWT-Ext's (paging via links or back/forward buttons). To mitigate this when it's very important, you can either:
            1. drop all cached records every time new records are fetched, via setting invalidateCache on every DSResponse
            2. use SmartClient's Messaging module to deliver real-time updates

            If you prefer to scroll to the top on every criteria change, you can use scrollBodyTo() to do this immediately before changing criteria.

            No, the provided GridPager example does not require all data to be loaded up front. I guess you didn't try it before starting on your own? That might have saved time :)

            Note also this post summarizes the (severe) disadvantages of link-based paging relative to "live grid"-style paging.

            Comment


              #7
              Originally posted by Isomorphic
              1. drop all cached records every time new records are fetched, via setting invalidateCache on every DSResponse
              I tried to do this for hours without any success with the help from Reference and Forum. Do you have any sample codes?

              If you prefer to scroll to the top on every criteria change, you can use scrollBodyTo() to do this immediately before changing criteria.
              Yes, this had finally solved my first problem. Currently there is only one server request instead of two. Thanks.

              No, the provided GridPager example does not require all data to be loaded up front. I guess you didn't try it before starting on your own? That might have saved time :)
              Yes, I can confirm that, GridPager doesn't need to load all data up front. Previously, I tested with DataSource instead of RestDataSource because I was rushing through the test. Is my mistake, sorry about that.

              Note also this post summarizes the (severe) disadvantages of link-based paging relative to "live grid"-style paging.
              Yes, I read that before, apparently, the disadvantages of using link-based will not be so obvious if it is just a simple List of records. It will be nice if the link-based pagination is built into SmartClient itself so at least we have the option whenever the Customers requirement insist of having it in their system. Anyway, as I mentioned before, GridPager presentation of the pagination is not as user friendly as the gwt-ext pagination, that's why I am trying to make something to hopefully improve it.

              Comment


                #8
                Looks like nobody is replying my first question. Probably sample codes is too much, I was just hoping for some more hints. Thanks.

                I tried to do this for hours without any success with the help from Reference and Forum. Do you have any sample codes?
                Anyway, I found maybe a typo error in ListGrid.js - this.booeanFalseImage line 7593. I am using SmartClient_70beta_LGPL. Is there anyplace I need to report this?

                Comment


                  #9
                  Finally, managed to come out a simple gwt-ext like pagination, hope for some feedback or improvement from anybody out there. Anyway, I am not so good in JavaScripting, so please excuse my primitive JS codes.

                  I am using SmartClient_70beta_LGPL with Enterprise skin. I took out the css .toolStrip border and created 4 more gray images under skin actions folder: first_Disabled.png, prev_Disabled.png, next_Disabled.png, last_Disabled.png.

                  One problem is, when you do sorting on the Grid, it does not go to first page.

                  Another, you need to take care, for example if you go to the 4th page, if the server records only remain 3 pages of records after removed by somebody, then the server should return the last page (3rd page) records with the correct startRow, endRow and totalRows. I am using RestDataSource kind of concept so the _startRow, _endRow, _totalRows and _sortBy parameters are passed to the server same as RestDataSource.

                  It took me quite some time to do this PagedGrid and it is not fully tested, so for those who want to use it, you may use it without any warranty.

                  Anyway, is it legal for me to immitate gwt-ext pagination? If not what can I do?

                  Actually I am still not giving up on the original RestDataSource implementation, what have stop me from using it right now is just the only issue I faced which I still not sure how to solve it:
                  Originally posted by Isomorphic
                  1. drop all cached records every time new records are fetched, via setting invalidateCache on every DSResponse
                  Attached Files

                  Comment

                  Working...
                  X