How to define a custom filter in AngularJS - angularjs

I'm fairly new to AngularJS and still trying to grasp the basics. I'm trying to define a custom filter for my select dropdown. I have the logic but I don't know where to exactly implement it, and what I should modify on my html.
html
<ui-select multiple ng-model="criteria.regionIds" theme="select2" style="width: 100%;border:0!important;">
<ui-select-match placeholder="Select regions...">{{$item.label}}</ui-select-match>
<ui-select-choices repeat="region.code as region in regions | filter:$select.search">
<div ng-bind-html="region.label | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
I want to replace filter by a custom filter
js logic
app.filter('myCustomeFilter', function() {
return function(items, props) {
var out = [];
if (angular.isArray(items)) {
items.forEach(function(item) {
var keys = Object.keys(props);
var prop = keys[0];
var text = props[prop].toLowerCase();
if (item[prop].toString().toLowerCase().indexOf(text) === 0) {
out.push(item);
}
});
} else {
out = items;
}
return out;
};
});
how do I implement this js logic into my controller?
function summaryReportsResultsCtrl($scope, $state, $filter, $modal, growl, summaryreportService, paginationConfig, currentUser) {
// inside the controller
}

Can you be more elaborate on your query. What is the format of the data that you are filtering?
And are you using some custom directives (ui-select-match, ui-select-choices) on your html??
If you have an array of regions data like below and if you want to filter that data based on some user input, then u can use the predefined "filter" Filter and pass the "SearchText" to that filter in the html file.
<input type="text" placeholder="Select Regions..." ng-model="searchText"/>
<br/>
<select ng-model="selectedRegions" ng-options="eachRegion.code for eachRegion in regions | filter: searchText" multiple>
</select>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.searchText = "Metro";
$scope.regions = [
{code: 011, label: "Delhi", type: "Metro"},
{code: 022, label: "Mumbai", type: "Metro"},
{code: 033, label: "Kolkatta", type: "Metro"},
{code: 044, label: "Chennai", type: "Metro"},
{code: 080, label: "Bangalore", type: "City"},
{code: 079, label: "Ahmedabad", type: "City"},
{code: 040, label: "Hyderabad", type: "City"},
{code: 0612, label: "Patna", type: "City"}
];

Related

Filter and auto selected dropdown angularjs

I am new to angularjs and still learning things. I have this code below. What I am aiming here is to load the data into the dropdown from the database. For example the data from the database is New Construction I want to load all data from LoadDropdown function and the New Construction is selected as default.
HTML
<select name="ScopeofWork" class="form-control" ng-model="drpScopeWork" ng-options="SoW as SoW.label for SoW in ScopeOfWorkList">
<option value="" selected hidden></option>
</select>
JS
function LoadDropdown() {
$scope.ScopeOfWorkList = [{ value: 'New Construction', label: 'New Construction' },
{ value: 'Erection', label: 'Erection' },
{ value: 'Addition', label: 'Addition' },
{ value: 'Renovation', label: 'Renovation' },
{ value: 'Repair', label: 'Repair' }];
}
fnLoadDropdown();
function fnLoadDropdown() {
var url = '/AccessoryGroundPreparation/LoadScopeofWork';
$http({
method: "post",
url: url,
//data: { "ScopeOfWork": ScopeOfWork, "projectID": projectID }
}).then(function (res) {
var data = res.data;
if (data.data == null)
LoadDropdown();
else {
// $scope.drpScopeWork = $scope.ScopeOfWorkList[0];
$scope.drpScopeWork = data.data;
}
});
}
Use ng-init to assign a value to your model drpScopeWork form 0 index of your array like ng-init="drpScopeWork = ScopeOfWorkList[0].value"
Here is working code snippet:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.ScopeOfWorkList = [{
value: 'New Construction',
label: 'New Construction'
},
{
value: 'Erection',
label: 'Erection'
},
{
value: 'Addition',
label: 'Addition'
},
{
value: 'Renovation',
label: 'Renovation'
},
{
value: 'Repair',
label: 'Repair'
}
];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div>
<select name="ScopeofWork" class="form-control" ng-model="drpScopeWork" ng-options="SoW.value as SoW.label for SoW in ScopeOfWorkList" ng-init="drpScopeWork = ScopeOfWorkList[0].value">
</select>
</div>
</div>

Angular ui-select default selected value

