Filter.js is client-side JSON objects filter and render html elements. Multiple filter criteria can be specified and used in conjunction with each other.
Basic requirement to implement filtering using filter.js are JSON data, View template and filter criteria.
It takes three arguments one is movies, second is container in which html element going to append, third one is options. Options must have template element selector. Others are in options like criteria, callbacks, search.
var FJS = FilterJS(movies, '#movies', {
template: '#movie-template',
callbacks: {
afterFilter: function(result){
$('#total_movies').text(result.length);
}
}
});To append in 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
});Capture the JSON data (maybe using @movies.to_json). i.e
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
},
....
....
]Rendering JSON objects requires a view template. In filter.js micro-templating module 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>It required two mandatory options are field which is name of any property from JSON data and other is HTML ele element on which filter will be trigger by click,change etc events.
Other options are filter type, event and selector.
- filter
type, by default it is equal but if you want to search in range you can set itrange. Forrangehtml element value should be in format ofval1-val2. i.e100-200. delimiter, by default hyphen '-' is used as 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.eventby default for checkbox, radio button isclick, for text input, select box ischange.selectorby default for checkbox and radio button is:checked, for input fieldinputand for select box isselect.'#genre_criteria input:checkbox' will collect the checkboxes values in html element withid="genre_criteria"alloption : if selected values of specific filter criteria containsalloption 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.
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 below object to select filter on name field option value would be detail.name, for city detail.address.city.
JSON object:
{
detail: { name: 'Jiren', address: {city: 'Pune'} }
}Using removeCriteria, remove criteria dynamically. It take one argument filed name. i.e removing year criteria.
fjs.removeCriteria('year')Define callback in settings. Callbacks execute on different events.
beforeAddRecords: Trigger before adding records to filter.afterAddRecordsbeforeRender: Trigger before rendering going to call.beforeRecordRender: Trigger for each JSON object record at time of rendering.afterFilter: Trigger 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.
}
};var fjs = FilterJS(movies, '#movies', {
template: '#movie-template',
callbacks: filter_callbacks
}
# Or add callback separately.
FJS.addCallback('afterAddRecords', function(){
// i.e Update total count
});For search needed textbox element selector. By default search will work on all JSON object fields. If needed search in particular fields then set 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']}Default search will trigger after 2 char. This can be configured using start_length option.
search: {ele: '#searchbox', fields: ['name', 'runtime'], start_length: 4 }Default search will start searching immediately after user types. A timeout can be configured using timeout option (in milliseconds).
search: {ele: '#searchbox', fields: ['name', 'runtime'], timeout: 100 }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 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 using the record's
idfield.
fjs.removeRecords([1,2,3]);- Remove using JsonQuery criteria
fjs.removeRecords({year: 1980});
fjs.removeRecords({'year.$gt': 1980, 'rating': 8.5});npm install gulp -g- Install packages
npm install - To build
gulp build - For development
gulp. This will start watch on files, also start webserver.
- Old filter.js in v1.5.2 git tag.
To see the sample demo, clone this repo and open demo/filterjs.html in your browser
[Filter with Pagination] (http://jiren.github.io/filter.js/pagination.html)
If you use this, please send me an email, I shall add your link here!
- Josh Software
- Instant search field filtering sponsored by W/E consultants
Please send me a pull request so that this can be improved.
This is released under the MIT license.