How to filter the objects with multiple values? - angularjs

I have the array of objects. when I require to filter the object by single vaue i am doing like this:
$scope.filteredByPhase = $filter('filter')($scope.allApps, {Phase:"All"});
$scope.allAppsBatch = $scope.filteredByPhase;
But as a option, I would like to filter the objects by 2 'Phase` values by "All" or "Home" in this case how to filter?
I tried like this:
$scope.filteredByPhase = $filter('filter')($scope.allApps, {Phase:("All" || "Home")});
$scope.allAppsBatch = $scope.filteredByPhase;
But not works.. any one guide me please?

In AngularJS, you can use a function as an expression in the filter. In the function you can validate the condition and return Boolean value. All the falsy items are filtered out of the result. So you can do
$scope.filteredByPhase = $filter('filter')($scope.allApps, function (app) {
if (app.Phase == "All" || app.Phase == "Home") {
return true;
}
return false;
});
Read More : AngularJS Filter Documentation

Use $filter passing an anonymous comparison function.
$scope.filteredItems = $filter('filter')($scope.items, function (item) {
return (item.Phase == "all") ? true : false;
});
Keep in mind that you may use Array.filter as well:
$scope.items = [{
Phase: "home"
}, {
Phase: "all"
}, {
Phase: "all"
}, {
Phase: "home"
}];
console.log($scope.items);
$scope.filteredItems = $scope.items.filter(function (item) {
return (item.Phase == "all") ? true : false;
})
console.log($scope.filteredItems)
You may also trigger multiple filtering actions using chaining:
$scope.fi = $scope.i.filter(func1).filter(func2);

Related

Return objects in array with 'true' parameters

I have a teamDetails array, within which is a squad array, within which are player objects. Each player object has an injured property which contains the value "true" or "false".
I want to write a function that loops through the array returning only players whose injured property evaluates to true.
This is what I have so far (not working):
$scope.injuredPlayerSearch = function() {
var injuredPlayers = [];
$scope.teamDetails.squad.forEach(function(o) {
if (o[injured] === true) {
injuredPlayers.push(o)
}
});
return injuredPlayers;
}
I can't see what's wrong with this. If anyone can, would appreciate some help.
You do not need to write any function. angular is there for you.
var injuredPlayers = $filter('filter')($scope.teamDetails.squad, {injured:true}, true);
Here $filter is angular filter. Do dependency inject to your controler or sevice where you are using.
For more about angular filter refer here
Note: 2nd true is for strict type checking. it is equivalent to injured===true
EDIT
For showing it to directly on view angular has much better solution.
{{teamDetails.squad | filter:{injured:true}:true}}
For use in view no need any dependency injection or controller.
If the iteration is within an array of array this is the correct implementation:
$scope.injuredPlayerSearch = function() {
var injuredPlayers = [];
$scope.teamDetails.forEach(function(t){
t.squad.forEach(function(o) {
if (o[injured] === true) {
injuredPlayers.push(o)
}
});
});
return injuredPlayers;
}
You could use filter to return players who are injured:
$scope.injuredPlayerSearch = function() {
return $scope.teamDetails.squad.filter(function(o) {
return o[injured];
});
}
try this
var injuredPlayers = [];
angular.forEach($scope.teamDetails.squad,function(s){
if (s.injured === true) {
injuredPlayers.push(s)
}
})
return injuredPlayers;
Use the javascript filter
var players = [{ id : 0 , injured : true},
{ id : 1 , injured : false},
{ id : 2 , injured : false},
{ id : 3 , injured : true},
{ id : 4 , injured : true}];
var injuredPlayers = players.filter(filterByInjured)
function filterByInjured(player) {
if ('injured' in player && typeof(player.injured) === 'boolean' && player.injured === true) {
return true;
}
}
console.log(injuredPlayers);
You did everything correct just left something
$scope.injuredPlayerSearch = function() {
var injuredPlayers = [];
angular.forEach($scope.teamDetails.squad,function(o) {
if (o[injured] === true) {
injuredPlayers.push(o)
}
});
return injuredPlayers;
}

Multiple optional filters in angular

I am very new to angular and, I am not sure how to control the behavior of my filters.
In the app, I have two different single-select drop down controls that filter the results of my data set and fill a table. However, even though these filters work, the results are dependent of both controls and if both are not being used , the empty set is returned. So, my question is: How can I use these filters optionally? So, the app returns every result when the filters are not used or returns the filtered results by one of the controls or both?
Thank you
Here is the code:
AngularJS
The filters for each control. They look very similar:
.filter('byField', function () {
return function (results, options) {
var items = { options: options, out: [] };
angular.forEach(results, function (value, key) {
for (var i in this.options) {
if ((options[i].value === value.fieldId &&
options[i].name === "Field" &&
options[i].ticked === true)) {
this.out.push(value);
}
}
}, items);
return items.out;
};
})
.filter('byClass', function () {
return function (results, options) {
var items = { options: options, out: [] };
angular.forEach(results, function (value, key) {
for (var i in this.options) {
if ((options[i].value === value.documentClass &&
options[i].name === "Class" &&
options[i].ticked === true)) {
this.out.push(value);
}
}
}, items);
return items.out;
};
})
HTML
This is what I am doing to populate the rows of the table:
<tr ng-repeat="result in results | byField:outputFields | byClass:outputClasses">
<td>{{result.documentId}}</td>
...
</tr>
Dorado7.1 in all event listeners provides a view implicit variable pointing to the current event host's view, the variable can completely replace the use of this scenario.
Well, as I imagined the answer was more related to set theory than to angular.
I just made an union between the empty set and every result, and it worked.
.filter('byField', function () {
return function (results, options) {
var items = { options: options, out: [] };
angular.forEach(results, function (value, key) {
if (options.length) {
for (var i in this.options) {
if ((options[i].value === value.fieldId &&
options[i].name === "Field" &&
options[i].ticked === true)) {
this.out.push(value);
}
}
} else {
this.out = results.slice();
}
}, items);
return items.out;
};
})

