Seen a few options for filtering data via checkboxes but it all seems fairly overly complicated for something I\'d expect Angular to do easily.
Take a nose at http://pln
Here is a solution; showing diffs only:
In index.html modify the relevant lines as follows:
<li data-ng-repeat="result in results | unique: 'provider.name'">
<input type="checkbox"
id="cb_{{ result.provider.providerId }}"
data-ng-model="checkbox[result.provider.providerId]"
/>
<label for="cb_{{ result.provider.providerId }}">{{ result.provider.name }}</label>
</li>
...
<li data-ng-repeat="result in ( filteredItems = (results | filter: searchByCarClass | filter: selectCarClass | filter: searchByCheckbox )) | orderBy:orderByFilter">
...
</li>
In script.js add:
$scope.checkbox = {};
var showAll = true;
$scope.searchByCheckbox = function(result) {
return showAll || $scope.checkbox[result.provider.providerId];
};
$scope.$watch("checkbox", function(newval, oldval) {
showAll = true;
angular.forEach($scope.checkbox, function(val) {
if( val === true ) showAll = false;
});
}, true);
(EDIT) Changed the key to $scope.checkbox
to providerId
. Filter starts disabled, so all entries are shown.
Good luck!
Just for the fun of it, I implemented a solution that has a much simpler API (wish of Leads in comments). Here it goes:
Add the cbFilter
dependency to the controller, remove all the checkbox
-related code and replace it as follows; this is the new API (it can't get any simpler :)
app.controller('resultsData', function($scope, $http, cbFilter){
...
$scope.checkbox = cbFilter($scope, "provider.providerId");
...
}
Rreplace the filter in the list (notice searchByCheckbox
is replaced by checkbox
):
<li data-ng-repeat="result in ( filteredItems = (results | filter: searchByCarClass | filter: selectCarClass | filter: checkbox )) | orderBy:orderByFilter">
And, finally, add the service:
app.factory("cbFilter", ["$parse", function($parse) {
return function($scope, matchExpression) {
var showAll = true,
getter = $parse(matchExpression),
filter = function(data) {
if( showAll ) return true;
return filter[getter(data)] === true;
},
unwatch = $scope.$watch(
function() {
var x, ret = {};
for( x in filter ) {
if( !filter.hasOwnProperty(x) ) continue;
ret[x] = filter[x];
}
return ret;
},
function() {
showAll = true;
angular.forEach(filter, function(val) {
if( val === true ) showAll = false;
});
},
true
);
$scope.$on("$destroy", unwatch);
return filter;
};
}]);
The implementation is much more complex than before, and probably slower. However the API is much simpler (one-liner).