Compare date and pick next value from array in angular js - angularjs

I have a json file with a list of holiday info, I would like to compare today's date with the list and display the next upcoming holiday.
How do I do the following?
Format today's date to compare with holiday json
Find the next holiday, display it's name and date
HTML display
<p>Next holiday is {{holiday.name}} on {{holiday.date}}</p>
Holiday Json
[
{
"name": "Christmas Eve",
"country": "US",
"date": "2015-12-24"
},
{
"name": "Christmas",
"country": "US",
"date": "2015-12-25"
},
{
"name": "First Day of Kwanzaa",
"country": "US",
"date": "2015-12-26"
},
{
"name": "Second Day of Kwanzaa",
"country": "US",
"date": "2015-12-27"
}
]

The other alternative is to use custom directive as below.
MyDirectives.directive("drHoliday", function() {
return {
replace: true,
restrict: 'A',
scope: false, //default
link: function(scope, element, attrs) {
items = scope.holidays.filter(function(item) {
var d1 = new Date();
var d2 = new Date(item.date);
return d2 > d1;
});
console.dir(items);
element.html('<p>Next holiday is ' + items[0].name + ' on ' + items[0].date + ' </p>');
}
}
});
And the markup would be something like below.
<div dr-holiday></div>
The working fiddle can be found here.
You can even sort filtered array by date if you are not taking care of same in server side code to make sure that items[0] would be the date you are expecting.
items.sort(function(a,b){
return new Date(b.date) - new Date(a.date);
});

Here is a function. Call it with your holidays array.
function getNextHoliday(holidays){
//Create date with today
var today = new Date();
//Iterate the holiday array in the scope
for (idx in holidays) {
//Create date variable for each holiday
var holiday = new Date(holidays[idx].date);
//Compare
if (holiday > today)
return holidays[idx].name + " on " + holidays[idx].date;
}
}

Here's a JSfiddle http://jsfiddle.net/user2314737/c6BfQ/277/
I used two filters: one to select dates greater than today's date and another to show only the first such item <tr ng:repeat="data in data | filter:dateFilter|limitTo:1">
function dateCtrl($scope) {
$scope.dateFilter = function ($scope) {
var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1;
var curr_year = d.getFullYear();
var today = curr_year + "-" + curr_month + "-" + curr_date;
return (Date.parse($scope.date) > Date.parse(today));
}
$scope.data = [{
"name": "Christmas Eve Last Year",
"country": "US",
"date": "2014-12-24"
}, {
"name": "Christmas",
"country": "US",
"date": "2015-12-25"
}, {
"name": "First Day of Kwanzaa",
"country": "US",
"date": "2015-12-26"
}, {
"name": "Second Day of Kwanzaa",
"country": "US",
"date": "2015-12-27"
}];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng:app>
<div ng:controller="dateCtrl">What's the next holiday?
<table class="table">
<tr>
<th>name</th>
<th>country</th>
<th>date</th>
</tr>
<tr ng:repeat="data in data | filter:dateFilter|limitTo:1">
<td>{{data.name}}</td>
<td>{{data.country}}</td>
<td>{{data.date}}</td>
</tr>
</table>
</div>
</body>

Related

Angularjs search with exclamation as first letter

Angularjs: Search filter not working when search starting with ! (exclamation mark)
If my data is like name='Anand!'
client side filter should work with searchWord='!'
Please if anyone has solution for the same then provide me the same.
Thanks in advance !!
My Code:
<input type="search" class="form-control" ng-model="searchtext"
placeholder="search here..." />
<div ng-repeat="cust in customers |orderBy:'id' | filter:searchtext">
</div>
$scope.customers = [{
"id": 1,
"first_name": "Anand!",
"last_name": "GK",
"gender": "Male"
}, {
"id": 2,
"first_name": "ABC !",
"last_name": "XYZ",
"gender": "Female"
}];
In above example you provide the filter on first_name only and also the function will be common for all so we can use it any where
this can be achieved too, all you have to do is get values of all fields in your object and then match the searchText like following:-
All you need to do, is write a custom filter of your own
angular.module('app', []).controller('ctrl', function($scope) {
$scope.customers = [{
"id": 1,
"first_name": "Anand!",
"last_name": "GK",
"gender": "Male"
}, {
"id": 2,
"first_name": "ABC !",
"last_name": "XYZ",
"gender": "Female"
}];
}).filter('searchFilter', function() { /* this the Custom Filter, you can code it to include other fields in search too */
return function(input, searchText) {
if (!searchText)
return input;
var matchedRecord = [];
var matchFound = false;
for (var i = 0; i < input.length; i++){
for (var key in input[i]) {
if(input[i][key] != undefined && input[i][key].toString().toLowerCase().indexOf(searchText.toLowerCase()) != -1) {
matchFound = true;
}
}
if(matchFound)
matchedRecord.push(input[i]);
matchFound = false;
}
return matchedRecord;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='ctrl'>
<input type='text' ng-model='searchText' />
<ul>
<li ng-repeat='customer in customers | searchFilter: searchText'>{{customer | json}}</li>
</ul>
</div>

AngularJS Filed nested array of objects with array of objects

I'm trying to filter a nested array of objects with my own objects, by idSubject. But I'm not getting the right result.
I have articles (which have subjects)
And a array of objects (which are the subjects I want to filter the articles with)
Data looks like this:
So I'm trying to filter the array of articles by its subjects.
I tried the following:
<div class="panel panel-default"
ng-repeat="searchArticle in searchArticles | filter: {subjects: filterSubjects} as articleSearchResult">
So filterSubjects is the second screenshot and SearchArticles is the first screenshot.
Without much luck.
Hope you can help, please tell me if things are still unclear.
This custom filter will help you.
Example : http://plnkr.co/edit/jMizCLxPH6DtDA5wL15Q?p=preview
HTML:
<body ng-app="myApp">
<div ng-controller="MainCtrl">
<h2>Select Subjects</h2>
<div ng-repeat="subject in subjects">
<label>
<input type="checkbox" ng-model="filterSubjects[subject.id]" ng-true-value="'{{subject.id}}'" ng-false-value="''">{{subject.name}}</label>
</div>
<h2>Filtered Articles</h2>
<div ng-repeat="searchArticle in searchArticles | subjectFilter:filterSubjects">{{searchArticle.name}}</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
filtered = articles.filter(function(e){return filterSubjects.indexOf(e.sid) >= 0},filterSubjects);
return filtered;
}
});
if you want to filter based on object :
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject1",
"id": "2"
}];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
var sFiltered = [];
for (var i = 0; i < filterSubjects.length; i++) {
sFiltered.push(filterSubjects[i].id);
}
var filtered = articles.filter(function(e) {
return sFiltered.indexOf(e.sid) >= 0;
}, sFiltered);
return filtered;
}
});

