Multiple Boolean Filter in Angular? - angularjs

I have a settings node in a user with three boolean values and a three exact same values in an item. I want to filter the list of items based on the user setting on which to display.
I searched high and low and nothing seems to be working:
item:
{"cash_back": true,
"miles": false,
"points": false
}
user:
settings: {"cash_back": true,
"miles": false,
"points": true
}
html:
ng-repeat="item in items | filter: {cash_back: user.settings.cash_back, points: user.settings.points, miles: user.settings.miles} | limitTo: curLimit"
...but it does work if I have one
filter: {cash_back: user.settings.cash_back}
obviously just for that setting...
can anyone help on this?
I would like to see all that are true (so if points and miles are true see all points and miles items even if there is a miles item with a points value of false)

I figured it out on my own. (One thing to note is in my user node I keep track of a list of item ids - the reason for the initial for loop) I set up a filtering function and compared the two boolean values ( I separated each into an if statement for debugging and tracking results - this can be cleaned up later.)
function:
$scope.settingsFilter = function(card){
var temp = {};
for(c in $scope.cards){
if ($scope.cards[c].id === card){
temp = $scope.cards[c];
break;
}
}
if(($scope.user.settings.cash_back == true && temp.cash_back == true)){
return true;
}
if(($scope.user.settings.points == true && temp.points == true)){
return true;
}
if(($scope.user.settings.miles == true && temp.miles == true)){
return true;
}else{
return false;
}
return false;
}
html:
ng-repeat="card in userCards | filter:settingsFilter track by $index"

Related

Angular 6 check box doesn't change state based on ngModel

In an array say I have five mantras out of it users have to choose maximum of three. This is my implementation
<input class='f-z-14' type="checkbox" [(ngModel)]='mantrasSelected[i]' [checked]='mantrasSelected[i] === true' (change)='mantraChecked(i, mantrasSelected[i], mantra)'>
And in my ts
mantraChecked(i, event, mantra) {
if (event) {
if (this.selectedCount < 3) {
this.selectedCount += 1;
this.mantrasSelected[i] = true;
} else {
this.mantrasSelected[i] = false;
}
} else {
if (this.selectedCount > 0 && this.selectedCount <= 3) {
this.selectedCount -= 1;
this.mantrasSelected[i] = false;
}
}
}
So If i choose first three means in this.mantrasSelected I will be having [true, true, true, false, false]. So If user checked fourth one means I'm checking in my mantraChecked() if count is greater than 3 means I dont want to check it. after I click 4th mantra I'm changing mantrasSelected to [true, true, true, false, false] but view shows it is checked. How can show to the user that they have checked only three box? How two biding work with checkbox? Thank you.

Angular Filter controller filter default display all objects if no category is selected

html
ng-click="selectCategory(item)"
controller
$scope.selectCategory = function (newCategory) {
$scope.bottomValue = newCategory;
selectedCategory = newCategory;
$scope.selectedPage = 1;
}
$scope.categoryFilterFn = function (product) {
return selectedCategory == null ||
product.category == selectedCategory;
}
I have the category filter controller side below that's working fine and filtering the array correctly however when no category has been selected no objects are selected which is not desired
Objective : I want all values in the array to be displayed when no category is selected
e.g. note when $scope.bottomValue is removed from below all the objects in the array are returned.
$scope.edition_products = $filter('filter')( $scope.filteredItems, {approved: true, category: $scope.bottomValue});
Note: I no I can do this view side with filters but I want this working controller side.
You can update your condition to
return !selectedCategory || product.category == selectedCategory;
You might even want to add the approved there
return product.approved && (!selectedCategory || product.category == selectedCategory);

AngularJS - ng-if checking for true values when key is unknown

