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.

Monday, March 21, 2011

The Social Protocol


What are social networks? They're websites people from around the globe use to communicate with one another. What is a website? They're a bunch of related resources linked together, and requested by web browsers. How are resources requested and returned? The browser sends an HTTP request to the website, and displays the result. This is how the overabundance of social networks work in their most basic sense – like websites do. Users around the globe, social network or otherwise, are connected via HTTP. I wonder, is HTTP an inherently social protocol, or does it appear that way because of the social phenomenon on the web? There are some interesting properties of the protocol that give it the appearance of being inherently social.

Just in case you don't think social networks are pervasive in the web space, try visiting any major site. You probably can't find many that don't have social network buttons embedded in the interface. The idea with these widgets isn't to build more incoming links. No, the idea is to be social about the subject matter. To talk about it. To rant and rave about it for that matter. Being social is about spawning new ideas through collaboration. Whether the majority of the discussions that take place over social networks add anything of value is subjective but nevertheless, powerful. We have networks of opinions we can traverse and mull over if we're so inclined. We even have tools that will search the these opinions, assessments, and wild theories, extracting the stuff we want. Think about the way a search engine works on the web - the same idea, only the data set we're querying is created by social networking tools. The data is linked together the same way the rest of web is, discussions about sirloin steak are probably linked to discussions about seasoning salt. Likewise on the rest of the web, only its pages that are linked, not discussions.

The world is a big place. The advent of the web made it an order of magnitude smaller. The web was designed for connectedness, hence the name. Collaboration, asking questions, getting answers, expressing opinions. What exactly is sent over the wire? We don't want to send raw text to our collaborators. We need content to be readable. We need to identify headings, and images. We need to emphasize certain points of interest in our content. A web browser parses a markup language and presents formatted information to the receiving user. This is the ML in HTML. Hyper-text is text with links to other URLs. The user supplies the link, and they're taken to the new location on the web. Addressability, a formatting language, a web browser that does all the underlying work. What else do we need to communicate over the web in a meaningful way?

Fast-forwarding a little, back to where social networks are the driving force of the web. How did the social phenomenon start? We used to have websites for sought-after information. Good luck finding an answer to your question should a web page dedicated to the topic not already exist. Of course, forums solved this problem originally, but there was something missing. Something that needed a personal opinion couldn't be done here. However, for general topics, forums are a great way to share knowledge. Opinions are expressed, knowledge conveyed, and not only is my question answered, but the thread lives on and helps thousands of people in the same situation I was in two months ago. Social networks took the concept of forums, groups, threaded-discussions and changed two things. First, you're no longer having a threaded-discussion with people you don't know. You're talking about stuff with friends, colleagues, people you've allowed access. This is your social circle, and your supposed to value their opinion over that of anonymous entities on the rest of the web. Second, the idea of a discussion being centered around a topic as been largely diminished in social networks. Essentially, in social networks, the user is the topic. Everything else is centered around the what they decide is relevant.

Back to the pre-social network web, HTML pages, web browsers, and the glue holding it all together – HTTP. The hyper-text transfer protocol is how we get from one page to another, load the page initially, and interact with the servers that store these pages. More importantly, HTTP gives the web a unified interface for these interactions. Browsers send HTTP requests to a location, a URL. An HTTP request has a method that tells the server what to do with the resource when it receives the request. For instance, if I want to retrieve an HTML page from a given URL, I send a GET HTTP request to that URL. GET means retrieve the HTML page and send it back to my browser. Say I'm on a site the lets me review cars. I sill out a review form and submit it. When I do this, I'm posting a new resource. For this I use the POST method. These two methods are the most common. When you're browsing the web, you might visit 50 to 100 pages. All of these requests are GET requests.

There are other, less-common HTTP methods as well - PUT, and DELETE. These methods also modify resources. If I want to delete a web page, I send a DELETE request to the page URL. If I want to update an existing resource, say change the text, I send a PUT request. Together, these four methods represent the unified behavior interface of the web. These are the actions of the web, create (POST), read (GET), update (PUT), and delete (DELETE). 
 