AngularJs - Filter an object only by certain fields in a custom filter

I'm working on this codepen. The data comes from an array of objects, and I need to make a filter only by name and amount.
I have this code, but if you type a character in the search box, it only search by amount, and not by name too. In other words, if the you type 'warren' or '37.47' it has to return the same result, but doesn't works.
var filterFilter = $filter('filter');
$scope.filter = {
condition: ""
};
$scope.$watch('filter.condition',function(condition){
$scope.filteredlist = filterFilter($scope.expenses,{name:condition} && {amount:condition});
$scope.setPage();
});
You want to create a custom filter for your app.
directiveApp.filter("myFilter", function () {
return function (input, searchText) {
var filteredList = [];
angular.forEach(input, function (val) {
// Match exact name
if (val.name == searchText) {
filteredList.push(val);
}
// Match exact amount
else if (val.amount == searchText) {
filteredList.push(val);
}
});
input = filteredList;
return input;
};
});
You can write your logic in this filter and now use this filter to filter your list.
Update
You can just implement this filter to your custom filter pagination.
Here is the new version of your code. Codepen
List of updates on your code
Added new filter parameter to your ng-repeat attribute
ng-repeat="expense in filteredlist | pagination: pagination.currentPage : numPerPage : filter.condition"
...
Well, finally (based in the idea of Abhilash P A and reading the docs), I solved my question in this way:
var filterFilter = $filter('filter');
$scope.filter = {
condition: ""
};
$scope.$watch('filter.condition',function(condition){
$scope.filteredlist = filterFilter($scope.expenses,function(value, index, array){
if (value.name.toLowerCase().indexOf(condition.toLowerCase()) >= 0 ) {
return array;
}
else if (value.amount.indexOf(condition) >= 0 ) {
return array;
}
});
$scope.setPage();
});
The final codepen ! (awsome)

Filter with multiple values

I have items which should have multiple (e.g. categories). Now I want to filter my items to these categories.
I think the task is not possible with the filter-directive without using a custom filter, right?
I came up with a solution, but it looks dirty and wrong to me:
$scope.filterList = function (item) {
var found = false;
var allFalse = true;
angular.forEach(item.attributes, function (value, key) {
if ($scope.activeAttributes[value.name] === true) {
found = true;
}
});
angular.forEach($scope.activeAttributes, function (value, key) {
if (value === true) {
allFalse = false;
}
});
$log.log("length: " + Object.keys($scope.activeAttributes).length);
if (found === true || Object.keys($scope.activeAttributes).length === 0 || allFalse === true) {
return true;
}
};
Demo JSFiddle of my code
I thought with Angular, that the code should be simple and most of the work should be done by Angular. What if I need to filter more attributes?

angularjs - ngRepeat with OR filter

I have a list with the items (name: String, age: Int, checked:Boolean).
This list is displayed with an ng-repeat.
I want to enable the user to search the list using a searchfield, but the search must not affect the checked-values.
the search should only trigger, if the users enters something in the searchfield
if the seachfield is filled, the search should filter as usual, but the checked items must not be filtered out.
I tried to create a custom filter. I have problems in understanding the $filter('filter') function with my OR-logic.
Could anyone help me untie the knot in my brain?
app.filter('mySearchFilter', function($filter) {
return function(data, searchText) {
if(!searchText || searchText.length === 0) {
return data;
}
console.log(searchText);
return $filter('filter')(data, searchText);
//how can I provide additional, OR-concatinated, filter-criteria?
}
});
Check out my plunk for the minimal-example-code.
http://plnkr.co/edit/3xHLOrSPD3XZy2K9U2Og?p=preview
As I understand you, you are looking for a union function. Underscore provide such a function. With this you may write your filter in this way:
app.filter('mySearchFilter', function($filter) {
return function(data, searchText) {
if(!searchText || searchText.length === 0) {
return data;
}
var allChecked = data.filter(function(d){return d.checked});
var allMatched = $filter('filter')(data, searchText);
return _.union(allMatched, allChecked);
}
});
have a look at: http://documentcloud.github.io/underscore/#union and don't forget to include the script:
<script src="http://documentcloud.github.io/underscore/underscore.js"></script>
PLUNKR

Resources