I'm trying to create a filter which will filter out the results in the table based on the value selected in the dropdown. Currently, it works for all the dropdowns except the 'type'.
The 'type' dropdown has been created using the unique properties from an array of objects. So, now, it contains two values 'Internal' and 'External'.
Based on the value I select, it should show me only the filtered results in the table. But as of now, it just shows blank.
How do I fix this?
Here's the code:
var app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope', '$filter', function($scope, $filter) {
$scope.loc = {
Sydney: 4,
Toronto: 7,
London: 3,
Berlin: 7
};
$scope.country = ['Australia', 'India', 'Germany', 'China', 'Canada', 'United Kingdom'];
$scope.items = [{
name: 'ABC',
type: 'INTERNAL',
countryName: 'Germany',
city: 'Berlin'
}, {
name: 'BCD',
type: 'EXTERNAL',
countryName: 'India',
city: 'Bangalore'
}, {
name: 'CDE',
type: 'INTERNAL',
countryName: 'Germany',
city: 'Berlin'
}, {
name: 'ABC',
type: 'EXTERNAL',
countryName: 'Australia',
city: 'Sydney'
}, {
name: 'DEF',
type: 'INTERNAL',
countryName: 'China',
city: 'Shanghai'
}, {
name: 'CDE',
type: 'EXTERNAL',
countryName: 'Germany',
city: 'Berlin'
}, {
name: 'BCD',
type: 'INTERNAL',
countryName: 'Australia',
city: 'Sydney'
}, {
name: 'ABC',
type: 'EXTERNAL',
countryName: 'United Kingdom',
city: 'London'
}, {
name: 'ABC',
type: 'INTERNAL',
countryName: 'China',
city: 'Shanghai'
}, {
name: 'DEF',
type: 'EXTERNAL',
countryName: 'Canada',
city: 'Toronto'
}, {
name: 'DEF',
type: 'INTERNAL',
countryName: 'India',
city: 'Bangalore'
}, {
name: 'BCD',
type: 'EXTERNAL',
countryName: 'Germany',
city: 'Berlin'
}, {
name: 'ABC',
type: 'INTERNAL',
countryName: 'Canada',
city: 'Toronto'
}];
$scope.changeFilter = function() {
$scope.my.countryName = $scope.my.countryName || undefined;
$scope.my.city = $scope.my.city || undefined;
$scope.my.type = $scope.my.type || undefined;
};
}]);
app.filter('unique', function() {
return function(input, key) {
var unique = {};
var uniqueList = [];
for(var i = 0; i < input.length; i++){
if(typeof unique[input[i][key]] == "undefined"){
unique[input[i][key]] = "";
uniqueList.push(input[i]);
}
}
return uniqueList;
};
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div class="container">
<div ng-app="myApp" ng-controller="myCtrl">
<div class="row">
<div class="col-md-3">
<label>Search Keyword:</label>
<input type="text" class="form-control" ng-model="my.$"/>
</div>
<div class="col-md-3">
<label>Country:</label>
<select class="form-control" ng-model="my.countryName" ng-options="ctry for ctry in country" ng-change="changeFilter()">
<option value="">Select a country</option>
</select>
</div>
<div class="col-md-3">
<label>City</label>
<select class="form-control" ng-model="my.city" ng-options="key as key for (key, value) in loc" ng-change="changeFilter()">
<option value="">Select a city</option>
</select>
</div>
<div class="col-md-3">
<label>Type:</label>
<select class="form-control" ng-model="my.type" ng-options="item.type for item in items | unique:'type'" ng-change="changeFilter()">
<option value="">Select a type</option>
</select>
</div>
</div>
<hr />
<div class="row">
<table class="table table-bordered">
<tr>
<th>Name</th>
<th>Country</th>
<th>City</th>
</tr>
<tr ng-repeat="item in items | filter: my">
<td>{{item.name}}</td>
<td>{{item.countryName}}</td>
<td>{{item.city}}</td>
</tr>
</table>
</div>
</div>
</div>
Actually your approach is correct. Just give 'item.type as item.type' also.
<select class="form-control" ng-model="my.type" ng-options="item.type
as item.type for item in items | unique:'type'" ng-
change="changeFilter()">
<option value="">Select a type</option>
</select>
This works. Previously, when u select "my.type" on selection of one value, ie is "INTERNAL/EX.." one entire item is selected. But we need only one value.