Blog

LiveGrid component with ExtJS

Posted by:

I’m thrilled to announce a Sneak Preview of my LiveGrid component based on ExtJS 2.0 RC 1. After I was pretty sure that There is no spill! and I have been Fighting the spill, I refactored my algorithms to work with the ExtJS library.

When I’m speaking of the term “LiveGrid”, I simply refer to a (grid) view representing a large server side backed database. Instead of paging, the view buffers a specific number of records from the database. When scrolling, the position of the “cursor” changes and a request for new data will be send to the server, delivering an updated buffer with the data the new cursor position indicates.

For making this “view” possible, I have overwritten a few classes from the ExtJS-source:

[Skip reading and go to the example]

Ext.ux.data.BufferedJsonReader

BufferedJsonReader derives from Ext.data.JsonReader and allows to pass a version value representing the current state of the underlying data repository.
The version property is handled server side and should change whenever a record gets added or deleted in the data repository. The store will then be notified and fires the versionchange event if the current version differs from the version-value from a previous request.

Ext.ux.grid.BufferedStore

BufferedStore derives from Ext.data.Store and introduces a new config option called bufferSize. The bufferSize property represents the maximum number of data which will be available in the store. Let’s say, your database table you’re reading from has a total number of 5000 records, and bufferSize equals to 300, then the store will have 300 records from this table available for reading. The larger your table, the larger this property should be. The value of bufferSize will be sent to the server as the limit parameter.

Ext.ux.grid.BufferedGridView

Here is where the magic happens: BufferedGridView, deriving from Ext.grid.GridView. It is responsible for requesting buffer data and calculating the range of records to fetch from the underlying data repository upon scrolling. It introduces several new events such as beforebuffer, buffer and cursormove. You will also have to pass a config parameter called nearLimit upon creating an instance of BufferedGridView: The value will help the view in calculating a predictive buffer offset: While scrolling down, the view has to decide which records the user wants to read next. If they are not within the current range of buffered data, the view will notify the store to request new data from the server. The start parameter send with the request will determine the position of the data the user requested.

Ext.ux.BufferedGridToolbar

A toolbar you can add to the GridPanel you are using. Similiar to the Ext.PagingToolbar, this component will keep you up to date about the loading state and the current position of your cursor you are moving through the data. It also gives you a reload button to refresh the view with the newest data.

Ext.ux.grid.BufferedRowSelectionModel

One of the toughest nut to crack was the decision on how to make selections possible in the scope of possible available data and not current available data. The usual row selection model will allways have records available for storing them in the selections set. What if this records are not available, but where requested to mark as selected by the user?

The extended implementation stores selections based upon their assumed position in the data model. Let’s say you have a table with a number of 5000 records, and you allow to select multiple rows at once in the view (using shift & ctrl key). One of the many possible scenarios is teh following: The user loads the view, clicks the first row while holding down shift, then scrolls down and adds the very last row to the selection. What happens here ist that the store will not request every single record that may come into the view while scrolling, so most likely there may have been only two request for data been made: The initial load and a second one to update the buffer when the user reaches the very end of the table. With a bufferSize set to 300, that would be 4400 records which where not loaded, but requested to add to the selection. Those selections will be stored in a property called pendingSelections, represented by their positions in the data model. Using the method getPendingSelections the selection model computes the ranges of records that where marked as selected, but not available in the store during this operation. It’s up to the user to work with this indexes – he can set up a ajax request to fetch this data from the table. But how does the user know this selection is still valid? It may become invalid when rows have been added or deleted in the table, leading to data disintegrity when the user requests those pending selections and deletes the records associated with them. Well, he doesn’t. But the version property and the versionchange event (as mentioned in the BufferedStore introduction) can help him in deciding if he wants to keep the selections or if he wants to clear the selections-set before any operation with this data will be made. Additionally, the BufferedRowSelectionModel introduces a new event selectiondirty that gets fired whenever the selection model can predict that the selected ranges may have become invalid.

That ‘s it for now. I’m giving you an example of a Grid using the above components. I’m still working on it, so the first downloadable release is scheduled for the next week. I will also have a documentation until then.

Enjoy, and leave your comments, suggestions and bug reports here or in the forum thread over at the ExtJS forums.

22


About the Author

Thorsten is the author of the conjoon open source project and the Ext.ux.Livegrid component. In this blog he writes more or less frequently about his current projects and web development in general.

