simi kaur
simi kaur

Reputation: 1277

Get the nested object name

I have an object Called '$scope.filter' that looks like this:

IMAGE

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

Answers (1)

Denis Thomas
Denis Thomas

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

Related Questions