Planning for table sorting
We've had results table sorting by column-header-click on the list of features for a while, and I'd like to get it done. There are lots of implementations of this out there (I've written one or two myself in the past), but the complication here is that the output tables consist of two rows for each visible row; one contains the data, and the next contains a div which will be used to display a retrieved record for viewing or editing. When I sort the table, I need to keep these pairs of rows together. The former always has an id beginning with "disp", and the latter has a class of "recDisplayRow", so they're relatively easy to distinguish, but I'm still not quite sure of the exact method to use. There's a sophisticated library here which has some good pointers, although a lot of its code is superfluous to our needs as it's handling old browser limitations. It also has workarounds for the vagaries of table structures which we don't need to worry about, because our tables have a predictable structure (although I was annoyed to discover that I didn't use thead, just a regular row full of th tags -- but that's not a problem really because row 0 is always the header).
So I think the answer is to learn from that code, but write something much simpler. This would be the basic plan:
- Sorting is accomplished by detaching the rows in pairs, and storing them in a 2-level JS array, like this:
- rows[0][0] = extracted data from the column in row #1 on which the rows will be sorted. This can be passed to the the sort algorithm.
- rows[0][1] = row #1 (first data row)
- rows[0][2] = row #2 (associated hidden view/edit row)
- rows[1][0] = extracted data from the column in row #3 on which the rows will be sorted.
- rows[1][1] = row #3 (second data row)
- rows[1][2] = row #4 (associated hidden view/edit row)
- We obviously need an algorithm for extracting the text content of the column, but that should be fairly simple; as far as I can tell, it really just amounts to getting the td node's text content, but there may be the odd exception (images for attachments?).
- The next question is how to sort the content; there are various different types, including integers, dates, floats (treating lat and long as floats) and text. Each of these needs a different sorting algorithm, and each type of content needs to be identified in order for us to know the content type. Up to now there's been nothing to identify the data type of the content, so I've added a class to the header cell so that we can easily tell which comparator function to invoke. The class is simply the classname of the underlying AdaptiveDB field type. This is not costly because it happens only once for each column. There are a couple of good comparator functions already in the
- We also need to add a little span which can contain an indicator triangle showing that the table has been sorted by a specific column. This can be empty until it's filled when a sort is invoked. I've already added this to the code in the trunk.
- The sort procedure itself will need to be passed the column that's been clicked on; it could either derive this from "sender", or the column code itself could have its position hard-coded into it as part of the JS call. The latter is probably easier.
- There has to be a way for the JS to remember what column was last used to sort the data, and which direction it was sorted in, so that it can (for instance) remember to sort in reverse if clicking for the second time on a header, and remove a previous triangle from another header when a subsequent sort changes the order. This could be done by stashing content in variables, but we have to remember that at any time, the table can be replaced by the results of another search, which since it's done by AJAX, would not empty those variables.
Can't think of anything else right now...