Initial implementations of lists in a web application are generally very simple. As the list grows in size, more functionality is required. Here is an attempt at compiling the major functional requirements of a list. You may not use many of these functions, but it is useful to know what is possible.
There should be an easy way for users to search all fields of the entire list. The simplest implementation would be a single textbox with a Search button. Users may then want to search on specific fields. A straightforward method is to present separate input fields for each searchable field. This however limits the user to searching each field for one particular value. You may have to present additional fields for specifying ranges or conditional operators (like greater than or equal to).
For more complex conditions, it may be helpful to present a query language like a simplified version of SQL. Or better still, provide a query builder, where the user can create a complex query and execute it. This is more preferable as it reduces the learning curve from beginner to intermediate. The query builder should also provide for searching dynamic values such as “today”, “current time”, etc. and aggregate functions such as “total sales is greater than x”.
Users may wish to save their queries for a later time. It should be easy to give them a meaningful name, description and even allow for tagging. Sometimes, the user may want to save the results of the query (a snapshot in time) instead of the query itself. Saving a data set may only be possible if the list size is small. Otherwise it should allow the users to export the information out to a document in Word, PDF, Excel or other formats.
Paging is more a practical than usability concern. Users may wish to have all records displayed to them, but doing so would be time-prohibitive and involve unnecessary data processing, when the user is interested in just a few records. Paging is generally implemented by links to different pages, though nowadays, it is common to see the “infinite” page where vertically scrolling down displays more records fetched dynamically that weren’t there initially. Live Image Search and Google Reader (see below) have good implementations of the latter design.
If the list is organized alphabetically or chronologically, being able to access a specific page is a more useful feature than displaying an infinite page. The reverse is true if the list organizes the results by relevance or randomly. For example, you might guess that the middle page of a contact list may contain names starting with “K” or “M”, but retrieving the 100th page of Yahoo! search result page is meaningless. For the former case, provide links or “jump-to-page” functionality at the top and bottom of the list.
Users would also find it useful to control the number of results per page. A global setting is usually appropriate, though it is more helpful to provide a setting in each list screen and remember the last selected value. For the default page size, choose a value that returns a reasonable-sized amount of data without the user having to navigate or scroll too much. Somewhere between 10 and 25 seems like a good guess, but you can make a more educated decision by observing your users and finding out how much they click to a different page or scroll for each page.
Displaying the number of results across all pages can be useful. But performance concerns may prevent you from giving an accurate value. In such cases, you can do what Gmail does, give an estimate:
The most common implementation of sorting results is doubling the header column as a sort column. You click on a header column; the data sorts by that field. You click again; it sorts in the reverse order. Display the sort direction as an icon or arrow in the column. The limitation is that you can generally only sort the data by one column. Also, the sorting is not linked to the search functionality, so each time the user issues a search, he or she has to sort the search results again.
A better implementation would be to allow the user to specify multiple sorting criteria, so that the user can say, sort the contacts by city and then by last name within each city. This can be part of the search section and so each saved search can have its own sort. You can still retain the column heading sort, but it would be overridden by the search sort condition when the search executes. But after the results are displayed, clicking on the columns would override the search sorting, thus avoiding the need for users to change the search sort condition for a temporary sorting need.
There are client-side implementations of sorting data, but they should be avoided because generally the client does not receive all the data because of paging. Sorting the single page of results provides incorrect results from the right method of first sorting the entire data and displaying the first page. Another mistake commonly seen in client-side sorting is that numeric values or dates are sorted as if they were strings.
If the user has not sorted the data, it should default to the most meaningful sort. For example, contacts should be sorted alphabetically. Bills should be sorted by the one pending for the longest time.
Layout and Information
Should you have lines for separating the columns? What should be the font size of the columns? Should you display alternating rows in different colors? There are so many different choices that you can make for presenting the list information. Let me point you to Matt Berseth for some examples (and code!). Of course, tables do not have to be your first choice, either. You could present the data in a visual manner, such as graphs or maps. In such visual displays, paging and sorting are less of a concern, but searching (or filtering) remains important.
While designing the layout, you should be concerned about noise. The user is generally interested in only a few records and perhaps only a few columns. Searching solves the first problem. Providing the ability to show and hide columns helps with the second. I think it is better to allow selection of necessary columns when providing search criteria, and then allow a separate override when the search results are displayed.
Summary headers or footers are useful. While the conventional method is to have a summary row, on the web, providing the summary information in the header can avoid scrolling. You can even create a summary that provides information other than an aggregate function of a particular column. Of course, it goes without saying that the summary information must be emphasized using a greater font size or color.
Users want to do more with their lists. People like list management because it reminds them of a spreadsheet program like Microsoft Excel, which makes it very easy to add and change data. Though a web application has other better features, users want it all. A common need is to apply an action across multiple items in the list, such as Delete or Mark as Read. We see this uniformly implemented using a checkbox column. Users can choose the required items and select an action. While this works effectively, it limits the user to working with the current page of results.
Many implementations also have a master checkbox (in the header column) that selects or unselects all the checkboxes in the list. However, Gmail differs by offering text links for selecting “All”, “None”, “Starred”, etc. Hotmail has, perhaps, the worst implementation of the checkbox column. First, the checkbox is hidden behind an envelope icon. Second, if you miss the checkbox when clicking, it opens the message, making you lose all the previous checkbox selections you made.
With the increase in Ajax-enabled applications, users are demanding more from the list screen, such as the ability to add and edit records right in the grid. This works well when the number of fields in a particular record is relatively few. When a record has more fields, the user is forced to scroll horizontally. Some fields may require more advanced controls making the page code-heavy and unwieldy.
A final piece of the puzzle is security. Some records must be hidden or disabled for some actions for different groups of users. A simple case would be each user owning the records that they have created and others unable to view them, unless the user decides to make them public or share them with select friends. This is a common situation with most social networks.
Advanced security may require an authorization module that allows the system to define user roles and access rights. Building this or re-using an existing framework may take a life of its own especially if security is very fine-grained, because the authorization module is linked to every part of the application. Keeping it simpler can mean easier development.
Security is a large and complex domain. This is one area that you will have to pay increasing attention to as your application gains more users. Managing the authorization framework, managing the needs of the end users and continuing to build your application can be quite demanding. So plan well for it.