Last active
August 29, 2015 14:24
-
-
Save brianally/c22ec8ab4468ef09c01b to your computer and use it in GitHub Desktop.
Multiple filters for Ember-Data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// some controller | |
import Ember from 'ember'; | |
export default Ember.Controller.extend({ | |
responses : [], | |
filteredResponses: [], | |
sectors : [], | |
dateFrom : null, | |
dateTo : null, | |
filters : { | |
region: {}, | |
sector: {}, | |
date : {} | |
}, | |
minDate: function() { | |
// responses are sent already ordered by date so just get first in list | |
var responses = this.get('filteredResponses'); | |
if ( responses.length ) { | |
var created = responses[0].get('respondent').get('created').toString(); | |
return new Date(created); | |
} | |
return new Date(); | |
}.property('responses', 'filteredResponses', 'dateFrom'), | |
maxDate: function() { | |
var responses = this.get('filteredResponses'); | |
if ( responses.length ) { | |
var created = responses.get('lastObject').get('respondent').get('created').toString(); | |
return new Date(created); | |
} | |
return new Date(); | |
}.property('responses', 'filteredResponses', 'dateTo'), | |
actions: { | |
filterByRegion: function (fnFilter) { | |
this.set('filters.region', fnFilter); | |
this.notifyFilterChange(); | |
}, | |
filterBySector: function (fnFilter) { | |
this.set('filters.sector', fnFilter); | |
this.notifyFilterChange(); | |
} | |
// no action for date; uses observer | |
}, | |
dateDidChange: function() { | |
var dateFrom = this.get('dateFrom') || this.get('minDate'); | |
var dateTo = this.get('dateTo') || this.get('maxDate'); | |
var from = moment( new Date(dateFrom.toString()) ); | |
var to = moment( new Date(dateTo.toString()) ); | |
if (to.isBefore(from, 'day')) { | |
alert(''to' cannot come before 'from'!'); | |
return; | |
} | |
var fnFilter = function(item) { | |
var created = moment( new Date(item.get('respondent').get('created').toString()) ); | |
return (from.isBefore(created, 'day') || from.isSame(created, 'day') ) && ( created.isBefore(to, 'day') || created.isSame(to, 'day') ); | |
}; | |
this.set('filters.date', fnFilter); | |
this.notifyFilterChange(); | |
}.observes('dateFrom', 'dateTo'), | |
notifyFilterChange: function() { | |
var filters = this.get('filters'); | |
// we want the unfiltered responses because we'll iterate through all filters | |
var responses = this.model.get('responses'); | |
Object.keys(filters).forEach(function(n) { | |
if ( typeof filters[n] === 'function' ) { | |
responses = responses.filter( filters[n] ); | |
} | |
}); | |
this.set('filteredResponses', responses); | |
} | |
}); | |
// bootstrap-dropdown-select-filter.js | |
import Ember from 'ember'; | |
export default Ember.Component.extend({ | |
valueKey: 'id', | |
labelKey: 'name', | |
selectedOption: function() { | |
if (Ember.isEmpty(this.get('value'))) { | |
return {id: 0, name: 'All'}; | |
} else { | |
return this.get('options').findProperty('id', this.get('value')); | |
} | |
}.property('options', 'value'), | |
actions: { | |
select: function(opt) { | |
this.set('value', opt.id); | |
var fnFilter = function(item) { | |
return this.get('value') === Ember.get(item, this.get('filter-key-path')); | |
}.bind(this); | |
this.sendAction('action', fnFilter); | |
}, | |
reset: function() { | |
this.set('value', null); | |
this.sendAction('action', function() { return true; }); | |
} | |
} | |
}); | |
// region-filter.js | |
// see: | |
// http://blessanmathew.com/2014/08/16/ember.js-list-filtering-using-a-multiple-selection-filter-component.html | |
import Ember from 'ember'; | |
export default Ember.Component.extend({ | |
selectedItems: [], | |
click: function(event) { | |
var el = Ember.$(event.target); | |
var filterFn; | |
if (el.is('input[type=checkbox]')) { | |
if (el.is(':checked')) { | |
this.get('selectedItems').pushObject(el.val()); | |
} else { | |
this.get('selectedItems').removeObject(el.val()); | |
} | |
} | |
if (this.get('selectedItems.length')) { | |
filterFn = function(item) { | |
return this.get('selectedItems') | |
.contains(Ember.get(item, this.get('filter-key-path'))); | |
}.bind(this); | |
} else { | |
filterFn = function() {return true;}; | |
} | |
this.sendAction('action', filterFn); | |
} | |
}); | |
// multiple-selection-filter.js | |
// see: | |
// http://blessanmathew.com/2014/08/16/ember.js-list-filtering-using-a-multiple-selection-filter-component.html | |
import Ember from 'ember'; | |
export default Ember.Component.extend({ | |
selectedItems: [], | |
// for each checked checkbox, store value in selectedItems | |
setSlectedItems: function() { | |
var _this = this; | |
this.$('input[type=checkbox]').each(function(i, el) { | |
if ( _this.$(el).is(':checked') ) { | |
_this.get('selectedItems').pushObject( _this.$(el).val() ); | |
} | |
}); | |
}.on('didInsertElement'), | |
// set all checkboxes to checked state and store values | |
resetChecked: function() { | |
var _this = this; | |
this.$('input[type=checkbox]').each(function(i, el) { | |
_this.$(el).prop('checked', true); | |
_this.get('selectedItems').pushObject( _this.$(el).val() ); | |
}); | |
}, | |
click: function(event) { | |
var el = this.$(event.target); | |
var filterFn; | |
if (el.is('input[type=checkbox]')) { | |
if (el.is(':checked')) { | |
this.get('selectedItems').pushObject(el.val()); | |
} else { | |
this.get('selectedItems').removeObject(el.val()); | |
} | |
} | |
if (this.get('selectedItems.length')) { | |
filterFn = function(item) { | |
return this.get('selectedItems') | |
.contains(Ember.get(item, this.get('filter-key-path'))); | |
}.bind(this); | |
} else { | |
this.resetChecked(); | |
filterFn = function() { return true;}.bind(this); | |
} | |
this.sendAction('action', filterFn); | |
} | |
}); | |
/* | |
{{! single-select dropdown -- choose a sector }} | |
<div class="sectors"> | |
<h5>Filter by sector</h5> | |
{{ui/bootstrap-dropdown-select-filter | |
options=sectors | |
filter-key-path="respondent.sector.id" | |
action="filterBySector"}} | |
</div> | |
{{! multi-select checkboxes -- deselect regions }} | |
<ul class="region-group"> | |
<h5>Filter by region</h5> | |
{{#ui/multiple-selection-filter filter-key-path="respondent.region.name" action="filterByRegion"}} | |
{{#each region in regions}} | |
<li class=""> | |
<label> | |
<input type="checkbox" class="item-checkbox" {{bind-attr value=region}} checked="checked" /> | |
{{region}} | |
</label> | |
</li> | |
{{/each}} | |
{{/ui/multiple-selection-filter}} | |
</ul> | |
{{! dual datepickers -- narrow date interval }} | |
<div class="date-range form-inline"> | |
<h5>Filter by date</h5> | |
<div class="form-group"> | |
<label>From:</label> | |
{{bootstrap-datepicker | |
value=dateFrom | |
startDate=minDate | |
endDate=maxDate | |
format="yyyy-mm-dd" | |
autoClose=true | |
clearBtn=true}} | |
</div> | |
<div class="form-group"> | |
<label>To:</label> | |
{{bootstrap-datepicker | |
value=dateTo | |
startDate=minDate | |
endDate=maxDate | |
format="yyyy-mm-dd" | |
autoClose=true | |
clearBtn=true}} | |
</div> | |
</div> | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment