Hide Empty Filtered ng-repeat - javascript

I am looking to hide a category if it it empty. My current solution is not working:
HTML:
<ul>
<li data-ng-repeat="items in shop | unique : 'cat' | orderBy: 'cat'">
<h2>{{items.cat}}</h2>
<ul>
<li ng-repeat="items in shop | filter:{cat: items.cat} | filter:query"
<h3>{{items.name}}</h3>
</li>
</ul>
</li>
</ul>
My Filter "unique" looks like so:
app.filter('unique', function() {
return function(collection, keyname) {
var output = [],
keys = [];
angular.forEach(collection, function(item) {
var key = item[keyname];
if(keys.indexOf(key) === -1) {
keys.push(key);
output.push(item);
}
});
return output;
};
});
JSON:
{
"businesses" : {
"-KQ1ggyrnYGYL1084Htz" : {
"name" : "business name",
"cat" : "food",
},
}
I assume that I could do something with ng-if and/or ng-hide/show but none of the combos I have done work.

You can use the ngIf directive or the ngShow/ngHide directives.
How you use them depends on your JSON.
Heres an example of the ngIf with some basic data:
(function() {
angular.module('MyApp', []);
})();
(function() {
angular.module('MyApp').controller('MyController', MyController);
MyController.$inject = ['$scope'];
function MyController($scope) {
$scope.shop = [{
name: "test 1",
cat: "cat 1"
}, {
name: "test 2",
cat: "cat 3"
}, {
name: "test 3",
cat: ""
}, {
name: "test 4",
cat: "cat 4"
}];
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="MyApp">
<div data-ng-controller="MyController">
<ul>
<li data-ng-repeat="items in shop | orderBy: 'cat'" ng-if="items.cat">
<h2>{{items.cat}}</h2>
<ul>
<li ng-repeat="items in shop | filter:{cat: items.cat}">
<h3>{{items.name}}</h3>
</li>
</ul>
</li>
</ul>
</div>
</div>

Related

Filter with ng-repeat

I'm trying to make a filter with the angularJs directive called ng-repeat the filter works as follows:
When you click on the checkbox filters in an array the items that have offers, I'm using a function to filter, I think there is a better way to do it without so much code.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http, $document) {
$scope.items = [
{
id: 0,
description: "Primer Item 1",
offers: [
{
id: 0,
name: "Casa"
}
]
},
{
id: 1,
description: "Segundo Item 2"
},
{
id: 2,
description: "Tercer Item 3"
},
{
id: 3,
description: "Cuarto Item 4"
},
{
id: 4,
description: "Quinto Item 5"
},
{
id: 5,
description: "Sexto Item 5",
offers: [
{
id: 1,
name: "Bodega"
}
]
},
{
id: 6,
description: "Septimo Item 6"
},
{
id: 7,
description: "Octavo Item 7"
},
{
id: 8,
description: "Noveno Item 8"
},
{
id: 9,
description: "Decimo Item 9"
}
];
$scope.filterItem = function() {
if (!$scope.itemOffer){
$scope.filterOffer = function(item) {
return item.offers && item.offers.length > 0;
};
$scope.itemOffer = true;
} else {
$scope.filterOffer = function(item) {
return item;
};
$scope.itemOffer = false;
}
};
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<input type="checkbox" name="filter" value="propertyOffer" ng-model="propertyOffer" ng-click="filterItem()">Item with offert
<div ng-repeat="item in items | filter: filterOffer track by $index">
{{ item }}
</div>
</body>
</html>
You can use ng-if with the ng-repeat directive to filter items containing offers at will :
JS CODE
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http, $document) {
$scope.offersOnly = false;
$scope.items = [
// Your items
];
});
HTML CODE
<body ng-app="myApp" ng-controller="myCtrl">
<input type="checkbox" ng-model="offersOnly" ng-true-value="true" ng-false-value="false"/>
<div ng-repeat="item in items" ng-if="!offersOnly">
{{item}}
</div>
<div ng-repeat="item in items" ng-if="offersOnly && item.offers">
{{item}}
</div>
</body>

Angular filter for words inside a phrase

I'm building an AngularJS app. I have this array:
$scope.products = [
{name: 'cake (just it!)'},
{name: 'orange cake'},
{name: 'cheesecake'}
];
then I use ng-repeat for show it.
<li ng-repeat="product in products | filter : { name : word }">
{{ $product.name }}
</li>
I want to add a filter that will search the beginning of each word inside the phrase, so if I do this:
$scope.word = 'ca';
It will return the following array:
$scope.products = [
{name: 'cake (just it!)'},
{name: 'orange cake'}
];
You could do it using a custom filter as mentioned below
var app = angular.module("sampleApp", []);
app.controller("sampleController", ["$scope",
function($scope) {
$scope.products = [{
name: 'cake (just it!)'
}, {
name: 'orange cake'
}, {
name: 'cheesecake'
}, {
name: 'cheese'
}, {
name: 'cheeseca ca'
}];
}
]);
app.filter("nameFilter", function() {
return function(names, contains) {
return names.filter(function(obj) {
var expString = '(\\w*\\s|^)' + contains + '';
var exp = new RegExp(expString, "g");
if (exp.test(obj.name))
return name;
});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<ul>
<li ng-repeat="product in products | nameFilter : 'ca' ">
{{product.name}}
</li>
</ul>
</div>
</div>

Order 1st ng-repeat by the 2nd ng-repeat value

Lets say I have two ng-repeats like
<div ng-repeat="category in categories">
{{category.name}}
<div ng-repeat="subcategory in category.subcategories">
{{subcategory.value}}
</div>
</div>
and I've would like to order the categories according to the subcategory.value?
JS:
$scope.categories = [
{
name: "1st category",
subcategories: [
{
name: "1st subcategory",
value: 1
},
{
name: "2nd subcategory",
value: 2
}
]
},
{
name: "2nd category",
subcategories: [
{
name: "3rd subcategory",
value: 5
},
{
name: "4th subcategory",
value: 6
}
]
},
{
name: "3rd category",
subcategories: [
{
name: "4th subcategory",
value: 3
},
{
name: "5th subcategory",
value: 4
}
]
}
];
Also made a Plunker:
https://plnkr.co/edit/8ugJckYRrZoyQlnBYkuU
Expected result should be:
2nd category
6
5
3rd category
4
3
1st category
2
1
Solved it by creating a customOrderBy.
HTML:
<div ng-repeat="category in categories | customOrderBy:'subcategories':'value':true">
JS:
.filter('customOrderBy', function() {
return function(items, field, value, reverse) {
var filtered = [];
angular.forEach(items, function(item) {
item.subcategories.sort(function(a, b){
return a[value]-b[value];
});
if(reverse) item.subcategories.reverse();
filtered.push(item);
});
filtered.sort(function (a, b) {
return (a[field][0][value] > b[field][0][value] ? 1 : -1);
});
if(reverse) filtered.reverse();
return filtered;
};
});
Here's the Plunker: https://plnkr.co/edit/8ugJckYRrZoyQlnBYkuU?p=preview
Below this code:
<div ng-repeat="category in categories | orderBy:'name':true">
{{category.name}}
<div ng-repeat="subcategory in category.subcategories | orderBy: 'value':true">
{{subcategory.value}}
</div>
</div>
For your expected result:
<div ng-repeat="category in categories | orderBy: '-name'">
{{category.name}}
<div ng-repeat="subcategory in category.subcategories | orderBy: '-value'">
{{subcategory.value}}
</div>
</div>
https://plnkr.co/edit/t3UVFpb3TLGAQdYMIbbd?p=preview

Angular Js Object Filter in ng-repeat

How can i filter based on object values like 1 or 2 or 3
i am trying to filter my json which looks similar to the names object
This is my code i tried to apply filter but its not working
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<ul>
<li ng-repeat="x in names ">
{{ x.name }}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.names = {
"1": {
"name": "some"
},
"2": {
"name": "values"
},
"3": {
"name": "are"
},
"4": {
"name": "there"
},
"5": {
"name": "here"
}
}
});
</script>
</body>
</html>
filter and orderBy do not work on object properties, only arrays. That being said, I think I found a solution that you will like:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<input type="text" ng-model="searchText"/>
<ul ng-init="nameArray=objArray(names)">
<li ng-repeat="x in nameArray | filter:searchText">
{{x.value.name}}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.searchText='';
$scope.names = {
"1": {
"name": "some"
},
"2": {
"name": "values"
},
"3": {
"name": "are"
},
"4": {
"name": "there"
},
"5": {
"name": "here"
}
};
$scope.objArray=function (obj) {
var result=[];
for (var key in obj) {
result.push({
key: key,
value: obj[key]
});
}
return result;
}
});
</script>
</body>
</html>
I don't think you can filter on property names. I assume these property names are some kind of IDs that you want to filter on. Then your data structure should reflect that and be like this:
$scope.names = [
{ id: "1", name: "some" },
{ id: "2", name: "values" },
{ id: "3", name: "are" },
{ id: "4", name: "there" },
{ id: "5", name: "here" }
]
Then you can filter like this:
<ul>
<li ng-repeat="x in names | filter: { id: searchId } >
{{ x.name }}
</li>
</ul>
Replace the searchId with your specific scope variable which contains the ID you are looking for.

AngularJS ng-repeat for dynamic child json array

I'm having a dynamic JSON, which contains the list of name, it also contains the children names as a subset. How can I show it in the HTML UI using angularJS ng-repeat
The Sample Dynamic JSON is
$scope.family = [
{
"name":"Siva",
"child":[
{
"name":"Suriya"
},
{
"name":"Karthick"
}
]
},
{
"name":"Kumar",
"child":[
{
"name":"Rajini"
},
{
"name":"Kamal"
},
{
"name":"Ajith"
}
]
},
{
"name":"Samer"
},
{
"name":"Mahesh"
}
];
<div ng-repeat="members in family">
<!-- How to Show it in the UI -->
</div>
Note: The JSON is generated based on Request. The Child array is
Optional and it may contain the length 'n'
You can better your answer by adding an ng-if directive, as the child is optional. Of course, it won't make any impact to you app, but it is a good way to code.
Plus, instead of adding ng-repeat on ul, it should be in li. It makes no sense in looping the ul for a single list.
Please refer the sample here.
HTML:
<div ng-app="app" ng-controller="test">
<ul ng-repeat="member in family">
<li>
{{member.name}}
<span ng-if="member.child.length > 0">
<ul>
<li ng-repeat="c in member.child">{{c.name}}</li>
</ul>
</span>
</li>
</ul>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function ($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer"
},
{
"name": "Mahesh"
}
];
});
The Corrected answer
<ul ng-repeat="member in family">
<li>{{member.name}}
<ul>
<li ng-bind="c.name" ng-repeat="c in member.child"></li>
</ul>
</li>
</ul>

Categories