1

I have two select elements. In my first select, I load names. I want that when I select a name, the second select element's options are filtered to include only the age of the selected user.

Example:

When I select Jacob in my first select, I want my Age select to have 27 as the only option.

Plunker

<table ng-table="tableParams" show-filter="true" class="table">
    <tr ng-repeat="user in $data" ng-class="{ 'emphasis': user.money > 500 }">
        <td data-title="'Name'" filter="{ 'name': 'select' }" filter-data="names($column)">
            {{user.name}}
        </td>
        <td data-title="'Age'" filter="{ 'age': 'select' }" filter-data="ages($column)">
            {{user.age}}
        </td>
    </tr>
</table>

How can I automatically filter my second select element based on the first select element?

J Richard Snape
  • 20,116
  • 5
  • 51
  • 79
Mercer
  • 9,736
  • 30
  • 105
  • 170

3 Answers3

2

Here is a working demo: http://plnkr.co/edit/3tLixkFKYgpXfx04PbaD?p=preview

One approach is to create custom templates for your filters. This way you have full control over the arrays that the filters are bound to, and you can easily attach change events:

<script type="text/ng-template" id="ng-table/filters/name.html">
  <select ng-options="name.id as name.title for name in nameOptions" 
          ng-model="params.filter()['name']" 
          ng-change="ages(column, params.filter()['name'])">
  </select>
</script>
<script type="text/ng-template" id="ng-table/filters/age.html">
  <select ng-options="age.id as age.title for age in ageOptions" 
          ng-model="params.filter()['age']"></select>
</script>

Then, use the templates in your ng-table markup:

<td data-title="'Name'" filter="{ 'name': 'name' }" filter-data="names($column)">
  {{user.name}}
</td>
<td data-title="'Age'" filter="{ 'age': 'age' }" filter-data="ages($column)">
  {{user.age}}
</td>

You can populate the option arrays in your existing names and ages functions:

$scope.names = function(column) {
    ...

    $scope.nameOptions = names;

    ...
};


$scope.ages = function(column, name) {      
  var def = $q.defer(),
      arr = [],
      ages = [];
  angular.forEach(data, function(item) {
      if (inArray(item.age, arr) === -1) {
          if (angular.isUndefined(name) || item.name === name) {
            arr.push(item.age);
            ages.push({
                'id': item.age,
                'title': item.age
            });
          }
      }
  });

  $scope.ageOptions = ages;

  def.resolve(ages);
  return def;
};
j.wittwer
  • 9,497
  • 3
  • 30
  • 32
1

I tried to solve this. Let me know if it is same what you need.
DEMO: Fiddle

<body ng-app ng-controller="AppCtrl">
<select ng-model="selectedName" ng-options="item as item for item in name">
    <option value="">Select Name</option>
</select>
<pre>selectedItem: {{selectedName | json}}</pre>

<select ng-model="selectedage" ng-options="item as item for item in age">
    <option ng-if="!selectedage" value="">Select age</option>
</select>
<pre>selectedItem: {{selectedage | json}}</pre>
</body>

JS:

function AppCtrl($scope) {

$scope.name = ["Ved", "James", "Doe","Prakash" ];
var age = {Ved :["25"],James :["26"],Doe:["27"],Prakash:["28"]};
    $scope.$watch('selectedName', function(newValue, oldValue) {
      if ( newValue) {
            var name = $scope.selectedName;
  $scope.age = age[name];
    }
  });
}
Ved
  • 11,837
  • 5
  • 42
  • 60
1

Here is a demo http://plnkr.co/edit/5fvtiept6M6VpAmo8a5f?p=preview So what you can do is,you can use your first select ng-model object which is as a filter to the second dropdown.

or

user first select binded object which is "formData.name" in here in example, in second dropdown.

    <!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@*" data-semver="1.2.0-rc3-nonmin" src="http://code.angularjs.org/1.2.0-rc.3/angular.js"></script>
    <script data-require="ng-table@*" data-semver="0.3.0" src="http://bazalt-cms.com/assets/ng-table/0.3.0/ng-table.js"></script>

    <link data-require="ng-table@*" data-semver="0.3.0" rel="stylesheet" href="http://bazalt-cms.com/assets/ng-table/0.3.0/ng-table.css" />
    <link data-require="bootstrap-css@*" data-semver="3.0.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />

    <link rel="stylesheet" href="style.css" />
    <script src="app.js"></script>
  </head>

<body ng-app="main" ng-controller="DemoCtrl">
    <table ng-table="tableParams" show-filter="true" class="table">
      <tr>
            <td data-title="'Name'">
              <select name="name" 
                data-ng-model="formData.name"
                ng-options="user.name for user in $data" 
                ng-change="changeAge(formData.name)"
                required >
                    <option value="">Select</option>
                </select>
            </td>
            <td data-title="'Age'">
                <select name="age" data-ng-model="formData.age"
                >
                  <option value="">Select</option>
                  <option value="">{{formData.name.age}}</option>
                </select>
            </td>
            </tr>
            <tr ng-repeat="user in $data|filter:formData.name">
              <td>
                {{user.name}}
              </td>
              <td>
                {{user.age}}
              </td>
            </tr>
    </table>    
</body>
</html>
Ritt
  • 3,181
  • 3
  • 22
  • 51
  • ok for you're reponse but why in the select `name` there is duplicate entries .? – Mercer Mar 27 '15 at 09:10
  • okay dats becuz you have same name object for 3 or 4 i guess.. u can apply filter on them too based on their money property.. le me knoe if u want fiddle for that.. thank you :) – Ritt Mar 27 '15 at 19:06
  • It’s posible to have a Fiddle please – Mercer Mar 28 '15 at 18:16
  • http://plnkr.co/edit/QDU34o9FFnGitiKC8UVm?p=preview so i have created this plunker which will filter your object array based on the condition in filterData() function and the value you give in Filter by money search box. – Ritt Apr 06 '15 at 09:49