The base table in the example below is a clone of the showcase example to demonstrate that the dropdown keeps the filter state across various table operations such as filtering, sorting, paging.
All core objects or "classes" in FooTable are derived from the FooTable.Class object. This object exposes a single
method called extend
which allows you to create a whole new class from a base class (inherit) or to simply override a single method on an existing class.
In this example we will be inheriting the base FooTable.Filtering component, modifying it and then replacing, it
with our modified version.
FooTable.MyFiltering = FooTable.Filtering.extend({ // inherit the base class
construct: function(instance){ // override the default constructor
this._super(instance); // call the base constructor
}
});
// replace the existing component with our custom one
FooTable.components.core.register('filtering', FooTable.MyFiltering);
To make the code more maintainable going forward and easier to understand we will add some properties to our custom filtering component to hold the available options, the default option, and the jQuery wrapper around our dropdown.
FooTable.MyFiltering = FooTable.Filtering.extend({
construct: function(instance){
this._super(instance);
this.statuses = ['Active','Disabled','Suspended']; // the options available in the dropdown
this.def = 'Any Status'; // the default/unselected value for the dropdown (this would clear the filter when selected)
this.$status = null; // a placeholder for our jQuery wrapper around the dropdown
}
});
To create the actual dropdown element and append it to the table we will override the $create
method and generate our markup as required. The base filtering
component exposes the property $form
which is the jQuery wrapper for the form that contains the default search input. Using this we can simply create our
dropdown and append it as required.
$create: function(){
this._super(); // call the base $create method, this populates the $form property
var self = this, // hold a reference to my self for use later
// create the bootstrap form group and append it to the form
$form_grp = $('<div/>', {'class': 'form-group'})
.append($('<label/>', {'class': 'sr-only', text: 'Status'}))
.prependTo(self.$form);
// create the select element with the default value and append it to the form group
self.$status = $('<select/>', { 'class': 'form-control' })
.on('change', function(){
self.filter(); // when ever the dropdown value changes trigger the filter operation
})
.append($('<option/>', {text: self.def}))
.appendTo($form_grp);
// add each of the statuses to the dropdown element
$.each(self.statuses, function(i, status){
self.$status.append($('<option/>').text(status));
});
}
At this point we have the dropdown appearing next to the search input and it triggers a filter operation whenever it is changed however we need to hook into the
filter operation to actually apply our custom filter. To do this we will override the base filtering components' filter
method and use the
addFilter
and removeFilter
methods to implement the status filter.
filter: function(query, columns){
var val = this.$status.val(); // get the current dropdown value
if (val != this.def) this.addFilter('status', val, ['status']); // if it's not the default value add a new filter
else this.removeFilter('status'); // otherwise remove the filter
return this._super(query, columns); // call the base filter method
}
So now we have the dropdown, it's applying the filter as required but we also need it to clear itself when we click the [X] button on the search input. To do this
we will override the base filtering components' clear
method and use the removeFilter
method to remove the status filter.
clear: function(){
this.$status.val(this.def); // reset the dropdown to the default value
this.removeFilter('status'); // remove the filter
return this._super(); // call the base clear method
}
That's it! We now have a custom filter dropdown that is fully integrated with the rest of the filter functionality. The full code can be seen below.
FooTable.MyFiltering = FooTable.Filtering.extend({
construct: function(instance){
this._super(instance);
this.statuses = ['Active','Disabled','Suspended'];
this.def = 'Any Status';
this.$status = null;
},
$create: function(){
this._super();
var self = this,
$form_grp = $('<div/>', {'class': 'form-group'})
.append($('<label/>', {'class': 'sr-only', text: 'Status'}))
.prependTo(self.$form);
self.$status = $('<select/>', { 'class': 'form-control' })
.on('change', function(){
self.filter();
})
.append($('<option/>', {text: self.def}))
.appendTo($form_grp);
$.each(self.statuses, function(i, status){
self.$status.append($('<option/>').text(status));
});
},
filter: function(query, columns){
var val = this.$status.val();
if (val != this.def) this.addFilter('status', val, ['status']);
else this.removeFilter('status');
return this._super(query, columns);
},
clear: function(){
this.$status.val(this.def);
this.removeFilter('status');
return this._super();
}
});
FooTable.components.core.register('filtering', FooTable.MyFiltering);