The social networks of today use HTTP because they're websites. HTTP has a unified interface, a small set of methods that tell the server what you want to do with the resource. Social networks generalized the concept of discussion topic and externalized their tools that allow readers of the web to point social network users to that web resource. Just like the TCP/IP protocol is general, you use it to send or receive data over the Internet, websites are general, you visit them seeking information or to perform whatever task you need. Just like HTTP provides a way for browsers to work with resource representations, social networks provide a way for users to connect with one another, regardless of the topic.

URLs are essential for sharing things on the web. Users point their browsers to URLs. In return, they get whatever the person on the other end is sharing. Generating new web resources, HTML pages and URLs is very easy today. Not just creating new resources, but managing their entire life cycle is trivial for most people. Social network or no social network, web applications make it easy to post new content, modify it, or get rid of it entirely. This is the social aspect of HTTP - the unified interface of GET, POST, PUT, and DELETE. Sometimes, you're required to supply specific parameters in your post to create a new recipe. You might need to specify a sorting column when retrieving a list of hockey teams. The question is, how do we get these parameters and how do we know which method to use?

Most resources on the web are simple. That is, they're meant to be read. This is why the default method used by a browser when pasting a URL is GET. The web is just like the real world in that you need to read before you write. This means you head to a website and see what it does, who owns it, does it interest you, is it safe, etc. Only afterward do we decide that we want to provide our own insights, thoughts, images, video, status, etc. These are objects we post onto the web using a URL endpoint. We update these objects later on by altering their attributes and putting them back. When they become irrelevant, we delete them. Or they're deleted for us. The work-flow, read about the service, post something, update it, is all derived from the end user content. The content dictates which which direction to take, which HTTP method to use.

To get a better idea of how HTTP is the ideal protocol for social work-flows, we need to think about RESTful web applications. That is, hypermedia as the engine of application state. Resources on the web don't have any state in the web browser. This means that what you're viewing right now is only a copy, a representation of the resource. The real one is on the server. Your web browser, being the application, needs direction on how to proceed, which URL to visit next, which method to use. Links do a good job of this. All the user needs to do is think "I want to go here" and click the link pointing to the new location. The browser says "GET me resource xyz". Now I can read the content and make a decision, what I want to do next. In this sense the user is the application. Imagine a different kind of web browser, one that doesn't care about presenting content to the user, one that only cares about making decisions a human would otherwise make. This kind of browser would maintain application state by continuously reading directions sent back from resources on the server and making the next move. There are, however, two things that this browser would struggle with.

The first, how does the browser know what it's options are? How does it know what it's next potential moves are, the URLs and expected methods. It would have to do what a human does, read the content in order to decide what to do next. So our new browser will need a representation it understands, XML for example. Inside the XML, we have content, probably related to the application domain our browser was built for. We also have link fields embedded in these server resource representations. These links aren't like regular links, they also have the HTTP method we're supposed to use. The browser then knows what method to use, it knows whether it is posting a new object or retrieving something that exists already.

The second problem, how does the browser know what the expected parameters are for any given resource? If a list of account transactions supports a page size, how does the browser know about it? The answer in HTML browsers is that the page designer implements a page size selector. The human operating the browser makes the decision by choosing an appropriate size. Our new browser has no luxery of human thought, only resource representations, URLs, and HTTP methods. They can only help guide our application if they provide the full extent of what can be done, how else can our application make an informed decision? It can't very well create new objects without knowing what fields are required. 
 
One option for these issues is an HTML form. Forms can store both the URL and the method required for any resource. Additionally, the input fields within make it easy for our browser to learn what the acceptable parameters for any given resource are. It doesn't need to make guesses by attempting to parse natural language, it simply reads the language it understands and acts accordingly.

The HTTP protocol itself isn't so much social as are the representations that HTTP clients interact with. If you visit someone's profile on a social networking site, that is a representation of what that person is doing, thinking, attending, reading, whatever. Based on what the visitor sees here, they make their decision on what to do next. Social networks make it so easy to hop around inside, jump from profile to profile, event to event. This is because they link to one another. Hypermedia. The engine of application state. If you update your profile, you're probably not sending a PUT request. If you delete a photo, you're probably not sending a DELETE request. This doesn't really matter because the ideas that make social networks social came from the web, refined and put in a confined container. HTTP is the interface that makes the web social.