Tuesday, March 29, 2011

jQuery UI Zero Feature Grid


The jQuery UI toolkit has really matured since earlier releases, adding new widgets and improving old ones. Soon, a new grid will join the widget repertoire. The grid is currently scheduled for the jQuery UI 2.1 release. But this is software, so I'd be reluctant to hold them to that date. Also, there is still a lot to do before a full-featured grid is ready – lets call this the many-feature grid. This type of widget requires other components be built first. Stuff like an underlying data model to store data, an in-line editor for changing grid cell values, and data types for performing validation. Another useful grid feature is sorting by column – yet another component required the many-feature version. The jQuery UI team has planned a precursor to the many-feature version - the zero-feature grid. This is a development starting point, a gateway for the grid widget to enter the real world. What can we do with a zero-feature grid widget? A jQuery UI grid is simply a table with visual embellishments. Is it of any practical value in production user interfaces?

So why do we need a grid widget in the first place when we have HTML tables? To answer this, we need a better understanding of what tables are and how they're supposed to be used. The best way to transform a table element into a functional grid is through a Javascript widget. If we're displaying grids in our user interface, we'll need to control it somehow. We can use the jQuery UI widget API to encapsulate the grid methods and options. What are these options and how do they relate to HTML tables?

HTML tables are a great way to display tabular data. Tabular data is just another way of saying “a table” - rows and columns. Columns describe what each row has. It also means that each row describes the same thing. You don't have one row with a “cost” column and another row without one. Each row in the same table are consistent. The value of the “cost” column might be missing, but the row still acknowledges it's existence. It “knows” about the column. HTML tables aren't all that different from database tables. One is stored on the file system while the other is displayed in the web browser. HTML tables are a nice way to display database tables. All the web application needs is to know about the columns in the table. It uses this information to generate the HTML table headers. Likewise for generating the table rows. When a query is executed, the application iterates over the results, generating the HTML table rows. This is one of the most common patterns in web development. HTML tables are the presentation layer for database tables.

Databases store our application data, but that doesn't mean we need a one-to-one representation of that data in our user interface, does it? For example, my application stores it's users in a table called, not surprisingly, users. My application's administrative user interface allows me to view all users and perform typical administrative tasks on them. This page runs a query against this database table and generates corresponding HTML table. The resulting table allows me to see a list of my application's users, along with some of their details - some of the columns of the user database table. So this isn't exactly a one-to-one mapping of each user row, its a truncated version. This page performs a query that only selects some of the key attributes of user entities that are of value to an administrator. I can now browse and view user attributes I'm interested in at a glance. This is a really powerful feature of viewing tabular data in user interfaces. I can focus my attention on a single column, moving down the list, looking for something interesting. If I want to view a more accurate representation of a user object I can visit the details page – a page displaying the full set of user attributes.

HTML tables offer an eye into an application's data. They're usually sourced from database tables, but this isn't imperative. The data could just as well be generated by computing input values from sources other than database tables. The data might come from a CSV file. It doesn't really matter where the data comes from, tables are easy for us to look at and browse. Fancier user interfaces in web applications, ones that know how to utilize CSS and Javascript, leave tables in their traditional form something to be desired. Its easy to make HTML tables look good in our user interfaces. The only real trouble we get into with implementing HTML tables is when we're using them as a page layout tool. Page layout isn't tabular data and is better achieved with a tableless structure. HTML tables don't have user interface design issues - interacting with them is difficult.

Sitting there, staring at a table doesn't really cut it. You'll constantly need to change the way the table data is presented to you. By this I mean adding constraints to your submitted query – things like ordering and grouping. The user interface controls we use to do this are typically outside of the table . Close by, but not part of it. You have a input boxes, check boxes, radio buttons – things that refine what is displayed in our table. The problem is, they aren't actually part of the table. This is challenging to deal with when implementing a widget much less providing a good user experience. 

