Angular custom search filter - angularjs

I need to create a custom search filter for this scope. I tried the default filter function , doesn't works, Because I displayed status as string in HTML and it is not filtered the way I want it. If I type Normal in the textbox, nothing happens because the data is 0, 1 and 2. And if I search the purchase time which is in 2016/05/16 format cannot search also.
$scope.orderHistory = {[
"purchaseTime": 1437536718345,
"status": 1,
]};
app.filter('filterSearch', function () {
//what to do here??
});
<input type="text" ng-model="searchReview">
<div dir-paginate="order in orderHistory|filterSearch:searchReview">
<ul>
<li><p class="table-data2-h">{{ order.purchaseTime | date : 'yyyy/MM/dd'}} </p></li>
<li>
<span ng-if="order.status == 0 ">Stable</span>
<span ng-if="order.status == 1 ">Normal</span>
<span ng-if="order.status == 2 ">Serious</span>
</li>
</div>

At first, I saw some mistakes on your code, you can compare it below.
I'd suggest you to create a simple function to parse your properties accordingly your requirements only on initilization (which one for sure will be better to parse everytime when than custom filter is called), then you can use the normal filter.
See it working:
(function() {
'use strict';
angular
.module('app', [])
.constant('STATUS', {
0: 'Stable',
1: 'Normal',
2: 'Serious'
})
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', 'STATUS'];
function MainCtrl($scope, STATUS) {
$scope.orderHistory = [
{
"purchaseTime": 1437536718345,
"status": 1
},
{
"purchaseTime": 1431236718345,
"status": 0
},
{
"purchaseTime": 1099536718345,
"status": 2
},
{
"purchaseTime": 1439744718345,
"status": 1
}
];
function parseProperties() {
$scope.orderHistory.map(function(order) {
// You can do it with switch statement
// switch (order.status) {
// case 0:
// order.status = 'Stable';
// break;
// case 1:
// order.status = 'Normal';
// break;
// case 2:
// order.status = 'Serious';
// break;
// }
// or using a constant that you can define above
order.status = STATUS[order.status];
order.purchaseTime = new Date(order.purchaseTime).toLocaleDateString();
return order;
});
}
parseProperties();
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<input type="text" placeholder="Search..." ng-model="searchReview">
<div ng-repeat="order in orderHistory | filter: searchReview">
<ul>
<li>
<p class="table-data2-h" ng-bind="order.purchaseTime"></p>
</li>
<li ng-bind="order.status"></li>
</ul>
</div>
</body>
</html>
I hope it helps

Related

Using ng-repeat in order to iterate over object properties and ordering by value instead of key with ng 1.3

I am in reference to the angular documentation about ngRepeat and iterating over object properties which states:
<div ng-repeat="(key, value) in myObj"> ... </div>
You need to be aware that the JavaScript specification does not define
the order of keys returned for an object. (To mitigate this in Angular
1.3 the ngRepeat directive used to sort the keys alphabetically.)
Say I have the following object:
var myObj = {FOO: 0, BAR: 1};
and want it to be ordered by value (i.e. 0 & 1) instead of keys. How can this be achieved with angular? (I use angular 1.3 by the way).
I have tried:
ng-repeat="(key, value) in myObj | orderBy:value"
But it does not work...
Can anyone please help?
Just as with filter, orderBy works with arrays only. One simple solution is to use a function that returns an array from an object:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<input type="text" ng-model="searchText"/>
<ul ng-init="nameArray=objArray(names)">
<li ng-repeat="x in nameArray | filter:searchText | orderBy: 'value.name'">
{{x.value.name}}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.searchText='';
$scope.names = {
"1": {
"name": "some"
},
"2": {
"name": "values"
},
"3": {
"name": "are"
},
"4": {
"name": "there"
},
"5": {
"name": "here"
}
};
$scope.objArray=function (obj) {
var result=[];
for (var key in obj) {
result.push({
key: key,
value: obj[key]
});
}
return result;
}
});
</script>
</body>
</html>
I believe the best and elegant solution is to make a filter that changes your object into an array. Therefore you can reuse it thought all your project in your template without coding any js.
Here is what the filter would look like:
(function () {
'use strict';
angular.module('app').filter('toArray', toArray);
toArray.$inject = [];
function toArray() {
return toArrayFilter;
function toArrayFilter(input) {
if (angular.isArray(input)) return input;
var list = [];
angular.forEach(input, iterateProperty, list);
return list;
function iterateProperty(elt, key) {
this.push({ key: key, value: elt });
}
}
}
})();
and here is how you would use it in your html template:
<div ng-repeat="element in myObject | toArray | orderBy:value">
{{element.key}}:
<pre>{{element.value | json}}</pre>
</div>

Searching a map and retrieving key if matching -angular js

Angular-JS
Searching a map and retrieving key if matching with the user given input key
my map luks like this
var myMap=
{
k:1000,
l:100000,
m:1000000,
c:10000000
};
If user input is "l" , i want to search the map and retrieve l along with value "100000"
and do some further operation
As myMap is an object (aka associative array, aka hash) you can access a value using the
[] operator.
angular.module('MyModule', [])
.controller('MyController', function($scope) {
$scope.myMap = { k:1000, l:100000, m:1000000, c:10000000 };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='MyModule' ng-controller='MyController'>
<input type='text' ng-model='myMapKey' />
<p>myMap value = {{myMap[myMapKey]}}</p>
</div>
To extend the answer from Gruff Bunny, you can also do the following to search for the key-value pair and do your calculation inside the controller and get the result as an output.
angular.module('MyModule', [])
.controller('MyController', function($scope) {
$scope.myMap = { k:1000, l:100000, m:1000000, c:10000000 };
$scope.chkIt = function(myIns){
var myVal = $scope.myMap[myIns];
if(myVal){
//do your calculation here
$scope.myResult = 'Calculation Done | Key: '+myIns+' | Value: '+myVal;
}else{
$scope.myResult = 'No Match for key: '+myIns;
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='MyModule' ng-controller='MyController'>
<input type='text' ng-change="chkIt(myMapKey)" ng-model='myMapKey' />
<p>myMap value = {{myResult}}</p>
</div>

Cannot read property 'replace' of undefined in angularJS?

I am using emoji filter, I am getting error that "Cannot read property 'replace' of undefined".
Errro is:
TypeError: Cannot read property 'replace' of undefined
at g.<anonymous> (file:///C:/xampp/htdocs/web_UI/js/emoji.min.js:1:10531)
at e (file:///C:/xampp/htdocs/web_UI/js/angular.min.js:155:305)
at Ia.| (file:///C:/xampp/htdocs/web_UI/js/angular.min.js:143:248)
at Object.A.constant [as get] (file:///C:/xampp/htdocs/web_UI/js/angular.min.js:154:212)
at g.$digest (file:///C:/xampp/htdocs/web_UI/js/angular.min.js:98:307)
at g.$apply (file:///C:/xampp/htdocs/web_UI/js/angular.min.js:101:157)
at HTMLAnchorElement.<anonymous> (file:///C:/xampp/htdocs/web_UI/js/angular.min.js:177:65)
at HTMLAnchorElement.m.event.dispatch (file:///C:/xampp/htdocs/web_UI/js/jquery.min.js:3:8436)
at HTMLAnchorElement.r.handle (file:///C:/xampp/htdocs/web_UI/js/jquery.min.js:3:5146)
Html code:
<div class="row" ng-repeat="n in q.answers" ng-bind-html = " n | emoji">
json response:
{
"data":[
{
"id":10,
"title":"what is internet?",
"userID":2,
"question":"what is internet?",
"viewed":0,
"votes":5,
"answers":[
{"id":15,
"questionID":10,
"userID":2,
"answer":"search on google ....:)",
"correct":"0",
"votes":7
},
{
"id":47,
"questionID":10,
"userID":2,
"answer":"test :smiley:",
"correct":"0","votes":0,
}
]}
]
}
js function:
QAApp.controller('askbyctrl', function ($scope, $http){
$http.get(server + 'api').success(function(data) {
/*console.log(data);*/
$scope.qa = data;
});
$scope.select = function(item) {
/*console.log(item);*/
$scope.selected = item
}
$scope.isSelected = function(item) {
return $scope.selected == item
}
});
then in html for answer use ng-repeat="q in qa.data" and to display answer use n in q.answers"
Please tell me how can I solve it?
Plunker link
This is the working code...
angular.module("app", ['emoji', 'ngSanitize']).controller("AppCtrl", function ($scope) {
$scope.messages = [
"Animals: :dog: :cat: :snake:",
"People: :smile: :confused: :angry:",
"Places: :house: :school: :hotel:"
];
});
<body ng-app="app" ng-controller="AppCtrl">
<ul>
<li ng-repeat="message in messages" ng-bind-html="message | emoji"></li>
</ul>
</body>
You need to apply the emoji filter to a string, however your n in q.answers is looping through a list of objects (not strings). You need to change your HTML to this:
<div class="row" ng-repeat="n in q.answers" ng-bind-html = "n.answer | emoji">
Check this plunker.

AngularJS - JSON and return all results

I'm trying to write a basic search function using AngularJS. I have written a service that finds my JSON file and binds it to a $scope object $scope.SearchResult
What i am trying to do it perform a search on the items within SearchResult when the user enters a string. For any matches found,return the entire contents.
HTML:
<div ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<input ng-model="searchText">
<button ng-click="performSearch(searchText)">Submit</button>
{{ item }}
</div>
JS:
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.SearchResult = [
{
"Index":1,
"Title":"Help",
"Snippet":"You found Mr Happy",
"Url":"www.test.co.uk"
},
{
"Index":2,
"Title":"Conatct",
"Snippet":"You found Mr Happy",
"Url":"www.test.co.uk"
},
{
"Index":3,
"Title":"Help",
"Snippet":"You found Mrs Angry",
"Url":"www.test.co.uk"
},
{
"Index":4,
"Title":"Help",
"Snippet":"You found Mr Sad",
"Url":"www.test.co.uk"
}
];
$scope.performSearch = function(searchText) {
console.log("Performing a search....");
angular.forEach($scope.SearchResult.Snippet, function(item) {
if( item.label.indexOf(searchText) >= 0 ) filtered.push(item);
console.log(item);
});
}
});
So if HAPPY was entered in the input field, 2 matches would be found and displayed.
Heres a plunker: http://plnkr.co/edit/mOjcYUbFpoveaDw12NjE?p=preview

Angularjs filter part of name

I have a jsFiddle here - http://jsfiddle.net/GRw64/
I'm new to Angularjs so still finding my feet
My example is a simple ng-init of customer names.
An input field and a ng-repeat to filter the name in the input field against the customer names.
If you type a name in the input field the ng-repeat filters the list to show that name.
If I type Chris the name 'Chris Dave' and 'Chris' appear in the list.
If I change to 'Chris Dave', 'Chris Dave' is still showing in the list but 'Chris' disappears
How can I get a return with all the results that match at least one word in the search.
<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/1.2.6/angular.min.js"></script>
</head>
<body ng-app="" data-ng-init="customers=[{name:'Chris Dave'},{name:'Chris'},{name:'John'},{name:'Paul'}]">
<div class="container">
Names:
<br />
<input type="text" data-ng-model="name" />
<br />
<ul>
<li data-ng-repeat="cust in customers | filter:name">{{ cust.name }}</li>
</ul>
</div>
</body>
</html>
You can also provide a function to the filter filter of Angular:
ng-repeat="cust in customers | filter:filterByName"
Then you have to define the function in your controller:
$scope.filterByName = function(customer) {
if(!$scope.name) {
return true;
} else {
var keywords = $scope.name.toLowerCase().split(' ');
for(var i in keywords){
var k = keywords[i];
if (customer.name.toLowerCase().indexOf(k) >= 0) {
return true;
}
}
return false;
}
}
Working example
Suppose you treat the space-separated keywords as OR relationship, you can create a custom filter to achieve what you need like this:
var app = angular.module('myApp', []);
app.filter('myFilter', function () {
return function (names, keyword) {
var listToReturn = [];
if (keyword === undefined) return names;
var keywords = keyword.toLowerCase().split(' ');
angular.forEach(names, function (name) {
for(var i in keywords){
var k = keywords[i];
if (name.name.toLowerCase().indexOf(k) >= 0) {
listToReturn.push(name);
break;
}
}
});
return listToReturn;
};
});
DEMO

Resources