AngularJS Filter not playing ball - angularjs

Being new to the Angular framework I started my project using the angularSeed download. I have services and directives working fine but today I needed a filter and I just can't seem to get one working.
I have set up JSFiddle with a basic example of my setup and commented out my filter call because its causing errors. I simply want to filter out qty = 0, your experience would be much appreciated; :-)
<div ng:app="myApp">
<div ng-controller="myCtrl">
<!-- div ng-repeat="item in items | {filter : notZero}" -->
<div ng-repeat="item in items" >
<strong>{{item.title}}</strong> {{item.qty}}
</div>
</div>
</div>
and the JS
angular.module('myApp', [
'myApp.controllers',
'myApp.filters'
]);
angular.module('myApp.filters', [])
.filter('notZero', function() {
return function( items, condition) {
console.log( items, condition);
};
});
angular.module('myApp.controllers', [])
.controller('myCtrl', function($scope) {
$scope.items = [
{
"title":"40cm",
"qty":3
},
{
"title":"55cm",
"qty":2
},
{
"title":"60cm",
"qty":0
},
{
"title":"70cm",
"qty":4
}
];
});

Couple of ways to approach this:
You can have ng-repeat modified as: ng-repeat="item in
items|filter:{qty: '!0'}"
Write your own filter which checks the qty is greater than zero.
Use ng-if: <div ng-if="item.qty > 0"><strong>{{item.title}}</strong> {{item.qty}}</div>

EDIT:
define an app filter this way:
myApp.filter('qtyNotZero', function() {
return function(items) {
var afterFilter = [];
for (var i = 0; i < items.length; i++){
if(item[i].qty != 0)
afterFilter.push(item[i]);
}
return afterFilter;
};
});
and then simply:
<div ng-repeat="item in items | filter: qtyNotZero>
The filter should be applied for the qty:
<div ng-repeat="item in items | filter: {qty: '!0'}">
Or, if you have a more complicated filter, this way you can filter with your own logic:
<div ng-repeat="item in items" | filter: PositiveQty>
...
$scope.PositiveQty = function(item) {
return item.qty > 0;
}
Anyway, you could also use:
<div ng-show="item.qty">
<strong>{{item.title}}</strong> {{item.qty}}
</div>

Related

AngularJS filtering ng-repeat OR on multiple fields

How can I filter one search term on different fields combining them in an OR statement?
<ul>
<li ng-repeat="person in persons| filter:filters{surname: 'foo' OR name: 'foo'}">
{{person}}
</li>
</ul>
You either filter by all properties of each object with | filter:'foo', or create a custom filter, e.g.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.persons=[
{"id":1,"name":"foo","surname":"bar"},
{"id":2,"name":"baz","surname":"foo"},
{"id":3,"name":"null","surname":"undefined"},
{"id":4,"name":"name","surname":"surname"}
]
});
app.filter('searchBy', function() {
return function(array, param) {
var new_array = [];
angular.forEach(array, function(value) {
if (value.name == param || value.surname == param) { // your filter query in here
new_array.push(value);
}
})
return new_array;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="person in persons| searchBy:'foo'">
{{person}}
</li>
</ul>
</div>

Filter the object in the array by dynamic filter - AngularJS

Right now my data structure is like
product = [{att1:'2',att2:'red',att3:'gold'},
{att1:'1',att2:'blue',att3:'wood'},
{att1:'2',att2:'green',att3:'plastic'},
{att1:'1',att2:'red',att3:'plastic'}]
And I have a filter on the web page, it has three parts: att1, att2, att3. The user doesn't have to choose options for every part.
For filter att1 it has 2 options: "1" and "2".
Filter att2 it has 2 options: "red" "blue" and "green"
Filter att3 it has 3 options: "gold", "wood" and "plastic".
I can get the options that are selected. For example:
{att1:['2'],att3:['gold','plastic']} or {att1:['1']}
My question is, how do I use product.filter to filter the product data?
Thanks!
You can use a custom filter function which is easy to use, I used att1 but you can expand it to all fields:
var app = angular.module("MyApp", []);
app.controller("MyCtrl", function($scope) {
$scope.products = [{att1:'2',att2:'red',att3:'gold'},
{att1:'1',att2:'blue',att3:'wood'},
{att1:'2',att2:'green',att3:'plastic'},
{att1:'1',att2:'red',att3:'plastic'}];
$scope.filterFunction = function(element) {
return element.att1.match(/^Ma/) ? true : false;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<form class="form-inline">
<input ng-model="query" type="text"
placeholder="Filter by" autofocus>
</form>
<ul ng-repeat="product in products | filter:query">
<li>{{product}}</li>
</ul>
<ul ng-repeat="product in products | filter:filterFunction">
<li>{{product}}</li>
</ul>
</div>
</div>
I banged out the particular logic for this one, using the three nested loops isn't super great but it does do the job. I'm sure you can optimize this further by using some maps or something but I just went with the get it done by brute force approach :)
angular.module('myApp',[])
.service('ProductService', function(){
return {
products:[
{att1:'2',att2:'red',att3:'gold'},
{att1:'1',att2:'blue',att3:'wood'},
{att1:'2',att2:'green',att3:'plastic'},
{att1:'1',att2:'red',att3:'plastic'}
]
}
})
.controller('TestCtrl', function(ProductService){
this.ProductService = ProductService;
this.filterObject1 = {att1:['2'],att3:['gold','plastic']};
this.filterObject2 = {att1:['1']};
})
.filter('productFilter', function(){
return function(input,filterObj){
if(!filterObj){
return input;
}
var newArray = [];
var filterKeys = Object.keys(filterObj);
for(var i=0;i<input.length;i++){
var curElement = input[i];
innerLoops:
for(var j=0;j<filterKeys.length;j++){
var curKey= filterKeys[j];
for(var k=0;k<filterObj[curKey].length;k++){
var curFilterValue = filterObj[curKey][k];
if(curElement[curKey].match(curFilterValue)){
//We found a match keep this element and move on to checking the next one by breaking out of the inner loops that are checking particular keys/values
newArray.push(curElement);
break innerLoops;
}
}
}
}
return newArray;
};
})
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script>
<div ng-app="myApp" ng-controller="TestCtrl as ctrl">
Unfiltered
<div ng-repeat="product in ctrl.ProductService.products|productFilter">
{{product}}
</div>
<hr/>
<strong>Filtered with: {{ctrl.filterObject1}}</strong>
<div ng-repeat="product in ctrl.ProductService.products|productFilter:ctrl.filterObject1">
{{product}}
</div>
<hr/>
<strong>Filtered with {{ctrl.filterObject2}}</strong>
<div ng-repeat="product in ctrl.ProductService.products|productFilter:ctrl.filterObject2">
{{product}}
</div>
</div>

Repeat a div or span according to the json value using angularjs

Suppose i have a json file as
{
"count":"3"
}
how to show 3 span or "n" number of span according to json value
here is my Plunker url
CONTROLLER
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.count =3;
$scope.getNumber = function(num) {
return new Array(num);
}
});
HTML
<li ng-repeat="i in getNumber(myNumber) track by $index"><span>{{$index+1}}</span></li>
JSFIDDLE
$scope.number = 5;
$scope.getNumber = function(num) {
return new Array(num);
}
<ul>
<li ng-repeat="i in getNumber(number)"><span>{{$index+1}}</span></li>
</ul>
Not sure what you mean. But according to my view, you have 2 problems:
1. Read count in json file
2. Show n span in view.
To read a json file, you can create a service to get it. Follow this Reading data from JSON file in Angularjs
Show show those span, use ng-repeat:
Hello world
count is $scope variable in ur controller.
Hope this help
You could simply do this.
var app = angular.module("sampleApp", []);
app.controller("sampleController", ["$scope",
function($scope) {
$scope.pro = [{
product: "chicken",
rating: 3
}, {
product: "fish",
rating: 1
}, {
product: "pizza",
rating: 4
}];
$scope.repeat = function(rating) {
return new Array(rating);
}
}
]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<div ng-repeat="array in pro">
<div>{{array.product}}
<span ng-repeat="number in repeat(array.rating) track by $index" ng-init="">*</span>
</div>
</div>
</body>
</div>
</div>

How to display custom layout with ng-repeat

Edit: My original question was not good enough, so edited it now.
Hi Im new to angular and im trying to display a custom Layout
for my data list with ng-repeat. I cant use ng-class, as I would like to display diffent model vaules too.
I implemented a function in my controller, that calculates true or false according to my desired design. Then im trying to use ng-if to display my desired HTML with the data. The way I implemeted seems a bit awkward, especially if the layout gets more complicated, is there a better way to achieve this behaviour?
Here a sample: http://plnkr.co/edit/puE7OE?p=info
Controller:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.eventModels=[{name:'event1', description: 'description1'}, {name:'event2', description: 'description2'},
{name:'event3', description: 'description3'}, {name:'event4', description: 'description4'},
{name:'event5', description: 'description5'}, {name:'even6', description: 'description6'}, {name:'even7', description: 'description7'}];
var counter = 0;
this.isLarge = false;
$scope.isLargeContainer = function() {
if(counter === 0) {
this.isLarge = true;
counter++;
} else {
this.isLarge = false;
if(counter === 2) {
counter = 0;
} else {
counter++;
}
}
};
});
View:
<body ng-controller="MainCtrl">
<section ng-repeat="(key, eventModel) in eventModels" >
<div ng-init="isLargeContainer(eventModel)"></div> <!--the only way I found to call a function within the repeat directive.-->
<div ng-if="isLarge">
<!--Display large content -->
<p class='large'>my large event: {{eventModel.name}}, {{eventModel.description}}</p>
</div>
<div ng-if="!isLarge">
<!--Display content small-->
<p class='small'>{{eventModel.name}}</p>
</div>
</section>
</body>
Thanks a lot in advance!
Im using Anguler 1.3.3
I just solved your problem. You can find the solution here:
http://jsfiddle.net/anasfirdousi/46saqLmw/
Here is the HTML
var myApp = angular.module('myApp',[]);
function myController($scope){
$scope.msg = 'Learning Angular JS ng-class Directive';
$scope.menu = [ 'Menu Item 1','Menu Item 2','Menu Item 3','Menu Item 4'];
}
.large {
font-size:16px;
}
body{
font-size:12px;
}
<div ng-app="myApp" ng-controller="myController">
{{ msg }}
<ul>
<li ng-repeat="(key, value) in menu" ng-class="{'large': $index==2 }"> {{ value }} </li>
</ul>
</div>
In your case, you actually have to use ng-class with expressions. The class is applied only if the condition holds true.
http://jsfiddle.net/anasfirdousi/cuo6cn3L/
Check the above link. This is another example if you want to do it on any specific condition. You can call a function which checks a condition and returns either a true or a false rather than using an inline expression.
var myApp = angular.module('myApp',[]);
function myController($scope){
$scope.msg = 'Learning Angular JS ng-class Directive';
$scope.menu = [ 'Menu Item 1','Menu Item 2','Menu Item 3','Menu Item 4'];
$scope.CheckSometing = function(v){
if(v=='Menu Item 3'){
return true;
}
else
{
return false;
}
}
}
.large {
font-size:16px;
}
body{
font-size:12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
{{ msg }}
<ul>
<li ng-repeat="(key, value) in menu" ng-class="{'large': CheckSometing(value) }"> {{ value }} </li>
</ul>
</div>

Angularjs and filters returning JS error

I am having problems getting the angular seed framework working for filters, it is fine for services and directives but returns a "FilterProvider" error when I wire up a filter.
I really cant see where i am going wrong? i have set up a JSFiddle here ->
<div ng:app="myApp">
<div ng-controller="myCtrl">
<div ng-repeat="item in items | {filter : notZero}">
<strong>{{item.title}}</strong> {{item.qty}}
</div>
</div>
</div>
with my controllers and filter like this:
angular.module('myApp', [
'myApp.controllers',
'myApp.filters'
]);
angular.module('myApp.filters', [])
.filter('notZero', function() {
return function( items, condition) {
console.log( items, condition);
};
})
angular.module('myApp.controllers', [])
.controller('myCtrl', function($scope) {
$scope.items = [
{
"title":"40cm",
"qty":3
},
{
"title":"55cm",
"qty":2
},
{
"title":"60cm",
"qty":0
},
{
"title":"70cm",
"qty":4
}
];
});
This is how you invoke a custom filter:
<div ng:app="myApp">
<div ng-controller="myCtrl">
<div ng-repeat="item in items | notZero">
<strong>{{item.title}}</strong> {{item.qty}}
</div>
</div>
</div>
jsfiddle

Resources