Filter.js
Filter.js is client-side JSON objects filter which can render html elements. Multiple filter criteria can be specified and used in conjunction with each other.
Usage
Basic requirement to implement filtering using filter.js are JSON data, a 'View' template and a filter criteria.
Filter Initialisation
It takes three arguments one is movies, second is 'container' in which html elements are to be to appended and the third one is options. You can set options such as template, criteria, callbacks and search but only template
is compulsory.
var FJS = FilterJS(movies, '#movies', { template: '#movie-template', filter_on_init: true, // Default filter_on_init is false callbacks: { afterFilter: function(result){ $('#total_movies').text(result.length); } } });
To append each item in different container use option appendToContainer
. This option is a function with two arguments, one is html element content and second is record object.
//This will append elements to specific year. var appendFn = function(html_ele, record) { $("#" + record.year).append(html_ele); } var FJS = FilterJS(movies, '#movies', { template: '#movie-template', appendToContainer: appendFn });
JSON data
Capture the JSON data (maybe using @movies.to_json).
var movies = [ { "name": "The Shawshank Redemption", "rating": 9.3, "director": "Frank Darabont", "year": 1994, "stars": [ "Tim Robbins", "Morgan Freeman", "Bob Gunton" ], "runtime": 142, "genre": [ "Crime", "Drama" ], "id": 1 }, .... .... ]
View
Rendering JSON objects requires a view template. The micro-templating module in filter.js is inspired by Underscore.js.
<script id="movie-template" type="text/html"> <div class="movie"> <div class="thumbnail"> <span class="label label-success rating"><%= rating %></span> <div class="caption"> <h4><%= name %></h4> <div class="outline"> <%= outline %> <span class="runtime"> <i class="glyphicon glyphicon-time"></i> <%= runtime %> mins. </span> </div> <div class="detail"> <dl> <dt>Actors</dt> <dd><%= stars %></dt> <dt>Year</dt> <dd><%= year %></dd> </dl> </div> </div> </div> </div> </script>
Filter Criteria
The two mandatory options required are field
which is name of any property from JSON data and other is HTML ele
element on which filter will be triggered by an event(e.g. click, change, etc.). Other filter options are type
, event
and selector
.
- filter
type
: by default it is equal but if you want to search within a range you can set it torange
. Forrange
, html element value should be in format ofval1-val2
(e.g.100-200
). By default hyphen '-' is used asdelimiter
or range separatorval1-val2
. If you want to use a different separator (if data contains hyphen e.g: '2012-02-02') it can be specified usingdelimiter: ','
and html element value should be in formatval1<delimiter>val2
. i.e.2012-02-02,2015-02-02
. event
by default for checkbox and radio button isclick
and for text input and select box it ischange
.selector
by default for checkbox and radio button is:checked
, for input field isinput
and for select box isselect
. '#genre_criteria input:checkbox' will collect the checkboxes values in html element withid="genre_criteria"
all
option : if selected values of specific filter criteria containsall
option value then all record selected for that criteria.
There are two way to add criteria. One is add at time of filter object initialisation and other is add when required.
//On create var fjs = FilterJS(movies, '#movies', { template: '#movie-template', criterias: [ {field: 'year', ele: '#year_filter', type: 'range'} ] } // Add one at a time. FJS.addCriteria({field: 'year', ele: '#year_filter', type: 'range'}) FJS.addCriteria({field: 'genre', ele: '#genre_criteria input:checkbox'}) // with all option FJS.addCriteria({field: 'year', ele: '#year_filter', type: 'range', all: 'all_years'}) // Full options list. FJS.addCriteria({field: 'genre', ele: '.genres', event: 'change', selector: ':checked' })
field: genre
this is a JSON attribute defined in JSON objects.
For Range selections
More detail for range
filter. It is expected to set ranges as values like '20-30'
Example:
<input checked="checked" value="20-30" type="checkbox">
For nested field selection: In the below object, to select filter on name field
option value would be detail.name
and for city detail.address.city
.
JSON object:
{ detail: { name: 'Jiren', address: { city: 'Pune' } } }
Remove criteria.
Using removeCriteria
, remove criteria dynamically. It take one argument filed
name. i.e removing year criteria.
fjs.removeCriteria('year')
Filtering Callbacks
Define callback in settings. Callbacks execute on different events.
beforeAddRecords
: Triggered before adding records to filter.afterAddRecords
: Triggered after all records are added.beforeRender
: Triggered before rendering going to call.beforeRecordRender
: Triggered for each JSON object record at time of rendering.afterFilter
: Triggered after filtering event.
i.e.,
var filter_callbacks = { beforeAddRecords: function(records){ // Process new JSON data records. // i.e Process data before adding to filter while streaming. }, afterAddRecords: function(records){ // i.e Update google markers or update sorting. }, beforeRender: function(records){ // }, beforeRecordRender: function(record){ //i.e Add/Update record fields }, afterFilter: function(result){ // i.e Update result counter, update google map markers. } };
Init Filter object with above callbacks
var fjs = FilterJS(movies, '#movies', { template: '#movie-template', callbacks: filter_callbacks } # Or add callback separately. FJS.addCallback('afterAddRecords', function(){ // i.e Update total count });
Instant Search integration
To enable search, add a textbox element and set the selector in options. By default search will work on all JSON object fields. If you want to search on some particular fields then set the fields
option.
// Init with search FilterJS(movies, '#movies', { template: '#movie-template', search: { ele: '#searchbox' } // Search in all fields of JSON object. } // Search in given fields search: { ele: '#searchbox', fields: ['name', 'runtime'] }
The search will trigger after 2 characters by default. This can be configured using start_length
option.
search: {ele: '#searchbox', fields: ['name', 'runtime'], start_length: 4 }
By default search will start immediately after a user types. A timeout can be configured using timeout
option (in milliseconds).
search: {ele: '#searchbox', fields: ['name', 'runtime'], timeout: 100 }
Add more data to existing filter
If you are streaming JSON data using ajax then you can add data like this
var fjs = FilterJS(movies, '#movies', { template: '#movie-template'}) fJS.addData(data)
Add data using ajax streaming
Add streaming option to above define 'settings'.
var fjs = FilterJS(movies, '#movies', { template: '#movie-template', streaming: { data_url: 'movies/index.json', stream_after: 1, batch_size: 50 } });
- Only 'data_url' is mandatory.
- 'stream_after' default value is 2 sec.
- Streaming ajax request format
movies/index.json.json?offset=0&limit=50&q='search text'
Add streaming after initialisation.
fjs.setStreaming({ data_url: 'data/stream_movies.json', stream_after: 1, batch_size: 50 });
Remove records from filtering
- Remove records using the record's
id
field.
fjs.removeRecords([1,2,3]);
- Remove using JsonQuery criteria
fjs.removeRecords({year: 1980}); fjs.removeRecords({'year.$gt': 1980, 'rating': 8.5});
Change Template dynamically and Rebuild
If you want to change the template dynamically but do not want to re-render the view (you many choose to render the template yourself) then just pass the template name to setTemplate
function.
fjs.setTemplate('#movie-list-template');
If you want to re-render the new template then pass a second paramater as true
. This will render the container with the data using the new template specified and apply the filtering.
fjs.setTemplate('#movie-list-template', true);
Build and Development
npm install gulp -g
- Install packages
npm install
- To build
gulp build
- For development
gulp
. This will start watch on files, also start webserver.
Note
- Old filter.js in v1.5.2 git tag.
Demo
To see the sample demo, clone this repo and open demo/filterjs.html in your browser
Auto filtering using html attributes
Used by
Itrenewdirect (product search)
If you use this, please send me an email, I shall add your link here!
Sponsors and Supporters
- Josh Software
- Instant search field filtering sponsored by W/E consultants
Contributing
Please send me a pull request so that this can be improved.
License
This is released under the MIT license.