Filtering by a Date Range in Your Data Table

This is the story…

of a couple plugins and some github repos that got together and started ajam band. They just wanted to cover some mixpanel songs. Such as the basic table with a global search:

Screen Shot 2015-01-07 at 10.12.37 PM



And adate range filter:

Screen Shot 2015-01-07 at 10.08.29 PM



Here’s how

For the first-time visitor, our web app is an Angular front-end calling a JSON API.

A while ago I settled on Renard Laurent’s Smart Table as a suitable module for creating a data table. I found it performed much betterthan ng-grid, which is more popular but severelyoverburdened by its bloated feature set. I’ve alway had a weakness for wanting compatibility with old versions of IE and Smart Table is (was, the last I checked) better at that, too.

So, I set up smart table, using Bootstrap to style it of course:

And here is what a session object might look like:

Screen Shot 2015-01-07 at 10.28.28 PM



Notice that it has deep properties – such as the coach’s name. That turned out to be problematic. Later. First, I wanted to get that date range filter working. Googling it for 30 minutes turned up a couple angular modules that were built on top of a Bootstrap date range picker by Dan Grossman. The one I settled on was this one, by fragaria. But this one looked good, too.

So include the script files and the css files and put the directivedate-range-picker on a button and you get a dropdown much like you see in the feature image of this post. Feels good but now we have to get the table filtered. Google that for 30 minutes (probably more…) before you see that someone has already asked for help in a github issue. Renard supplies aplunkr to illustrate how we would create a custom filter for a date range (or any kind of range).

That got mydate range filter working.

But, now I want to filter by deep properties.Such as, to use the data in Renard’s plunkr, I want to filter by first name and last name when the object looks like this:

$scope.displayed = [ { person: { firstName: 'Laurent', lastName: 'Renard' }, birthDate: new Date('1987-05-21'), balance: 102, email: [email protected]' },

4 hours later, after toying in the chrome dev editor and the aforementioned plunkr, I have decided the best way to go is to “flatten” the object as such:

[ { "person": { "firstName": "Laurent", "lastName": "Renard" }, "birthDate": "1987-05-21T00:00:00.000Z", "balance": 102, "email": "[email protected]", "person.firstName": "Laurent", "person.lastName": "Renard" },

See how the properties of the person object are now on the parent, by way of using the dot notation in the property keys?

Here’s how to do it:

//break out the notation angular.forEach(expression, function(value, key) { if (key.indexOf('.') != -1) { var input = value; angular.forEach(array, function(row) { if (!row[key]) { var valid = true; var getter = $parse(key); var value = getter(row); if (input && input != '') { row[key] = value; } } }); } }); var output = filterFilter(array, expression, customComparator);

Do this before you even call the customComparator. Then, we can use the regular ol’ standardComparator to take care of the deep properties. If you’re asking yourself what the hell are the two comparators I just mentioned, then look at this plunkr.

Now, we can search in each column with one of these:

Cool? Cool. See it in action below:

Conclusion

  1. Shout outs to all the people who build these modules and plugins.
  2. Mad props to plunkr.
  3. Much love to chrome dev editor – this was the first project where I actually changed the javascript code of my files through the dev editor. And it’s a breeze – saved me a bunch of git push’ing.