Discussion

  1. Fangzx  November 11, 2007

    LiveGrid is great! Thank you for sharing the code.
    http://www.siteartwork.de/livegrid — can’t visit!

    (reply)
  2. Marc  November 16, 2007

    Dear Mr. Suckow-Homberg, thanks for sharing your amazing code. We are building an ext based web application and are currently searching for motivated & skilled JavaScript developers. It would be a plasure to have you onboard. Please contact me, if you are interessted.

    (reply)
  3. Edouard  January 25, 2008

    Since I use it, I just love this live grid !!

    I wanted to upgrade my ExtJS framework to the new 2.0.1 version. But now, if I use the key board arrows to scroll up or down in the grid, it generates a bug…

    I came back to the 2.0 version, hoping and waiting that you’ll discover where this bug comes from and be able to correct it.

    Thanks again for this nice work.

    (reply)
  4. Ricardo Stuven  February 28, 2008

    @Edouard: I had the same bug using arrow keys to scroll when I upgraded to 2.0.1. This is my fix:

    BufferedGridView.patch:

    @@ -1074,6 +1074,8 @@
    return;
    }

    + var c = this.scroller.dom;
    +
    if(hscroll !== false){
    var cleft = parseInt(cellEl.offsetLeft, 10);
    var cright = cleft + cellEl.offsetWidth;
    @@ -1086,7 +1088,7 @@
    c.scrollLeft = cright-c.clientWidth;
    }
    }
    - return cellEl || rowEl;
    + return cellEl ? Ext.fly(cellEl).getXY() : [c.scrollLeft, Ext.fly(rowEl).getY()];
    },

    (reply)
  5. Edouard  March 10, 2008

    Hi Thorsten,

    I am using your LiveGrid extension and I appreciate it very much. But I can’t make it work with the latest Ext’s relases (2.0.1 and 2.0.2) and this is very annoying… Have you updated your code since or will you do it ?

    Thanks a lot for your nice job.

    (reply)
  6. Alexis  March 16, 2008

    Hallo Thorsten,

    eine wunderbare User Extention für ExtJS. Vielen Dank. Auch ich habe mit dem letzten Download von ExtJS (2.0.2) Probleme. Im IE und RowClick kommt eine “böse” JS Fehlermeldung. Freue mich, wenn Du ein Update machen kannst, denn EXTJS braucht dringend ein performantes Livegrid :-) . Ãœbrigens: Kann ich Dich im OS Projekt Livegrid irgendwie unterstützen?

    Besten Gruss,
    Alexis

    (reply)
  7. Edouard  March 19, 2008

    Thanks Ricardo. I didn’t see your answer but in the meanwhile I have made the same modifications and it works. Now I am waiting that Thorsten releases the bug fixes he promised on ExtJS forum… :-)

    (reply)
  8. admin  March 19, 2008

    Fixed in the new version. Thx for your feedback so far, guys.

    (reply)
  9. David Clyant  May 19, 2008

    Excellent bit of kit.

    However, we’ve just upgraded to the newest release of ExtJS (2.1) and the column headers in the Grid are no longer selectable nor sortable. I’ve noticed that there have been some column sort issues with 2.1 grids in general. Are these also affecting the LiveGrid? If so, do you have any ideas when you’ll be able to fix them?

    Apart from this one bug, the Live Grid has been flawless. Excellent work. :o )

    (reply)
  10. Than  June 13, 2008

    This livegrid plugin for ExtJS is awesome. However, it conflicts with another plugin, the column locking. The problem occurs when using the BufferedGridView, it overrides the column locking functionality. Please let me know if it is possible to keep locking and live data source at the same time. Thanks in advanced.

    (reply)
  11. Gary  June 17, 2008

    superb!

    Just need support for Page Up/Down buttons and that is one cool and complete widget!

    (reply)
  12. Claudio  June 22, 2008

    Excellent code!
    It’s possible use it with GroupingStore feature ?
    Thank you, bye

    (reply)
  13. Vishnu  September 16, 2008

    Phenomenal – nice job. I have been looking for this for a while. Stay tuned – I might be able to contribute to you a GWT-EXT wrapper.

    (reply)
  14. Oscar  October 27, 2008

    Can you please make this use the EditGrid (for in-place editing), write some documentation showing simple server-side code and client-side code and publish prices for people who want to use this on a commercial basis?

    (reply)
  15. Jeff  October 31, 2008

    Any chance of the source code button working on the gwt-ext-ux demo page for the Live Grid?

    (reply)
  16. Thorsten  October 31, 2008

    Hi Jeff,

    unfortunately I cannot be of help regarding this subject, since I’m not involved into the gwt-ext-project and someone else did obviously port/maintain the port.

    (reply)
  17. Vishnu  January 6, 2009

    Hi:

    Just encountered a small problem – bufferedRowSelectionModel is not compatible with the checkboxRowSelectionModel. I want to use a checkbox in the first column. Is this possible?

    Also, I have the GWTEXT wrapper almost done.

    (reply)
  18. Mono  January 7, 2009

    I like this example and try to use extjs-gwt in eclipse project. This is my first article about extjs-gwt:gxt
    http://extjs-gwt.blogspot.com
    See more about Extjs-gwt on eclipse.
    I think this extjs-gwt article can help beginner to learn.

    (reply)
  19. Doug Fulford  March 27, 2009

    This looks great! Does it work with flat files? We have a logger which logs an overwhelming number of messages to a file. We read them as they are being written and put them into a Store for an extJs GridPanel. Needless to say, the grid gets fat pretty quicky and activity screeches to a halt. We need a grid because we want to be able to filter (like excel).

    (reply)
  20. Bjoern  November 12, 2009

    Great work, we are going to licence the commercial version when Grouping is possible. I tried some forum hacks to achieve grouping, but it does not work reliable yet. Keep on coding :)

    (reply)
  21. BaÄŸlama Büyüsü  June 1, 2010

    Great work, we are going to licence the commercial version when Grouping is possible. I tried some forum hacks to achieve grouping, but it does not work reliable yet. Keep on coding :)

    (reply)

Add a Comment


Refresh