I want to apply a ng-if in AngularJS depending if any of the values in a JSON is true.
The first level keys are always the same, but then the second level keys are always different. (so I cannot do ng-if="known_stuff.unpredictable_thing", as the name of "unpredictable_thing" will be different each time. Here is the JSON.
{
"known_stuff":
{
"unpredictable_thing":false
},
"known_stuff_2":
{
"non_predictable_stuff":true
},
"known_stuff_3":
{
"something_unknown":false
}
}
Thanks in advance!
controller:
$scope.check = function(someObject) {
// return true if some value is true inside the object
for (var key in someObject) {
if (someObject[key] === true) {
return true;
}
}
return false;
};
template:
ng-if="check(known_stuff)"
or
ng-show="check(known_stuff)"
if your data is an array then the function has to look like that:
$scope.checkData = function(data) {
for (var i = 0; i < data.length; i++) {
for (var key1 in data[i]) {
// return true if some value is true inside the object
for (var key in data[i][key1]) {
if (data[i][key1][key] === true) {
return true;
}
}
}
}
return false;
};
template:
ng-if="checkData(data)"
If you want to check any of the value in your provided json is true then
ng-if="known_stuff.unpredictable_thing == ture ||
known_stuff_2.non_predictable_stuff == true ||
known_stuff_3.something_unknown == true"
If I got your question right, your json will have the first level key same (known_stuff) but inside know_stuff there can be multiple key with different names (like unpredictable_thing here).
The easiest solution is to iterate the first level key, gaining key value pair like below.
<div ng-repeat = "(key, val) in known_stuff" ng-if="known_stuff[key]">
//do something --> {{key}} - {{val}}
</div>
Supporting Plunk -> http://plnkr.co/edit/6hQQAtqRseb1gWvueFKr
-----------------------------------------------UPDATE---------------------------------------------
Assign jsonData with your data.
<div ng-repeat= "stuff in jsonData">
<div ng-repeat = "(key, val) in stuff" ng-if="stuff[key]">
//do something --> {{key}} - {{val}}
</div>
</div>
Also, updated the same plunk. I hope this answers your question.

AngularJS - stuck on removing/clearing a filter

I have a filter applied on a drop down, but I would like it removed depending on another drop down value. Code below. If the user chooses "Medium" (or any other value), then I need the filter removed that gets applied when the user selects "Small". Right now, if the user chooses "Small" and then "Medium", the options are still being filtered out.
if(val == "Small"){
$scope.Variant.Specs.Color.Options = $scope.Variant.Specs.Color.Options.filter(function(item) {
return item.Value !== 'Red' && item.Value !== 'Blue';
});
}
else if(val == "Medium") {
$scope.Variant.Specs.Color.Options = $scope.Variant.Specs.Color.Options;
}
Create an angular $filter which takes the colors and size as arguments.
app.filter('filterColors', function() {
return function(colors, size) {
if(size=='Medium') {
return colors;
} else {
return colors.filter(function(d) {
return d != 'Red' && d != 'Blue';
});
}
}
});
plunkr

Ignoring blank dropdown values in an AngularJS filter

I have a tabular list of user data which I'm adding 'advanced search' functionality to. The advanced search consists of a number of dropdowns allowing users to filter their results, for example, limiting the results to users from a particular department:
<select ng-model="search.department_id" ng-options="department.id as department.name for department in departments">
<option value="">(Select from list)</option>
</select>
The results are then displayed using:
<table>
<tr ng-repeat="user in users | filter:search | orderBy:'name')">
<td> [code to show user data here.] </td>
</tr>
</table>
If you select a department from the dropdown, this works correctly. But if you change your mind and pick the default '(Select from list)' option again, only users with a blank department_id value are shown. What I want to happen is for the department dropdown to be ignored if no department is selected.
After some searching around, it looked like I could solve this using a custom comparator, so I wrote this:
$scope.ignoreNullComparator = function(expected, actual){
if (expected === null) {
return true;
} else {
return angular.equals(expected, actual);
}
};
and changed the ng-repeat to:
ng-repeat="user in users | filter:search:ignoreNullComparator | orderBy:'name'
but although with some debugging could see the custom comparator being used, it didn't make any difference to the results.
So, how can I get the filter to ignore the dropdowns if the blank option is selected?
The order of parameters in your comparator is wrong, comparator should be defined as function(actual, expected):
$scope.ignoreNullComparator = function(actual, expected){
if (expected === null) {
return true;
} else {
return angular.equals(expected, actual);
}
};
i update the function to work with string and number search fields
$scope.ignoreNullComparator = function(actual, expected){
if (expected === null || expected === '' || typeof expected === "undefined") {
return true;
} else if(!isNaN(expected)) {
expected2 = parseInt(expected);
return angular.equals(expected2, actual);
} else if( actual.indexOf(expected) === -1 ){
return false;
}
return true;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

Resources