ng-dataList (working title) wish list
This post is primarily a set of notes to myself on what I would like to see in a new “data list” angular component. It’s here on my blog for easy sharing.
Background
At NewOrbit we build a range of web-based applications for our clients and partners. Mostly they have a lot of data in them and, inevitably, a significant portion of the user interface revolves around listing and interacting with data.
We have used a number of approaches to listing data over the years including jqGrid and ng-grid, both of which have a lot of very useful features and we have been happy to use them. The main issue really is around responsive design and mobile devices. I have some thoughts on a slightly different approach that may be feasible. The end-goal for us would be to either contribute to an existing OSS project for Angularjs or build a new project. Truth be told, ng-grid has most of the building blocks we need and the ideal would be to work with that team to enhance ng-grid, if it fits with that team’s vision.
All the most recent work I have done has been with ng-grid so I will focus on comparing and contrasting with ng-grid in this post. I think ng-grid has some really clever core features, including some nice functionality around limiting how many entries are actually created in the DOM (or so I believe).
Responsive design
There is a good discussion on responsive design for ng-grid here. To be honest, it comes down to the word “grid” and the fact that, well, making a grid responsive in a sensible way is hard (if not actually impossible). I have called this post “ng-dataList” for a reason, in that I want to think about a component to list data in a variety of formats, including (probably) grids. The idea, broadly, is to build the infrastructure component that understands things like interacting with data sources (see below), caching templates, figuring out which DOM entries to create and so on. It should come with some default Presentation options but with the user able to completely change them as they see fit.
But I am getting ahead of myself here.
There are a number of articles out there emphasising that responsive design isn’t just about reformatting the same data for different form factors, it’s about trying to understand what the user wants to do when using different devices and adapt accordingly. For example, if you are looking at a flight booking site, chances are that on your mobile you are browsing and “getting a feel” whereas you are more likely to do the actual booking when sat at your computer. This means that you want to think differently about what information you show to the user in the list of possible flights, depending on the device they are using. There was a very good article covering this that I can’t currently find.
The other aspect is the increasing importance of “cards”. This article explains it better than I ever could. Suffice to say, the ability to show a list of data as cards, either all underneath each other or even with multiple cards per row is an extremely useful thing – for large screens as well.
Yes, you can build “card lists” like this yourself, and indeed we have done so. But you still need to think very carefully about pagination and DOM manipulation if your backing data store has thousands of data items. Hence, having a reusable component that handles all of that plumbing and simply hands over a set of objects to a template provided by the end-developer seems like a useful thing.
Searching
An interesting thing to consider if you show data as cards is searching/filtering and sorting. With a grid it’s quite easy; people know that they can click on column-headers to sort and they know that if there is an input box underneath the column heading then they can type something in there to filter. That’s all of a sudden a lot harder if you are showing a list of cards. One option may be to re-invent the ancient practice of “query-by-form”; You could potentially show a card at the top of the list and allow the user to type search data into it and to click on fields and/or labels to sort. In any case, it will require more UI thought than what you can get away with in a grid.
Data sources
jgGrid is designed to work with remote data sources and give you a bunch of hooks to provide functions for to get data in to the grid. ng-grid natively expects you to have all the data locally in an array but provide you with a number of hooks you can override in order to support server-side pagination, sorting and filtering. I have successfully written a directive that allows me to relatively easily use ng-grid with an oData backend, so the model works. However, it is too hard to write such directives; there are too many things you have to override and too many little tweaks you need to put in.
What I would prefer is the concept of a “data source” which is a separate javascript function (or object instance) which can be passed information about pagination, filtering and sorting in a standard way and will then be responsible for returning the appropriate set of data to the “infrastructure” component – of course, via a promise or a callback.
That way, rather than pointing the “dataList-options” at an array, you would say something like
data: new inMemorySource($scope.data)
or
data: new oDataSource(url)
etc…
The thinking is to completely remove the core data handling from the core library and just use plugins. This would make it super easy to wire in different data providers.