increment variable when checkbox is checked - angular - angularjs

I want the $scope.selectedRecords variable to increment when a checkbox is checked. Right now nothing appears to happen, meaning the {{selectedRecords}} doesn't increment. There is no change.
Controller:
$scope.selectedRecords = 0;
// SET-UP ROW CLICK FOR CHECKBOX
$scope.setSelected = function(record) {
if (!record.Selected) {
record.Selected = true;
$scope.selectedRecords += 1
} else {
record.Selected = false;
$scope.selectedRecords -= 1
}
}
HTML:
<h4>{{selectedRecords}} users selected</h4>
<tr ng-repeat="record in records | orderBy:sortType:sortReverse | filter:searchUsers" ng-class="class" class="row-link" ng-click="setSelected(record)">
<input type="checkbox" ng-model="record.Selected" ng-click="setSelected(record)">

Here's a working example : http://codepen.io/anon/pen/pjNWVL?editors=101
Can't really understand why your sample doesn't work, but mine might give you some help :-)
HTML :
<div ng-app="pouet" ng-controller="PouetCtrl">
<h4>{{selectedRecords}} users selected</h4>
<div ng-repeat="record in records">
<input type="checkbox" ng-model="record.selected" ng-click="setSelected(record)">
<span class="label">{{record.label}}</span>
</div>
</div>
JS :
var mod;
mod = angular.module('pouet', []);
mod.controller('PouetCtrl', function($scope) {
$scope.records = [
{
selected: false,
label: 'foo'
}, {
selected: true,
label: 'bar'
}, {
selected: true,
label: 'baz'
}
];
$scope.selectedRecords = ($scope.records.filter(function(record) {
return record.selected;
})).length;
$scope.setSelected = function(record) {
if (record.selected) {
record.Selected = true;
$scope.selectedRecords += 1;
} else {
record.selected = false;
$scope.selectedRecords -= 1;
}
};
});

The problem is that you have not defined record on the scope. If you add something like this to your controller:
$scope.record = {};
Then things should work.
Now, if you are in an ng-repeat block, things will be more complicated.

Related

How to programmatically check checkbox with dynamic model name?

I have created a some checkboxes with dynamic model name like this:
<label ng-repeat="item in main.itemDetails">
<input type="checkbox" checklist-value="item.price"
ng-click="itemChanged(item)" ng-model="checkboxes[item.name]">
{{item.name}} - <b>{{item.price}} €</b>
<br>
</label>
In my controller, I want to check some checkboxes if their model's name exists in array $scope.selectedItems.
I'm trying to do something like this but it isn't working:
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope['selectedItems[i].name'].isChecked = true;
}
for example if item.name = 'Item1' I want the model to be named $scope.Item1 and later I want to call $scope.Item1.isChecked = true;
What Am I doing wrong here?
Your are storing the model in the $scope.checkboxes, so you can set its value to true like the code below.
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope.checkboxes[$scope.selectedItems[i].name] = true;
}
It looks like your using a string literal here:
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope['selectedItems[i].name'].isChecked = true;
}
Just change this to read:
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope[selectedItems[i].name].isChecked = true;
}
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.main = [{
'name':'test1',
'price':'23',
'isChecked':false
},
{
'name':'test2',
'price': '25',
'isChecked':false
},
{
'name':'test3',
'price': '21',
'isChecked':false
}];
$scope.selectedItems = [{
'name':'test1'
},
{
'name':'test2'
}];
angular.forEach($scope.main, function(valueMain){
angular.forEach($scope.selectedItems,function(valueSelected){
if(valueMain.name=== valueSelected.name){
valueMain.isChecked = true;
}
})
});
$scope.toggleCheck = function(item){
if(item.isChecked === true){
item.isChecked === false;
}else{
item.isChecked === true;
};
}
}
<script src="https://code.angularjs.org/angular-1.0.1.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<label ng-repeat="item in main">
<input type="checkbox" ng-model="item.isChecked" ng-checked="item.isChecked" ng-change="toggleCheck(item)">
{{item.name}} - <b>{{item.price}} €</b>
<br>
</label>
</div>
</div>
Angular Foreach is the easiest way to solve this kind of problem.

