Geeks With Blogs
James Timperley

Knockout.js is fantastic! Maybe I missed it but it appears to be missing flexible filtering, sorting, and pagination of its grids. This is a summary of my attempt at creating this functionality which has been working out amazingly well for my purposes.

Before you continue, this post is not intended to teach you the basics of Knockout. They have already created a fantastic tutorial for this purpose. You'd be wise to review this before you continue.

http://learn.knockoutjs.com/

Please view the full source code and functional example on jsFiddle. Below you will find a brief explanation of some of the components.

http://jsfiddle.net/JTimperley/pyCTN/13/

First we need to create a model to represent our records. This model is a simple container with defined and guaranteed members.

function CustomerModel(data)
{
    if (!data)
    {
        data = {};
    }
    
    var self = this;
    self.id = data.id;
    self.name = data.name;
    self.status = data.status;
}

Next we need a model to represent the page as a whole with an array of the previously defined records. I have intentionally overlooked the filtering and sorting options for now. Note how the filtering, sorting, and pagination are chained together to accomplish all three goals. This strategy allows each of these pieces to be used selectively based on the page's needs. If you only need sorting, just sort, etc.

function CustomerPageModel(data)
{
    if (!data)
    {
        data = {};
    }
    
    var self = this;
    self.customers = ExtractModels(self, data.customers, CustomerModel);
    
    var filters = […];
    var sortOptions = […];
    self.filter = new FilterModel(filters, self.customers);
    self.sorter = new SorterModel(sortOptions, self.filter.filteredRecords);
    self.pager = new PagerModel(self.sorter.orderedRecords);
}

The code currently supports text box and drop down filters. Text box filters require defining the current 'Value' and the 'RecordValue' function to retrieve the filterable value from the provided record. Drop downs allow defining all possible values, the current option, and the 'RecordValue' as before. Once defining these filters, they are automatically added to the screen and any changes to their values will automatically update the results, causing their sort and pagination to be re-evaluated.

var filters = [
    {
        Type: "text",
        Name: "Name",
        Value: ko.observable(""),
        RecordValue: function(record) { return record.name; }
    },
    {
        Type: "select",
        Name: "Status",
        Options: [
            GetOption("All", "All", null),
            GetOption("New", "New", true),
            GetOption("Recently Modified", "Recently Modified", false)
        ],
        CurrentOption: ko.observable(),
        RecordValue: function(record) { return record.status; }
    }
];

Sort options are more simplistic and are also automatically added to the screen. Simply provide each option's name and value for the sort drop down as well as function to allow defining how the records are compared.

This mechanism can easily be adapted for using table headers as the sort triggers. That strategy hasn't crossed my functionality needs at this point.

var sortOptions = [
    {
        Name: "Name",
        Value: "Name",
        Sort: function(left, right) { return CompareCaseInsensitive(left.name, right.name); }
    }
];

Paging options are completely contained by the pager model.

Because we will be chaining arrays between our filtering, sorting, and pagination models, the following utility method is used to prevent errors when handing an observable array to another observable array.

function GetObservableArray(array)
{
    if (typeof(array) == 'function')
    {
        return array;
    }
 
    return ko.observableArray(array);
}
Posted on Monday, July 29, 2013 3:55 AM Knockout.js , JavaScript | Back to top


Comments on this post: Knockout.js - Filtering, Sorting, and Paging

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
good one !
Left by Altaf Shaik on Aug 17, 2013 12:07 AM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
I completely agree that Knockout is missing a top-notch grid plugin. koGrid was a very nice start, but is not fully featured, and development seems to have come to a stop.

jQuery Datatables seems to have something in works, but still in development. http://datatables.net/dev/knockout/

What you have made here is a very, very nice start. Would be cool to see some upgrades, such as: sorting on each column in the th, not an external drop-down, dynamic building of options for header select elements, grid-editing options (making data observables and using ko.utils.unwrapObservable is a start).
Left by mg1075 on Aug 21, 2013 11:38 AM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
great! :) but how do you fetch the data? from where? do you get it from database?
Left by Uze on Sep 19, 2013 7:22 AM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
I have been tooling around with this solution because it is really nice. My guess on how to build dynamic drop downs / options is tying it directly to self.currentPageRecords so that every time it updates it recomputes the options. Correct me if I am wrong because I am going to attempt to make this more dynamic.
Left by Jon on Feb 25, 2014 8:56 AM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
Hi.... i have a question.... when i add a item to array, the DOM dont refresh.... Refresh only when I change select dropdrown or other filter.... How refresh DOM inmediatly when item add to array Cuestomers without interaction with filters?

Thanks for your help.

Excuse my english...
Left by Elkin on Feb 26, 2014 9:25 PM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
My solution was add productos..... Not of CustomerPageModel.

Yes of FilterModel.
Left by Elkin on Mar 08, 2014 5:40 AM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
Hi, very nice article! Would it be possible to add multiple filters to this, ie. two or more filter select boxes?

Thank you.
Left by Adrian on Dec 08, 2014 7:34 AM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
Very nice. Also check out knockout-datatable, looks like a hidden gem: https://github.com/immense/knockout-datatable
Left by toxin on Dec 13, 2014 4:59 AM

# re: Knockout.js - Filtering, Sorting, and Paging
Requesting Gravatar...
Thanks for the wonderful work.I have been searching for the functionality like this for hours.Finally I found yours.Thanks
Left by Hsakarp on May 04, 2015 2:20 PM

# Column Headers
Requesting Gravatar...
Can this be adjusted to use column headers to sort instead of dropdown boxes?

Thanks
Left by Jono on Oct 15, 2015 9:56 AM

Your comment:
 (will show your gravatar)


Copyright © jtimperley | Powered by: GeeksWithBlogs.net