I am using ui-select in Angular to have a select box in my page. I can search by typing and when I select value, the name will be displayed [Which is fine], and the ng-model has the selected values id[which is also correct]
Now I try to load view of a already saved record. I want the selected box to pre filled.
But it does not!
This is my HTML
<ui-select ng-model="vm.product.category">
<ui-select-match placeholder="Type to search">{{ (vm.categories | filter : { id : vm.product.category } : true)[0].name }}</ui-select-match>
<ui-select-choices repeat="category.id as category in (vm.categories | filter: {name: $select.search})">
<span ng-bind-html="category.name | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
Here is my controller,
app.controller('productDetailsController', [
'$scope', 'Product',
function ($scope, Product) {
var vm = this;
vm.product = {};
vm.categories = [{name: "General", id: "1"}, {name: "Product", id: "2"}]
Product.get({id: id}).$promise.then(function (data) {
vm.product = data.data;
}, function (error) {
alert(error);
});
}
]);
When I load record from database my model () has the ID. but I want the name to be displayed to the user.
How can I do this? WHat am I doing wrong here?
Thanks in advance!
var app = angular.module('app', ['ui.select']);
app.service('myservice', ['$timeout', '$q',
function($timeout, $q) {
this.getData = function() {
var defer = $q.defer();
//Here, $timeout corresponds to $http
$timeout(function() {
defer.resolve({
'data': {
product_name: "Galaxy S3",
product_description: "Galaxy S3 desc",
category: 1,
is_active: true
}
});
}, 1000);
return defer.promise;
}
}
]);
app.controller('productDetailsController', ['$scope', 'myservice',
function($scope, myservice) {
var vm = this;
vm.product = {};
vm.categories = [{
name: "General",
id: "1"
}, {
name: "Product",
id: "2"
}];
myservice.getData().then(function(data) {
vm.product = data.data;
});
}
]);
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.11.2/select.css" rel="stylesheet" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.11.2/select.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-sanitize.js"></script>
<div ng-app="app" ng-controller="productDetailsController as vm">
<ui-select ng-model="vm.product.category">
<ui-select-match placeholder="Type to search">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="category.id as category in vm.categories | filter: {name: $select.search}">
<div ng-bind="category.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>

selected option is not getting displayed Angularjs dropdownlist

When I am using an object where I have property which has selectedOptions it is not getting displayed in the dropdownlist. However, when I put in scope and select from the object then it displayed. Anyone has any idea why the first one is not working. Here is the plunker link.
http://plnkr.co/edit/XLuXmAmh4F9OobyJhBCW?p=preview
var app = angular.module('angularjs-starter', []);
var model = {
options : [
{ id: 1, name: 'foo' },
{ id: 2, name: 'bar' },
{ id: 3, name: 'blah' }],
selectedOption : { id: 1, name: 'foo' }
}
app.value('vm',model);
app.controller('MainCtrl', function($scope,vm) {
$scope.vm =vm;
$scope.items = [
{ id: 1, name: 'foo' },
{ id: 2, name: 'bar' },
{ id: 3, name: 'blah' }];
$scope.selectedItem = $scope.items[1];
});
<body ng-controller="MainCtrl">
<h1>Select something below</h1>
<select id="s1" ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
<h3>The selected item:</h3>
<pre>{{selectedItem | json}}</pre>
<h3>The inner html of the select:</h3>
<pre id="options" class="prettify html"></pre>
<select data-ng-options="o.name for o in vm.options" data-ng-model="vm.selectedOption"><option value="">Select one</option></select>
<pre>{{vm.selectedOption | json}}</pre>
</body>
Angular uses strict comparison (===) to evaluate if given option is to be selected. It will only if the value of selectedItem is the same as the option's one. And in JavaScript, if you create two objects of the same structure and try to strictly compare it, they are not the same, i.e.:
{a: 1} !== {a: 1}
In the second example you're keeping the reference to the original object insted, so it would be like doing this:
var obj1 = {a: 1};
var obj2 = obj1;
obj1 === obj2;

Angularjs and UI-Select: how to select an option from code

in angularjs i have a ui-select:
<ui-select ng-model="itemSelected.selected" theme="selectize" ng-disabled="disabled">
<ui-select-match placeholder="Select an item...">{{$select.selected.Name}}</ui-select-match>
<ui-select-choices repeat="item in itemsList">
<span ng-bind-html="item.Name"></span>
</ui-select-choices>
</ui-select>
How can i select an item from code when i load the page?
When i load the page in the controller i get the $scope.itemsList: how can i select a specific item from the controller?
Thanks
You can set that on controller load itself
Markup
<body ng-controller="DemoCtrl">
<p>Selected: {{item.selected}}</p>
<ui-select ng-model="item.selected" theme="select2" ng-disabled="disabled" style="min-width: 300px;">
<ui-select-match placeholder="Select a item in the list">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="item in items | propsFilter: {name: $select.search, age: $select.search}">
<div ng-bind-html="item.Code | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</body>
Code
app.controller('DemoCtrl', function($scope, $http) {
$scope.disabled = undefined;
$scope.clear = function() {
$scope.item.selected = undefined;
};
$scope.item = {};
$scope.items = [
{ name: 'Item1', Code: 'Code1', },
{ name: 'Item2', Code: 'Code3'},
{ name: 'Item3', Code: 'Code4'},
{ name: 'Item4', Code: 'Code4' },
{ name: 'Item5', Code: 'Code5' },
];
$scope.item.selected = $scope.items[0] //here you can set the item selected
});
Working Plunkr
The plunkr by #Pankaj Parkar was no longer working for the intended usage so I forked it and got it working here:
http://plnkr.co/edit/Y6cdgJQ3YPq7Ncb3bT4A?p=preview
The key changes involved actually setting the selected item in the controller:
$scope.address = {};
$scope.refreshAddresses = function(address) {
var params = {address: address, sensor: false};
return $http.get(
'http://maps.googleapis.com/maps/api/geocode/json',
{params: params}
).then(function(response) {
$scope.addresses = response.data.results
$scope.address.selected = $scope.addresses[0];
$scope.$apply();
});
};
$scope.refreshAddresses('New York, NY');
The key addition is $scope.address.selected = $scope.addresses[0]; and $scope.refreshAddresses('New York, NY'); to get it to go.
I also updated the other selects to prepopulate, as well.

