How to filter date in ngTable? - angularjs

I am trying to filter date in ngTable based on the given format d MMM yyyy HH:mm:ss. I followed this answer and created a custom filter, but it does not take the given format instead d MMM, yyyy.
How can I have filter on ngTable to filter dates in a given format? Here is my plunker
ngTable
<td data-title="'Start Date'" class="text-center" header-class="text-left" filter="{ 'start_date': 'text' }" sortable="'type'">{{item.start_date| date: 'd MMM yyyy HH:mm:ss'}}</td>
<td data-title="'End Date'" class="text-center" header-class="text-left" filter="{ 'end_date': 'text' }" sortable="'type'">{{item.end_date| date: 'd MMM yyyy HH:mm:ss'}}</td>
Custom filter
filter('customUserDateFilter', function($filter) {
return function(values, dateString) {
var filtered = [];
if (typeof values != 'undefined' && typeof dateString != 'undefined') {
angular.forEach(values, function(value) {
var source = ($filter('date')(value.start_date)).toLowerCase();
var temp = dateString.toLowerCase();
//if ($filter('date')(value.start_date).indexOf(dateString) >= 0) {
//if (temp.indexOf(" ") >=0)
//debugger;
if (source.indexOf(temp) >= 0) {
filtered.push(value);
}
});
}
return filtered;
}
})

You have to be careful when you are changing the format of the date. This is because the filter formats the date which has to be the same format as shown in the table to ensure correct functionality:
var source = ($filter('date')(value.start_date)).toLowerCase();
must be changed to this:
var source = ($filter('date')(value.start_date, 'd MMM yyyy HH:mm:ss')).toLowerCase();
Here is the working plunkr.

Related

st-table convert string to date

I have json object array binded to a table. Objects have a date column which is in date format but string. I need to change date format.
I tried;
<tbody>
<tr ng-repeat="row in table_data">
<td>{{row.availabledate | date:'MMMM dd, yyyy'}}</td>
</tr>
</tbody>
But, since it is string it is not formatted. I dont want to convert it in a loop for the sake of performance. Is there a way to convert this string to date and then format it on html part?
One way is to make your own filter, then use the date filter.
This crude/raw filter expects a YYYYMMDD string and creates a date object from it that you can then use angular's date filter on.
app.filter('strToDate', function() {
return function(input) {
var year = input.substring(0,4);
var month = input.substring(4,6);
var day = input.substring(6,8);
// Do filter work here
return new Date(year,month,day);
}
});
and then
<td>{{row.availabledate | strToDate | date:'MMMM dd, yyyy'}}</td>
Here's a Plunker link with working example: https://plnkr.co/edit/hn5StpktiMLq2gWHAszu?p=preview
You could also just make your filter return the formatted date.
Another way, doing all the work inside the filter:
app.filter('strToDate', function($filter) {
//1. date value
//2. the format input by user
return function(input, format) {
//Create the date object
var year = input.substring(0,4);
var month = input.substring(4,6);
var day = input.substring(6,8);
var newDate = new Date(year,month,day);
// return the format selected
return $filter('date')(newDate , format)
}
});
You can use the filter like this:
<td>{{row.availabledate | strToDate :'MMMM dd, yyyy'}}</td>

Angular date filter with date-string

I have a datestring in the following format: YYYY-MM-DD HH:mm:SS
I want to use the Angular date filter in the binding to change it to a YYYY-MM-DD HH:mm format.
I am trying {{data.date | date : "YYYY-MM-DD HH:mm"}}, but it doens't seem to work. Any ideas on what to change to get it to recognize my date format?
Try this
In Js file
angular.module('yourmodule').filter('datetime', function($filter)
{
return function(input)
{
if(input == null){ return ""; }
var _date = $filter('date')(new Date(input),
'MMM dd yyyy - HH:mm:ss');
return _date.toUpperCase();
};
});
In HTML
<span>{{ d.time | datetime }}</span>

problems with a filter date in angularJS

i have a problems with my filter date , I would like to filter between 2 date but with a condition if the date from is not valid then I start at 2017-01-01 (for that I think it is good) and if the date 'to' is not valid I start Has the current date
Here is my plunker:
http://plnkr.co/edit/8sK29zG7YoPOdntbFfcK?p=preview
Thank you for your help
Your filter could be something like this :
app.filter("myfilter", function($filter) {
return function(items, from, to) {
const testFrom = Date.parse(from);
const testTo = Date.parse(to);
if (!testFrom){
console.log('Not valid');
from = moment('2017-01-01');
}
//here it does nt work
if (!testTo){
to = moment();
}
const valids = items.reduce((acc,val) => {
const date = moment(val.dateenvoi);
if(date.isSameOrAfter(from) && date.isSameOrBefore(to))
acc.push(val)
return acc;
},[]);
return valids;
};
});
Check this
No need for custom filter for this functionality, you can use angular predefined filter for this like
<input type="text" name="S_Date" ng-model="filter.dateenvoi"/>
and
<tr ng-repeat="x in myData | filter: filter">
working Plunker

How to split the date based on check-In and check-out date in angularjs?

