Reputation: 1277
I have an object Called '$scope.filter' that looks like this:
How do I get the name of the nested object i.e key in this case? preferably using the directive without involving controller but would do if not possible without it.
<ul>
<span ng-repeat="x in filter">
<span ng-repeat="(key,val) in x">
<span ng-if="x[key]">/*get values of checked checkboxes here HOW ?*/ </span>
</span>
</span>
</ul>
Here is where I am creating checkboxes:
<ul ng-repeat="(key,value) in filtered=(properties | filter: filterByCategory | groupBy: 'name') ">
<li>Group name: <strong>{{ key }}</strong></li>
<div ng-repeat="prop in value">
<label>
<input type="checkbox" ng-model="filter[key][$index]">
<span>{{prop.Property}}</span>
</label>
</div>
</ul>
Controller code:
.controller('dataController', function($scope, $filter)
{
$scope.properties = [
{name: 'Weight', Property: 'quintal', value:'50'},
{ name: 'Quantity', Property: 'Litre' , value:'40'},
{ name: 'Quantity', Property: 'ml' , value:'10'},
{ name: 'Height', Property: 'metres' , value:'10' },
{ name: 'Height', Property: 'cm' , value:'20'},
{name: 'Height', Property: 'inches' , value:'30'},
{ name: 'Size', Property: 'Fat' , value:'28' },
{ name: 'Size',Property: 'Slim', value:'48' },
{ name: 'Feature', Property: 'Sharp' , value:'9'},
{ name: 'Feature', Property: 'Bland', value:'2' },
{name: 'Weight', Property: 'KG', value:'10'},
{ name: 'Weight', Property: 'grams', value:'20' },
{ name: 'Weight', Property: 'ton' , value:'30'}
];
$scope.filter = {};
$scope.filterByCategory = function (prop) {
// console.log($scope.filter);
angular.forEach($scope.filter, function(item){
for(key in item)
{
if(item[key])
return;
else
console.log("show");
$scope.filter={};
}
});
return $scope.filter[prop.name] || noFilter($scope.filter) ;
};
Upvotes: 1
Views: 3884
Reputation: 1022
I modified your structure a bit since your format is some what complicated to work with when it comes to binding:
$scope.filter = [
{
id: 1,
groupName: 'Feature',
options: [
{id: 1, selected: false },
{id: 2, selected: false }
],
},
{
id: 2,
groupName: 'Weight',
options: [
{id: 4, selected: false },
{id: 5, selected: false }
],
},
];
Then you could use a function in the template to get the name of each option like this:
$scope.getName = function(group, option) {
var options = [];
for (var i = 0; i < $scope.properties.length; i++){
if ($scope.properties[i].name === group.groupName){
options.push($scope.properties[i].Property);
}
};
return options[group.options.indexOf(option)];
};
If you want to get all selected options from a nested list you could use a custom filter which will return the required data flattened in one list. There you could include any custom logic required to produce desired result.
Code would be like this example:
app.filter('groupFilter', function() {
return function(filterList, properties) {
var selectedOptions = [];
// Iterate all groups
for (var i = 0; i < filterList.length; i++){
var group = filterList[i];
// Get names for properties
var optionNames = [];
for (var k = 0; k < properties.length; k++){
if (properties[k].name === group.groupName){
optionNames.push(properties[k].Property);
}
};
// Find all selected options in group
for (var j = 0; j < group.options.length; j++){
var option = group.options[j];
if (option.selected){
selectedOptions.push(group.groupName + ' - ' + optionNames[j]);
}
}
}
return selectedOptions;
}
});
And the coresponding html:
<li ng-repeat="option in filter | groupFilter:properties">{{option}}</li>
You can see both in the sample below:
var app = angular.module('app', []);
app.filter('groupFilter', function() {
return function(filterList, properties) {
var selectedOptions = [];
// Iterate all groups
for (var i = 0; i < filterList.length; i++){
var group = filterList[i];
// Get names for properties
var optionNames = [];
for (var k = 0; k < properties.length; k++){
if (properties[k].name === group.groupName){
optionNames.push(properties[k].Property);
}
};
// Find all selected options in group
for (var j = 0; j < group.options.length; j++){
var option = group.options[j];
if (option.selected){
selectedOptions.push(group.groupName + ' - ' + optionNames[j]);
}
}
}
return selectedOptions;
}
});
app.controller('ctrl',function($scope) {
$scope.filter = [
{
id: 1,
groupName: 'Feature',
options: [
{id: 1, selected: false },
{id: 2, selected: false }
],
},
{
id: 2,
groupName: 'Weight',
options: [
{id: 4, selected: false },
{id: 5, selected: false }
],
},
];
$scope.getName = function(group, option) {
var options = [];
for (var i = 0; i < $scope.properties.length; i++){
if ($scope.properties[i].name === group.groupName){
options.push($scope.properties[i].Property);
}
};
return options[group.options.indexOf(option)];
};
$scope.properties = [
{ name: 'Weight', Property: 'quintal', value:'50'},
{ name: 'Quantity', Property: 'Litre' , value:'40'},
{ name: 'Quantity', Property: 'ml' , value:'10'},
{ name: 'Height', Property: 'metres' , value:'10' },
{ name: 'Height', Property: 'cm' , value:'20'},
{ name: 'Height', Property: 'inches' , value:'30'},
{ name: 'Size', Property: 'Fat' , value:'28' },
{ name: 'Size',Property: 'Slim', value:'48' },
{ name: 'Feature', Property: 'Sharp' , value:'9'},
{ name: 'Feature', Property: 'Bland', value:'2' },
{ name: 'Weight', Property: 'KG', value:'10'},
{ name: 'Weight', Property: 'grams', value:'20' },
{ name: 'Weight', Property: 'ton' , value:'30'}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
Filter:
<ul>
<li ng-repeat="grp in filter track by grp.id">
{{grp.groupName}}
<ul>
<li ng-repeat="option in grp.options track by option.id">
<label for="check{{option.id}}">
<input type="checkbox" ng-model="option.selected" id=check{{option.id}}>
{{getName(grp, option)}}
</label>
</li>
</ul>
Selected:
<span ng-repeat="selectedOption in grp.options | filter:{selected:true} track by selectedOption.id">
{{getName(grp, selectedOption)}}
</span>
<li>
</ul>
<label>
Selected:
<ul>
<li ng-repeat="option in filter | groupFilter:properties">{{option}}</li>
</ul>
</label>
</div>
Upvotes: 2