fighting the spill

Posted by:

More than a year ago I was digging deep in the sources of the Java-like GNU Classpath, trying to find a way to adopt the MVC Pattern they are using. Despite all the hassle with translating and substituting objects, methods and functionality (have you ever taken a look at the event queue?) to the world of userland Javascript, it worked quite well and the results were nice, but slow. Really slow. And since the runtime of the script always depents on the hardware-power the client provides, an overloaded source like this leads to frustration – not to usability (this is why my development environment is still underpowered by a 1,5 mhz computer).

One thing I always had in mind was to write a MVC powered Table widget, kind of a live data grid which provides the following functionality:

  • Fixed horizontal table header
  • Resizable columns
  • several row- & column-selection modes
  • lazy load of data

Points 1, 2 and 3 where quickly implemented and are already running smooth under Firefox 2 and IE 7 (I’ve never been a friend of backward compatibility when it comes to CSS and Javascript).

Number 4 was then again a tough nut to crack. Ignoring the basics OF loading the data – this will be done using a simple XMLHttpRequest – it was even more harder to write an algorithm providing:

  • synchronized behaviour of the position of the vertical scrollbar slider to the actual row shown on top of the table (i.e. the first row)
  • refilling the the table buffer quick enough so the user does not have to wait too long for incoming data
  • a smart computing of skipped rows, actual rows and rows to prebuffer when the user scrolls really fast through the table

Here’s what I came up with…

First of, I have splitted the widget into three classes: Control, Model and View. The control gives you – as the name already tells, the control over the table and lets you initialize it correctly and manipulate the table during the runtime of the script. most of the method calls herein delegate to the view, which will heavily communicate with the model. Questions by the view asked are, for example: I have to show rows 40-63, give me the data for that, I have to show a row, was that highlighted? etc. pp. yadayada…

The view itself computes the row-indices which are about to be shown in the viewport and holds a page-buffer and the page-size, which is the number of rows that can be displayed in the viewport (let’s say, for a viewport-height of 180px I can show 7 rows at once).

Basically, the page-size is also the average size of the buffered data: If the initial data-load is 14 table-rows, we can divide that by 2 and get the page-size: If you scroll 7 rows down, 7 rows are left and the next 7 rows get loaded and appended to the table, whereas the rows at top get removed – they are being re-used for the buffer, so you don’t have to call a document.createElement() each time the buffer runs empty.

I was also thinking of good old pagination with web applications created before buzzy AJAX hit the market. I had to find a way to compute the actual page and save the old-page number for referencing scrolling behaviour of the user. Thus, if page is > old-page, the user scrolls down, and else the user scrolls upwards. You might think of just storing the scrollTop-argument and compare this with the previously set value, but getting the page and comparing this to the previously viewed set of rows (i.e. the old page) is neccessary when it comes to skipped rows and computing the following spill of skipped rows.

I will soon upload a working example as soon as I have built in the XMLHttpRequest to connect to a database for real lazy loading, by now I’m just satisfied that a lot of brainstorming has finally come to an end and the algorithm works for now.

And if someone tells you a lot of programming should be done on the paper – trust him, he’s right… see attachment below.

testing some algorithms on paper


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.

Add a Comment