I have a hotel system need to split the date( duration of stay), The start date( Check-In) and EndDate(check-out) are selected by user in datepicker. like this:
<div class="datebox">
<input type="text" show-button-bar='false' class="form-control biginput" datepicker-popup ng-model="lodging.checkIn" is-open="checkin" datepicker-options="dateOptions" ng-required="true" close-text="Close"/>
<span class="dateicon" style='right:5px;' ng-click="openCheckIn($event)"></span>
</div>
<div class="datebox">
<input type="text" show-button-bar='false'
class="form-control biginput" datepicker-popup
ng-model="Lodging.checkOut" is-open="checkout" min-date='lodging.checkIn'
datepicker-options="dateOptions" ng-required="true"
close-text="Close" />
<span class="dateicon" style='right:5px;' ng-click="openCheckOut($event)"></span>
</div>
Users will choose check-in and check-out days from above two datepicker. I need to split out the information for each stays, such that if I choose check-in : 11/01/2015 check-out: 11/05/2015, I need to create a table to show each stay's expense from date 11/01/2015 to 11/05/2015. It will be like following table:
Date Amount
11/01/2015 109
11/02/2015 120
11/03/2015 101
11/04/2015 99
How to split out the duration date (like the first columnn of the table)and put them in the ng-repeat for my table?
First, prepare your table with ng-repeat
<table ng-init="loadStays()" ng-if="stays">
<thead>
<tr>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="stay in stays | between:lodging.checkIn:lodging.checkOut">
<td>{{ stay.date | date : 'mm-dd-yyyy' }}</td>
<td>{{ stay.amount }}</td>
</tr>
</tbody>
</table>
Then, create a filter for display only items between date from and date to (if I understand your question correctly)
// For parse a date in format: 'mm-dd-yyyy'
// If you have to parse the date from your item (maybe datetime ?)
// Use the built-in date filter
// like date = $filter('date')(item.date, 'mm-dd-yyyy')
parseDate = function(input) {
var parts = input.split('-');
return new Date(parts[1]-1, parts[2], parts[0]);
};
// Create the filter assuming app is your module.
app.filter('between', function() {
return function(items, from, to) {
filtered = [];
var dateFrom = parseDate(from);
var dateTo = parseDate(to);
if (from == '' && to == '')
return items;
filtered = items.filter(function(item) {
if (from !== '' && to == '') {
return item.date >= dateFrom;
} else if (from == '' && to !== '') {
return item.date <= dateFrom;
} else if (from !== '' && to !== '') {
return item.date >= dateFrom && item.date <= dateTo
}
});
return filtered;
};
});
With this code, stays are dynamically filtered and user see only items with a date attribute between your lodging.checkIn and logding.checkOut dates taken from datepicker ng-models.
And in case of you don't know how retrieve stays from your server, use something like :
// Retrieve stays from yourdomain/stays
$scope.loadStays = function() {
$http.get('stays').then(function(response) {
$scope.stays = response.data;
}, function(response) {
console.log(response);
});
};

ng-repeat filtering data by date range

I'm trying to filter a list that contains a timestamp by typing a range of dates
for example:
JSFIDDLE
html
<div ng-app="tst">
<div ng-controller="MyController">
<table>
<tr>
<td>From:
<input ng-model="query.date1" type="text" placeholder="" />
</td>
<td>To:
<input ng-model="query.date2" type="text" placeholder="" />
</td>
</tr>
<tr ng-repeat="order in orders |filter:query">
<td>{{order.date1 * 1000 | date:'dd-MM-yyyy'}}</td>
<td>{{order.date2 * 1000 | date:'dd-MM-yyyy'}}</td>
</tr>
</table>
</div>
</div>
javascript
var nameSpace = angular.module('tst',[]);
nameSpace.controller('MyController', function MyController($scope) {
$scope.orders = [
{
"date1":"1306487800",
"date2":"1406587800"
},
{
"date1":"1196487800",
"date2":"1406597800"
}]
});
i want to be able to fill the "From" field with the value : 27-05-2010
and the "To" field the value of : 29-07-2015
and get only the records that are in this range.
(the first record in the example).
Thanks allot
Avi
You can create a custom filter to achieve this aim.
JSFIDDLE
html
<input ng-model="dateFrom" type="text"/>
<input ng-model="dateTo" type="text"/>
<tr ng-repeat="order in orders | myfilter:dateFrom:dateTo">
<td>{{order.date1 * 1000 | date:'dd-MM-yyyy'}}</td>
<td>{{order.date2 * 1000 | date:'dd-MM-yyyy'}}</td>
</tr>
javascript
function parseDate(input) {
var parts = input.split('-');
return new Date(parts[2], parts[1]-1, parts[0]);
}
nameSpace.filter("myfilter", function() {
return function(items, from, to) {
var df = parseDate(from);
var dt = parseDate(to);
var result = [];
for (var i=0; i<items.length; i++){
var tf = new Date(items[i].date1 * 1000),
tt = new Date(items[i].date2 * 1000);
if (tf > df && tt < dt) {
result.push(items[i]);
}
}
return result;
};
});
also, i changed the timestamp data type from string to numbres.
$scope.orders = [
{
"date1": 1306487800,
"date2": 1406587800
},
{
"date1": 1196487800,
"date2": 1406597800
}]
I have created a filter with momentJS to make things easier:
.filter('dateRange', function() {
return function(items, startDate, endDate) {
var retArray = [];
if (!startDate && !endDate) {
return items;
}
angular.forEach(items, function(obj) {
var receivedDate = obj.date;
if (moment(receivedDate).isAfter(startDate) && moment(receivedDate).isBefore(endDate)) {
retArray.push(obj);
}
});
return retArray;
}
})
For time manipulation I strongly recommend libraries such as momentJS; with momentJS and modern browsers this can be achieved in a very declarative way:
.filter('dateRange', function() {
return function(items, startDate, endDate) {
//an undefined startDate is converted to the beginning of time
startDate = startDate || 0;
const granularity = null // can be 'days', ... see momentJS doc
//you need support for array.prototype.filter and arrow functions; i.e. IE sucks/needs a polyfill
return items.filter(item => moment(item).isBetween(startDate, endDate, granularity, '[]'));
}
}

Resources