Say the user wants to sort the table columns. The most efficient way of doing this, for their point of view, is by clicking the column. This displays a sorting direction arrow beside the column name. This is exceedingly intuitive for the user. Conversely, say you have a selector that says which column you want to sort by. You'd also need a selector that specifies the sorting direction. But this just doesn't feel right. Actually clicking on the column to sort it feels like you're interacting with the data, not obliging the application's limitations.

Another way to interact with an HTML table is re-sizing it. We might decide that we don't like the default size of the table and want a larger view of it. We might want to re-size the column headings too. Unlike the sorting by column feature where we actually click the column header to execute the query again with the new filter, resizing doesn't necessitate changing the data. This is purely presentational, an enhancement relies only on Javascript. The available interaction utilities in jQuery UI can handle stuff like this.

Lets jump back to the jQuery UI grid again. What are the future goals of this grid? Or, better yet, what exactly is a grid and how does it compare to a table? A grid is a table with lots of features fastened to it. Grids are more akin to spreadsheets. A grid isn't just a presentational layer for the real data housed in a remote database. No, a grid is the real deal – a mini database if you will. If I want to sort my grid data by a column name, the grid has built-in capabilities to do this. The grid has an underlying data model that does this for me. The model loads the raw data using an asynchronous HTTP request, or Ajax request. Sorting by column, clicking the grid column headers, doesn't execute a new query request. It just sorts what it already has. This gives the user a nice, prompt response. What else does the grid do? It is a widget, and so it provides an API for updating the data model, which subsequently updates the user interface. When working with a many-feature grid, it needs to ensure the integrity of the data model. This means that a float column cannot accept the string “foo”. Validation is a must-have.

So we now have this localized mini database in our web browser. How does this reflect the real data that lives on the remote database? I've made some changes to the grid. My user interface processed a few events that resulted in new rows being inserted and a few rows being updated. Now how do we let the real data know about these changes? The grid widget should automatically do it for us. We give the grid a data URL, used for the initial load. We also tell it about an endpoint to perform updates or insertions. This way the grid listens for any changes in the data model and pushes them out to the server.

These are the long-term goals of the many-feature jQuery UI grid widget. We've thought about basic HTML tables. About how they're formatted on-the-fly and they don't meet the interactive expectations of users. There is no underlying data model. There is no state monitoring. There is no automatic data synchronization with the remote database. You get what you pay for and HTML tables are cheap. With many-feature grids, you get a lot - and they're expensive. However, I think, with more features comes more problems. The zero-feature jQuery UI grid aims to solve some of the interactivity problems we mentioned earlier while remaining lightweight and easy to use.

The zero-feature term chosen for the first iteration of the grid widget is good, but it does in fact have a couple features. All jQuery UI widgets extend the basic HTML elements to which they're applied, even if only making them theme-ready. For example, the zero-feature grid is a theme-ready version of an HTML table. This is valuable because we can use the powerful theme framework with the table element. We could do this before, but we'd have to forcefully impose the theme classes on the table element. Now we simple make a widget out of it, which might add an element here and there inside the table. The ability to change the table dimensions, to re-size it is also a job for a jQuery UI widget. I'm not sure if the first iteration of the jQuery UI grid will have the ability to re-size the table headers and the table as a whole. It is a huge bonus if it does because these features are invaluable for reading tabular data. Especially re-sizing the columns.

So just how valuable is a zero-feature grid? If it offers some flexibility with regard to themes and allows for re-sizing, very valuable. Sure, it doesn't have all the bells and whistles of a many-feature grid, but it has to start somewhere. If you're using standard HTML tables in the standard way – running queries and mapping the resulting rows to HTML table markup, its trivial to make these tables into zero-feature widgets that add a lot of useful features. Maybe you're already doing something like a zero-feature grid using the jQuery UI widget framework. I would suggest trying out the zero-feature grid as soon as it becomes available. If you need to do custom asynchronous requests under the covers, try it out. You might find this simpler to use than the many-feature grid when it hits the shelves. In the end, you whatever leads to simpler user interface code.