directive that controlls upvotes and downvotes

I'm developing a upvote/downvote controlling system for a dynamic bunch of cards.
I can controll if I click to the img the checked = true and checked = false value but The problem I've found and because my code doesn't work as expected is I can't update my value in the ng-model, so the next time the function is called I receive the same value. As well, I can't update and show correctly the new value. As well, the only card that works is the first one (it's not dynamic)
All in which I've been working can be found in this plunk.
As a very new angular guy, I tried to investigate and read as much as possible but I'm not even 100% sure this is the right way, so I'm totally open for other ways of doing this, attending to performance and clean code. Here bellow I paste what I've actually achieved:
index.html
<card-interactions class="card-element" ng-repeat="element in myIndex.feed">
<label class="rating-upvote">
<input type="checkbox" ng-click="rate('upvote', u[element.id])" ng-true-value="1" ng-false-value="0" ng-model="u[element.id]" ng-init="element.user_actions.voted === 'upvoted' ? u[element.id] = 1 : u[element.id] = 0" />
<ng-include src="'upvote.svg'"></ng-include>
{{ element.upvotes + u[1] }}
</label>
<label class="rating-downvote">
<input type="checkbox" ng-click="rate('downvote', d[element.id])" ng-model="d[element.id]" ng-true-value="1" ng-false-value="0" ng-init="element.user_actions.voted === 'downvoted' ? d[element.id] = 1 : d[element.id] = 0" />
<ng-include src="'downvote.svg'"></ng-include>
{{ element.downvotes + d[1] }}
</label>
<hr>
</card-interactions>
index.js
'use strict';
var index = angular.module('app.index', ['index.factory']);
index.controller('indexController', ['indexFactory', function (indexFactory) {
var data = this;
data.functions = {
getFeed: function () {
indexFactory.getJSON(function (response) {
data.feed = response.index;
});
}
};
this.functions.getFeed();
}
]);
index.directive('cardInteractions', [ function () {
return {
restrict: 'E',
link: function (scope, element, attrs) {
scope.rate = function(action, value) {
var check_up = element.find('input')[0];
var check_down = element.find('input')[1];
if (action === 'upvote') {
if (check_down.checked === true) {
check_down.checked = false;
}
} else {
if (action === 'downvote') {
if (check_up.checked === true) {
check_up.checked = false;
}
}
}
}
}
};
}]);
Hope you guys can help me with this.
Every contribution is appreciated.
Thanks in advice.
I have updated your directive in this plunker,
https://plnkr.co/edit/HvcBv8XavnDZTlTeFntv?p=preview
index.directive('cardInteractions', [ function () {
return {
restrict: 'E',
scope: {
vote: '='
},
templateUrl: 'vote.html',
link: function (scope, element, attrs) {
scope.vote.upValue = scope.vote.downValue = 0;
if(scope.vote.user_actions.voted) {
switch(scope.vote.user_actions.voted) {
case 'upvoted':
scope.vote.upValue = 1;
break;
case 'downvoted':
scope.vote.downValue = 1;
break;
}
}
scope.upVote = function() {
if(scope.vote.downValue === 1) {
scope.vote.downValue = 0;
scope.vote.downvotes--;
}
if(scope.vote.upValue === 1) {
scope.vote.upvotes++;
} else {
scope.vote.upvotes--;
}
};
scope.downVote = function() {
if(scope.vote.upValue === 1) {
scope.vote.upValue = 0;
scope.vote.upvotes--;
}
if(scope.vote.downValue === 1) {
scope.vote.downvotes++;
} else {
scope.vote.downvotes--;
}
};
}
};

How to Add a product to the cart and then update the quantity from both the product page and from the cart itself.

I am completely stumped on how to achieve something specific that the below website has achieved. Does anyone know how to update the quantity of a product from the product details page to the shopping cart, and have that quantity shared/bound between the cart and and the product details page for each an every product repeated from a collection. (I am not talking about simply having a global cart quantity total via a simple custom directive). Please see the link below. Add a product to the cart and then update the quantity from both the product page and from the cart itself. This is what I am trying to achieve. Thank you all in advance!
http://demo.shopnx.in/
Typically you'll get better responses if you post some code that you have tried and then ask to be guided on where you are going wrong. I've created a simple JSFiddle to demonstrate one method of doing this. It is extremely simple, contrived, not production worthy by any stretch of the imagination and doesn't really do much, but it should show you one construct that will allow you to accomplish the functionality you're after.
The key is to use some type of shared storage so that the same array of items is available to both your product listing and the cart. In the sample I have done this using a Value:
.value('cartStorage', {
items: []
})
This value is then injected in the main controller:
.controller('mainController', function(cartStorage) {
var _this = this;
_this.cartStorage = cartStorage;
_this.items = [{
name: 'Apple',
price: .5,
quantity: 0,
showAddToCart: false,
addedToCart: false
}, {
name: 'Orange',
price: .5,
quantity: 0,
showAddToCart: false,
addedToCart: false
}, {
name: 'Grapes',
price: 1,
quantity: 0,
showAddToCart: false,
addedToCart: false
}];
_this.addToCart = function(item) {
_this.cartStorage.items.push(item);
item.addedToCart = true;
}
_this.increaseItemAmount = function(item) {
item.quantity++;
item.showAddToCart = true;
}
_this.decreaseItemAmount = function(item) {
item.quantity--;
if (item.quantity <= 0) {
item.quantity = 0;
item.addedToCart = false;
item.showAddToCart = false;
var itemIndex = _this.cartStorage.items.indexOf(item);
if (itemIndex > -1) {
_this.cartStorage.items.splice(itemIndex, 1);
}
} else {
item.showAddToCart = true;
}
}
})
As well as the cart controller:
.controller('cartController', function(cartStorage) {
var _this = this;
_this.cartStorage = cartStorage;
_this.increaseItemAmount = function(item) {
item.quantity++;
}
_this.decreaseItemAmount = function(item) {
item.quantity--;
if (item.quantity <= 0) {
item.quantity = 0;
item.addedToCart = false;
item.showAddToCart = false;
var itemIndex = _this.cartStorage.items.indexOf(item);
if (itemIndex > -1) {
_this.cartStorage.items.splice(itemIndex, 1);
}
}
}
_this.removeFromCart = function(item) {
item.quantity = 0;
item.addedToCart = false;
item.showAddToCart = false;
var itemIndex = _this.cartStorage.items.indexOf(item);
if (itemIndex > -1) {
_this.cartStorage.items.splice(itemIndex, 1);
}
}
})
Now the cartStorage object is shared so any update made in one controller will automagically be reflected in the other controller. All that's left is the markup:
<div ng-app="app">
<div ng-controller="mainController as main">
<h2>Main Controller</h2>
<div>
<table>
<tr>
<td>Item</td>
<td>Price</td>
<td>Quantity</td>
<td></td>
</tr>
<tr ng-repeat="item in main.items">
<td>{{item.name}}</td>
<td>{{item.price | currency}}</td>
<td>{{item.quantity}}</td>
<td>
<button ng-click="main.increaseItemAmount(item)">+</button>
<button ng-click="main.decreaseItemAmount(item)">-</button>
<button ng-click="main.addToCart(item)" ng-show="item.showAddToCart && !item.addedToCart">Add to Cart</button>
</td>
</tr>
</table>
</div>
</div>
<div ng-controller="cartController as cart">
<h2>Cart Controller</h2>
<div>
<table>
<tr>
<td>Item</td>
<td>Price</td>
<td>Quantity</td>
<td></td>
</tr>
<tr ng-repeat="item in cart.cartStorage.items">
<td>{{item.name}}</td>
<td>{{item.price | currency}}</td>
<td>{{item.quantity}}</td>
<td>
<button ng-click="cart.increaseItemAmount(item)">+</button>
<button ng-click="cart.decreaseItemAmount(item)">-</button>
<button ng-click="cart.removeFromCart(item)">Remove from Cart</button>
</td>
</tr>
</table>
</div>
</div>
</div>
Update showing the usage of a Factory instead of Value
Instead of using a Value use this service:
.factory('cartStorage', function() {
var _cart = {
items: []
};
var service = {
get cart() {
return _cart;
}
}
return service;
})
Then modify the code in the controllers to use the .cart property of the service instead of the value. You only need to change one line of code in both controllers. Change:
_this.cartStorage = cartStorage;
to:
_this.cartStorage = cartStorage.cart;
Here is an updated JSFiddle.
I made this plunker as an example.
I've used events to achieve the desired behavior. (
This is just one way of doing this, should have a lot of possibilities)
ProductsController:
app.controller('ProductsCtrl', function($scope, $rootScope) {
$scope.products = [
{
'name': 'Product One',
'price': 10,
'qty': 0
},
{
'name': 'Product two',
'price': 20,
'qty': 0
}
];
// Fire event to add
$scope.add = function(product) {
product.qty++;
$rootScope.$broadcast('addProduct', product.price);
}
// Fire event to remove
$scope.remove = function(product) {
if(product.qty > 0) {
product.qty--;
$rootScope.$broadcast('removeProduct', product.price);
}
}
});
CartController:
app.controller('CartCtrl', function($scope) {
$scope.total = 0;
// Catch the event to add
$scope.$on('addProduct', function(event, data) {
$scope.total += data;
});
// Catch the event to remove
$scope.$on('removeProduct', function(event, data) {
$scope.total -= data;
});
});
View:
<div ng-controller="CartCtrl">Total: {{total}}</div>
<br>
<div ng-controller="ProductsCtrl">
<div ng-repeat="product in products">
<span>Name: {{product.name}}</span>
<br>
<span>Price:{{product.price}}</span>
<span>Quantity:{{product.qty}}</span>
<br>
<button type="button" ng-click="add(product);">Add</button>
<button type="button" ng-click="remove(product);">Remove</button>
<br><br><br>
</div>
</div>
You can have a shared service between your Product details and Cart detail controller which can have an array where you can push the the Product selected with its quantity and other details.

$filter with OR [duplicate]

I want to use the filter in angular and want to filter for multiple values, if it has either one of the values then it should be displayed.
I have for example this structure:
An object movie which has the property genres and I want to filter for Action and Comedy.
I know I can do filter:({genres: 'Action'} || {genres: 'Comedy'}), but what to do if I want to filter it dynamically. E.g. filter: variableX
How do I set variableX in the $scope, when I have an array of the genres I have to filter?
I could construct it as a string and then do an eval() but I don't want to use eval()...
I would just create a custom filter. They are not that hard.
angular.module('myFilters', []).
filter('bygenre', function() {
return function(movies,genres) {
var out = [];
// Filter logic here, adding matches to the out var.
return out;
}
});
template:
<h1>Movies</h1>
<div ng-init="movies = [
{title:'Man on the Moon', genre:'action'},
{title:'Meet the Robinsons', genre:'family'},
{title:'Sphere', genre:'action'}
];" />
<input type="checkbox" ng-model="genrefilters.action" />Action
<br />
<input type="checkbox" ng-model="genrefilters.family" />Family
<br />{{genrefilters.action}}::{{genrefilters.family}}
<ul>
<li ng-repeat="movie in movies | bygenre:genrefilters">{{movie.title}}: {{movie.genre}}</li>
</ul>
Edit here is the link: Creating Angular Filters
UPDATE: Here is a fiddle that has an exact demo of my suggestion.
You can use a controller function to filter.
function MoviesCtrl($scope) {
$scope.movies = [{name:'Shrek', genre:'Comedy'},
{name:'Die Hard', genre:'Action'},
{name:'The Godfather', genre:'Drama'}];
$scope.selectedGenres = ['Action','Drama'];
$scope.filterByGenres = function(movie) {
return ($scope.selectedGenres.indexOf(movie.genre) !== -1);
};
}
HTML:
<div ng-controller="MoviesCtrl">
<ul>
<li ng-repeat="movie in movies | filter:filterByGenres">
{{ movie.name }} {{ movie.genre }}
</li>
</ul>
</div>
Creating a custom filter might be overkill here, you can just pass in a custom comparator, if you have the multiples values like:
$scope.selectedGenres = "Action, Drama";
$scope.containsComparator = function(expected, actual){
return actual.indexOf(expected) > -1;
};
then in the filter:
filter:{name:selectedGenres}:containsComparator
Here is the implementation of custom filter, which will filter the data using array of values.It will support multiple key object with both array and single value of keys. As mentioned inangularJS API AngularJS filter Doc supports multiple key filter with single value, but below custom filter will support same feature as angularJS and also supports array of values and combination of both array and single value of keys.Please find the code snippet below,
myApp.filter('filterMultiple',['$filter',function ($filter) {
return function (items, keyObj) {
var filterObj = {
data:items,
filteredData:[],
applyFilter : function(obj,key){
var fData = [];
if (this.filteredData.length == 0)
this.filteredData = this.data;
if (obj){
var fObj = {};
if (!angular.isArray(obj)){
fObj[key] = obj;
fData = fData.concat($filter('filter')(this.filteredData,fObj));
} else if (angular.isArray(obj)){
if (obj.length > 0){
for (var i=0;i<obj.length;i++){
if (angular.isDefined(obj[i])){
fObj[key] = obj[i];
fData = fData.concat($filter('filter')(this.filteredData,fObj));
}
}
}
}
if (fData.length > 0){
this.filteredData = fData;
}
}
}
};
if (keyObj){
angular.forEach(keyObj,function(obj,key){
filterObj.applyFilter(obj,key);
});
}
return filterObj.filteredData;
}
}]);
Usage:
arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]}
Here is a fiddle example with implementation of above "filterMutiple" custom filter.
:::Fiddle Example:::
If you want to filter on Array of Objects then you can give
filter:({genres: 'Action', key :value }.
Individual property will be filtered by particular filter given for that property.
But if you wanted to something like filter by individual Property and filter globally for all properties then you can do something like this.
<tr ng-repeat="supp in $data | filter : filterObject | filter : search">
Where "filterObject" is an object for searching an individual property and "Search" will search in every property globally.
~Atul
I've spent some time on it and thanks to #chrismarx, I saw that angular's default filterFilter allows you to pass your own comparator. Here's the edited comparator for multiple values:
function hasCustomToString(obj) {
return angular.isFunction(obj.toString) && obj.toString !== Object.prototype.toString;
}
var comparator = function (actual, expected) {
if (angular.isUndefined(actual)) {
// No substring matching against `undefined`
return false;
}
if ((actual === null) || (expected === null)) {
// No substring matching against `null`; only match against `null`
return actual === expected;
}
// I edited this to check if not array
if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) {
// Should not compare primitives against objects, unless they have custom `toString` method
return false;
}
// This is where magic happens
actual = angular.lowercase('' + actual);
if (angular.isArray(expected)) {
var match = false;
expected.forEach(function (e) {
e = angular.lowercase('' + e);
if (actual.indexOf(e) !== -1) {
match = true;
}
});
return match;
} else {
expected = angular.lowercase('' + expected);
return actual.indexOf(expected) !== -1;
}
};
And if we want to make a custom filter for DRY:
angular.module('myApp')
.filter('filterWithOr', function ($filter) {
var comparator = function (actual, expected) {
if (angular.isUndefined(actual)) {
// No substring matching against `undefined`
return false;
}
if ((actual === null) || (expected === null)) {
// No substring matching against `null`; only match against `null`
return actual === expected;
}
if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) {
// Should not compare primitives against objects, unless they have custom `toString` method
return false;
}
console.log('ACTUAL EXPECTED')
console.log(actual)
console.log(expected)
actual = angular.lowercase('' + actual);
if (angular.isArray(expected)) {
var match = false;
expected.forEach(function (e) {
console.log('forEach')
console.log(e)
e = angular.lowercase('' + e);
if (actual.indexOf(e) !== -1) {
match = true;
}
});
return match;
} else {
expected = angular.lowercase('' + expected);
return actual.indexOf(expected) !== -1;
}
};
return function (array, expression) {
return $filter('filter')(array, expression, comparator);
};
});
And then we can use it anywhere we want:
$scope.list=[
{name:'Jack Bauer'},
{name:'Chuck Norris'},
{name:'Superman'},
{name:'Batman'},
{name:'Spiderman'},
{name:'Hulk'}
];
<ul>
<li ng-repeat="item in list | filterWithOr:{name:['Jack','Chuck']}">
{{item.name}}
</li>
</ul>
Finally here's a plunkr.
Note: Expected array should only contain simple objects like String, Number etc.
you can use searchField filter of angular.filter
JS:
$scope.users = [
{ first_name: 'Sharon', last_name: 'Melendez' },
{ first_name: 'Edmundo', last_name: 'Hepler' },
{ first_name: 'Marsha', last_name: 'Letourneau' }
];
HTML:
<input ng-model="search" placeholder="search by full name"/>
<th ng-repeat="user in users | searchField: 'first_name': 'last_name' | filter: search">
{{ user.first_name }} {{ user.last_name }}
</th>
<!-- so now you can search by full name -->
You can also use ngIf if the situation permits:
<div ng-repeat="p in [
{ name: 'Justin' },
{ name: 'Jimi' },
{ name: 'Bob' }
]" ng-if="['Jimi', 'Bob'].indexOf(e.name) > -1">
{{ p.name }} is cool
</div>
The quickest solution that I've found is to use the filterBy filter from angular-filter, for example:
<input type="text" placeholder="Search by name or genre" ng-model="ctrl.search"/>
<ul>
<li ng-repeat="movie in ctrl.movies | filterBy: ['name', 'genre']: ctrl.search">
{{movie.name}} ({{movie.genre}}) - {{movie.rating}}
</li>
</ul>
The upside is that angular-filter is a fairly popular library (~2.6k stars on GitHub) which is still actively developed and maintained, so it should be fine to add it to your project as a dependency.
I believe this is what you're looking for:
<div>{{ (collection | fitler1:args) + (collection | filter2:args) }}</div>
Please try this
var m = angular.module('yourModuleName');
m.filter('advancefilter', ['$filter', function($filter){
return function(data, text){
var textArr = text.split(' ');
angular.forEach(textArr, function(test){
if(test){
data = $filter('filter')(data, test);
}
});
return data;
}
}]);
Lets assume you have two array, one for movie and one for genre
Just use the filter as: filter:{genres: genres.type}
Here genres being the array and type has value for genre
I wrote this for strings AND functionality (I know it's not the question but I searched for it and got here), maybe it can be expanded.
String.prototype.contains = function(str) {
return this.indexOf(str) != -1;
};
String.prototype.containsAll = function(strArray) {
for (var i = 0; i < strArray.length; i++) {
if (!this.contains(strArray[i])) {
return false;
}
}
return true;
}
app.filter('filterMultiple', function() {
return function(items, filterDict) {
return items.filter(function(item) {
for (filterKey in filterDict) {
if (filterDict[filterKey] instanceof Array) {
if (!item[filterKey].containsAll(filterDict[filterKey])) {
return false;
}
} else {
if (!item[filterKey].contains(filterDict[filterKey])) {
return false;
}
}
}
return true;
});
};
});
Usage:
<li ng-repeat="x in array | filterMultiple:{key1: value1, key2:[value21, value22]}">{{x.name}}</li>
Angular Or Filter Module
$filter('orFilter')([{..}, {..} ...], {arg1, arg2, ...}, false)
here is the link: https://github.com/webyonet/angular-or-filter
I had similar situation. Writing custom filter worked for me. Hope this helps!
JS:
App.filter('searchMovies', function() {
return function (items, letter) {
var resulsts = [];
var itemMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if ( itemMatch.test(item.name) || itemMatch.test(item.genre)) {
results.push(item);
}
}
return results;
};
});
HTML:
<div ng-controller="MoviesCtrl">
<ul>
<li ng-repeat="movie in movies | searchMovies:filterByGenres">
{{ movie.name }} {{ movie.genre }}
</li>
</ul>
</div>
Here is my example how create filter and directive for table jsfiddle
directive get list (datas) and create table with filters
<div ng-app="autoDrops" ng-controller="HomeController">
<div class="row">
<div class="col-md-12">
<h1>{{title}}</h1>
<ng-Multiselect array-List="datas"></ng-Multiselect>
</div>
</div>
</div>
my pleasure if i help you
Too late to join the party but may be it can help someone:
We can do it in two step, first filter by first property and then concatenate by second filter:
$scope.filterd = $filter('filter')($scope.empList, { dept: "account" });
$scope.filterd = $scope.filterd.concat($filter('filter')($scope.empList, { dept: "sales" }));
See the working fiddle with multiple property filter
OPTION 1:
Using Angular providered filter comparator parameter
// declaring a comparator method
$scope.filterBy = function(actual, expected) {
return _.contains(expected, actual); // uses underscore library contains method
};
var employees = [{name: 'a'}, {name: 'b'}, {name: 'c'}, {name: 'd'}];
// filter employees with name matching with either 'a' or 'c'
var filteredEmployees = $filter('filter')(employees, {name: ['a','c']}, $scope.filterBy);
OPTION 2:
Using Angular providered filter negation
var employees = [{name: 'a'}, {name: 'b'}, {name: 'c'}, {name: 'd'}];
// filter employees with name matching with either 'a' or 'c'
var filteredEmployees = $filter('filter')($filter('filter')(employees, {name: '!d'}), {name: '!b'});
My solution
ng-repeat="movie in movies | filter: {'Action'} + filter: {'Comedy}"
the best answer is :
filter:({genres: 'Action', genres: 'Comedy'}

check a checkbox by clicking a link in angularJs

I have the folowing code :
<li ng-repeat="item in items">
<a href="#" ng-if="!item.children" ng-click="checkItem(item,checkBoxModel)">
<input class="align"
ng-click="checkItem(item,checkBoxModel)"
type="checkbox" ng-checked="master"
ng-model="checkboxModel"/>
{{ item.title }}
</a>
</li>
in my controller i have checkItem function:
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
$scope.master=true;
$scope.checkBoxModel = false;*
} else {
....
$scope.master = false;
$scope.checkBoxModel = true;
}
}
The problem is that when I click on a link all of the checkboxes are checked. I just want the checkbox associated to the link to be checked.
Instead of setting a value master on the controllers $scope object, set it on the actual item that you pass in, and set it's ng-checked="item.master" and it's ng-model="item.checkBoxModel"
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
item.master=true;
item.checkBoxModel = false;
} else {
....
item.master = false;
item.checkBoxModel = true;
}
}
Change your app logic. You have to declare a variable for each item. But as i see, you have one for all in the global $scope named master. The master should have been declared for each item to specify the state of the option box. Then your problem will be solved.
Something like this:
app.js
$scope.items = [
{
name: 'example',
master: false,
checkboxModel: false
},
{
name: 'example',
master: false,
checkboxModel: false
}
];
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
$scope.items[item].master = true;
...
} else {
....
$scope.items[item].master = false;
...
}
}
index.html
<input class="align"
ng-click="checkItem(item, checkBoxModel)"
type="checkbox" ng-checked="item.master"
ng-model="item.checkboxModel"/>
<li ng-repeat="item in items">
<a href="#" ng-if="!item.children" ng-click="checkItem(item)">
<input class="align"
ng-click="checkItem(item)"
type="checkbox" ng-checked="item.checked"
/>
{{ item.title }}
</a>
in my controller i change the value of item.checked

Resources