exact filter in angular

In Angular, is there a way to modify the filter such that it only returns exact matches?
Example:
var words = [
{ title: "ball" },
{ title: "wall" },
{ title: "all" },
{ title: "alloy" }
];
var wordsFiltered = filter('filter')
(
words,
{
'title': 'all'
}
);
The above will match 'ball', 'wall', 'all' and 'alloy'. But I would like it to only match 'all'. Any way to change it?
UPDATE
Starting from AngularJS v.1.1.3 the exact filtering is provided natively:
Find words that exactly match title:
<input ng-model="match.title" />
<br>
and exactly match type:
<input ng-model="match.type" />
<hr>
<table>
<tr ng-repeat="word in words | filter:match:true">
<td>{{word.title}}</td>
</tr>
</table>
Plunker
Your question implies that you would want to match against multiple object properties so here's a filter that does that:
app.controller('AppController',
[
'$scope',
function($scope) {
$scope.match = {};
$scope.words = [
{ title: "ball", type: 'object' },
{ title: "wall", type: 'object' },
{ title: "all", type: 'word' },
{ title: "alloy", type: 'material' }
];
}
]
);
app.filter('exact', function(){
return function(items, match){
var matching = [], matches, falsely = true;
// Return the items unchanged if all filtering attributes are falsy
angular.forEach(match, function(value, key){
falsely = falsely && !value;
});
if(falsely){
return items;
}
angular.forEach(items, function(item){ // e.g. { title: "ball" }
matches = true;
angular.forEach(match, function(value, key){ // e.g. 'all', 'title'
if(!!value){ // do not compare if value is empty
matches = matches && (item[key] === value);
}
});
if(matches){
matching.push(item);
}
});
return matching;
}
});
<body ng-controller="AppController">
Find words that exactly match title:
<input ng-model="match.title" />
<br>
and exactly match type:
<input ng-model="match.type" />
<hr>
<table>
<tr ng-repeat="word in words | exact:match">
<td>{{word.title}}</td>
</tr>
</table>
</body>
PLUNKER
Try this :
var words = [
{ title: "ball" },
{ title: "wall" },
{ title: "all" },
{ title: "alloy" }
];
var wordsFiltered = filter('filter')
(
words,
{
'title': 'all'
},
true
);
You can use Regex to achieve a simple implementation:
<input ng-model="query" />
<tr ng-repeat="word in words | filter: myFilter">
In the controller:
$scope.myFilter = function (word) {
if ($scope.query === '') return true;
var reg = RegExp("^" + $scope.query + "$");
return reg.test(word.title);
};
I would create a new filter. Is this what you want?
HTML
<div ng-controller="MyCtrl">
{{words | exactMatch:'all'}} !
</div>
JavaScript
var myApp = angular.module('myApp',[]);
myApp.filter('exactMatch', function() {
return function(words, pattern) {
var result = [];
words.forEach(function (word) {
if (word.title === pattern) {
result.push(word);
}
});
return result;
}
});
function MyCtrl($scope) {
$scope.words = [
{title: "ball", other: 1},
{title: "wall", other: 2},
{title: "all", other: 3},
{title: "alloy", other: 4},
{title: "all", other: 5},
];
}
JsFiddle: jsfiddle
More information about custom filters: filters, creating custom filters and using filters
If you want use filter in Javascript instead of html you should look here: jsfiddle
I created my own filter.
<select
ng-model="selection.neType"
ng-options="option.NE_TYPE_ID as option.NAME for option in networkElementTypes">
<option value="">Todos</option>
</select>
<select
ng-model="selection.neTypeVendor"
ng-options="option.VENDOR_TYPE_ID as option.NAME for option in networkElementTypeVendors | exactMatch: {FK_NE_TYPE_ID: selection.neType}">
<option value="">All</option>
</select>
app.filter('exactMatch', function() {
return function(elements, pattern) {
var result = [];
var fieldSearch = Object.keys(pattern)[0];
elements.forEach(function (element) {
if (element[fieldSearch] == pattern[fieldSearch]) {
result.push(element);
}
});
return result;
}
});
angular-filter is a useful library of filters.
One of their filters is the where filter that does an exact match.

Resources