Angular Js How to filter records by date?

I am working in angular js and my data is coming from api in json array.I need to add filter according to selected date range from calendar. My dates are coming in two fields "from" and "to" or it can be a single date and i need to show records according to expiry date in json.
if user select the date range and click on search then i need to get selected records .This is my js in controller file.
localStorageService.set('usersOpen', users.openUsers);
localStorageService.bind($scope, 'usersOpen');
users.myUsers = myUsers;
function myUsers(start_date,end_date){
DataService.myOpenUsers()
.then(function successCallback(response) {
$scope.usersOpen.length = 0;
$scope.usersOpen.push({'data': response.data.results});
}, function errorCallback(response) {
});
This is json format that i need to filter.
{
"results": [{
"id": "999896",
"description": "Description Testingggg",
"picturesUrl": [],
"assigID": [{
"userId": "67767776",
"email": "test#gmail.com",
"firstName": "test",
"lastName": "User",
"pictureUrl": "",
"notifyStatus": "None",
}],
"expiryDate": "2016-10-14T17:48:50.100Z",
"createdUserId": "8887900",
"status": "Open",
"dtModified": "2016-10-14T12:21:27.431Z"
},{
"id": "999897",
"description": "New Tested Description",
"picturesUrl": [],
"assignedTo": [{
"userId": "887997",
"email": null,
"firstName": "testing",
"lastName": "users2",
"pictureUrl": null,
"notifyStatus": "None",
"devices": []
}, {
"userId": "887997",
"email": "testing#hotmail.com",
"firstName": "Testing",
"lastName": "User2",
"pictureUrl": "",
"notifyStatus": "None",
}],
"expiryDate": "2016-10-11T09:46:09.100Z",
"createdUserId": "887997",
"status": "Open",
"location": {
"lat": 12.1,
"lon": -3.1
},
"dtModified": "2016-10-11T09:36:30.217Z"
}]
}
This is html where i am getting records.
<ul>
<li ng-repeat="users in usersOpen[0].data track by $index" class="{{users.status}} {{yit.id}}">
<div class="content-box">
<div class="text-box">
{{users.description}}
</div>
{{users.expiryDate}}
</div>
{{users.firstName}}
</li>
</ul>
You can create a custom filter for filtering date range like this,
Filter
app.filter('dateFilter', function() {
return function(input, start, end) {
var inputDate = new Date(input),
startDate = new Date(start),
endDate = new Date(end),
result = [];
for (var i = 0, len = input.length; i < len; i++) {
inputDate = new Date(input[i].DepartureDateTime);
if (startDate < inputDate && inputDate < endDate) {
result.push(input[i]);
}
}
return result;
};
});
and apply in HTML
<div ng-controller="MyController">
<div ng-repeat="data in Combination | dateFilter:startDate:endDate ">
<div >{{data.DepartureDateTime}}</div>
</div>
</div>
DEMO
You can use angularjs $filter, you need to inject $filter in the controller and filter in whatever format you wanted.
$filter('date')(new Date(expiryDate), "M/d/yyyy");
for getting user data within a 2 date range , use this code
var fromTime = new Date("2015-04-23").getTime();
var toTime = new Date("2015-04-28").getTime();
var filteredDataByDates = [];
var row, date;
for (i in data) {
row = data[i];
date = new Date(row[4]);
if (date.getTime() >= fromTime && date.getTime() <= toTime) {
filteredDataByDates.push(row);
}
}
for your problem you can use native Javascript filter :
response.data.results.filter(function(user){
return //add your date test here on user.expiryDate
}

Filter by text search in some fields of array of objects

There must a small detail missing in this code but as I am new to angular I cannot figure it out myself. Here is the output:
Looping with objects:
{{ x.address + ', ' + x.beds }}
And here is the code:
<!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="objectsCtrl">
<p>Looping with objects:</p>
<ul>
<li ng-repeat="x in objects">
{{ x.address + ', ' + x.beds }}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('objectsCtrl', function($scope) {
$scope.objects = [
{
"address": "123, Demo Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "3",
"baths": "1"
},
{
"address": "123, second Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "1",
"baths": "1"
},
{
"address": "123, third Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "2",
"baths": "1"
},
{
"address": "123, fourth Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "4",
"baths": "1"
},
];
});
angular.module('myApp').filter('textSearchFilter',[ function (objects) {
return function(objects, searchText) {
searchText = searchText.toLowerCase();
var filtered = [];
angular.forEach(objects, function(item, searchText) {
if( item.address.toLowerCase().indexOf(searchText) >= 0 ||
item.beds.toLowerCase().indexOf(searchText) >= 0 ||
item.baths.toLowerCase().indexOf(searchText) >= 0
) {
filtered.push(item);
}
});
return filtered;
}
}]);
</script>
</body>
</html>
It seems that the list of objects is not passed correctly to the filter. I am guessing I did not put the filter function in thew right place.
Filter should be place on the ng-repeat directive objects array, using | pipe sign, thereafter you need to mention filter name.
<li ng-repeat="x in objects | textSearchFilter: searchInput">
Addionally you need to correct filter code
angular.module('myApp').filter('textSearchFilter',[ function (objects) { //<--remove object dependency
return function(objects, searchText) {
to
angular.module('myApp').filter('textSearchFilter',[ function () {
return function(objects, searchText) {
and add input field inside your HTML, like
<input type="text" ng-model="searchText"/>
Here is the final code working now:
<div ng-app="myApp" ng-controller="objectsCtrl">
<p>Looping with objects:</p>
<ul>
<li ng-repeat="x in objects | textSearchFilter:'demo'">
{{ x.address + ', ' + x.beds }}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('objectsCtrl', function($scope) {
$scope.objects = [
{
"address": "123, Demo Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "3",
"baths": "1"
},
{
"address": "123, second Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "1",
"baths": "1"
},
{
"address": "123, third Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "2",
"baths": "1"
},
{
"address": "123, fourth Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "4",
"baths": "1"
},
];
});
angular.module('myApp').filter('textSearchFilter',[ function () {
return function(objects, searchText) {
searchText = searchText.toLowerCase();
var filtered = [];
angular.forEach(objects, function(item) {
console.log(searchText);
if( item.address.toLowerCase().indexOf(searchText) >= 0 ||
item.beds.toLowerCase().indexOf(searchText) >= 0 ||
item.baths.toLowerCase().indexOf(searchText) >= 0
) {
filtered.push(item);
}
});
return filtered;
}
}]);

Angular JS Order By Filter not working for dynamic predicates

I am creating a Grid Control in Angular JS. ( I don't want to use ng-grid, smart table, etc for some reason)
Plunkr URL : http://plnkr.co/edit/arkCZcfXTIsW7sFCxisn?p=preview
On top of the table generated, i have populated fields in the combobox so that user is allowed to search on specific columns
or as free search.
As I see From here :
https://docs.angularjs.org/api/ng/filter/filter
For free search, I have used the syntax as {$:Value} and for column based search, {ColName:Value} syntax
However, I am unable to get it to work when I bind the column names to combobox.
I do get static search to work Eg if I write {'Code':"1"}, this works. but if I take "Code" from a combobox, it doesnt work.
Need help on setting dynamic filter.
This one also does not seem to help.
angular filter with dynamic list of attributes to search
This is the HTML
<div ng-controller="MyGrid">
Search in Column
<select ng-model="FilterByColumn" >
<option value="$">All</option>
<option ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible" value="{{hdr.name}}" >
{{hdr.caption}}
</option>
</select>
Value : <input type="text" ng-model="searchKeyword" />
<br />
Remove Sort
<table>
<thead>
<tr>
<th ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{hdr.caption}}
</th>
</tr>
</thead>
<tbody>
<%--<tr ng-repeat="dataVal in data | filter: {FilterByColumn : searchKeyword} | orderBy:predicate:reverse "> **Does not work--%>**
<%--<tr ng-repeat="dataVal in data | filter: {$ : searchKeyword} | orderBy:predicate:reverse "> **This works--%>**
<tr ng-repeat="dataVal in data | filter: GetFilter (FilterByColumn, searchKeyword) | orderBy:predicate:reverse "> **<!-- Does not work -->**
<td ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{dataVal[hdr.name]}}
</td>
</tr>
</tbody>
</table>
<pre>Sorting predicate = {{predicate}}; reverse = {{reverse}} ; SearchBy = {{FilterByColumn}} ; Search Key : {{searchKeyword}} </pre>
</div>
This is the JS :
'use strict';
var MyApp = angular.module('MyApp', []);
MyApp.controller('MyGrid', function ($scope) {
$scope.predicate = 'Code';
$scope.reverse = false;
$scope.FilterByColumn = '$';
$scope.headers = [
{
"name": "Code",
"caption": "Code",
"isVisible": true,
"displayOrder": 12
},
{
"name": "DispName",
"caption": "My Name",
"isVisible": true,
"displayOrder": 1
},
{
"name": "Locked",
"caption": "Islocked",
"isVisible": true,
"displayOrder": 2
}
];
$scope.data =
[{
"Code": "1",
"DispName": "abdul",
"Locked": "0"
},
{
"Code": "2",
"DispName": "Hemant",
"Locked": "0"
},
{
"Code": "3",
"DispName": "Rahul",
"Locked": "0"
},
{
"Code": "4",
"DispName": "Sandy",
"Locked": "0"
},
{
"Code": "5 ",
"DispName": "Nihal",
"Locked": "0"
},
{
"Code": "6",
"DispName": "Sachin",
"Locked": "0"
},
{
"Code": "7",
"DispName": "abdul f",
"Locked": "0"
},
{
"Code": "8",
"DispName": "abdul g",
"Locked": "0"
},
{
"Code": "9",
"DispName": "abdul h ",
"Locked": "0"
},
{
"Code": "10",
"DispName": "abdul i",
"Locked": "0"
}
];
$scope.getValue = function (obj, PropName) {
return obj[PropName];
};
$scope.SetSort = function (objName) {
//alert(objName);
$scope.predicate = objName;
$scope.reverse = !$scope.reverse;
};
$scope.GetFilter = function (srchCol, Srchval) {
//alert(srchCol);
//alert(Srchval);
if (srchCol == "") {
return { $: Srchval };
}
else {
return { srchCol: Srchval };
}
};
});
That is because when you write { srchCol: Srchval } - srcCol is the property name and is not substituted with the value in variable srcCol, try this syntax instead:
$scope.GetFilter = function (srchCol, Srchval) {
if (srchCol == "") {
return { $: Srchval };
}
else {
filter = {};
filter[srchCol] = Srchval;
return filter;
}
};

Resources