Angular JS Filter On date - angularjs

I was wondering if anyone could help me with filter on dates within ng-repeat
I have a text field that I enter the search text into for filter the results in my table
take this cut down example`
<tr id="credentialsData" ng-repeat="credential in credentials.data | filter:credentialsSearchText">
<td>{{credential.createdDate | date:'medium'}}</td>
</tr>`
credential.createdDate comes back in the rest call in the format 2015-03-24T21:19:49Z
When I attach the medium date filter - it displays as Mar 24, 2015 9:19:49 PM
However when i search on the String Mar or 9:, I get no results. Angularjs searches on the base object and ignores the filter.
I have read other options online where the person recommends adding different date formats into the json object but unfortunately that is not an option for me
Any help on this would be appreciated
Cheers
Damien

You can use a custom function for the filter.
https://docs.angularjs.org/api/ng/filter/filter
<tr id="credentialsData" ng-repeat="credential in credentials.data | filter:credentialsSearchText:compareCredentialDate">
<td>{{credential.createdDate | date:'medium'}}</td>
</tr>
In your controller, put a
$scope.compareCredentialDate = function(credential, expected) {
// you have to inject '$filter' to use this:
var dateFilter = $filter('date');
// this is the value that "credential.createdDate | date:'medium'"
// evaluates to:
var formattedDateString = dateFilter(credential.createdDate, 'medium');
// hypothetical matching method - you can implement whatever you
// want here:
var isMatch = formattedDateString.indexOf(expected) >= 0;
return isMatch;
}

Related

AngularJS orderby refining

I have a table of names starting with a title (Mr, Mrs, etc) and dates stored as strings plus some other data.
I am currently sorting it using
<tr dir-paginate="booking in bookingResults | orderBy:sortType:sortReverse | filter:searchPassenger | itemsPerPage: 15">
How could I refine my orderBy to sort names excluding the title (Mr, Mrs, etc) and dates as parsed dates not strings.
What would be best practice here?
EDIT :
I don't want to change the names in the model by the way - I want the format to remain "Mr Foo" and "Mr Bar" but when I sort them I want them to act as if they were just "Foo" and "Bar".
EDIT EDIT :
AngularJS 1.5.6
getting the right data in the right format
title & name
I'd use a regexp to pull the title from the name:
var regex = /((Dr\.|Mr\.|Ms\.|Miss|Mrs\.)\s*)/gmi
objName.replace(regex, '')
date
I'm assuming you're getting either a date object or a standard date string. If it's the latter, just create a Date object via new Date(incomingDateString). Then you can call:
objDate.getTime() //returns epoch in milliseconds
sorting
Some people might dislike this but I hate dirtying up view controllers with methods that NG directives need to use for things like ordering. Instead, I added some ng-flagged properties using ng-init on each row item. Then I can sort based off that. I didn't do it for the date in the example but you could extrapolate and apply.
ng-init w. ng-flagged properties
<tr ng-repeat="row in vc.listData | orderBy:vc.sortKey track by $index"
ng-init="row.$name = row.name.replace(vc.regexp, '')">
So in other words your objects go from this:
{
name:'Mr. Fred Rogers',
date:<date-object>
}
to this thanks to ng-init:
{
name:'Mr. Fred Rogers',
date:<date-object>,
$name:'Fred Rogers',
$date:1466192224091
}
And then via your sorting UI, you can set your $scope.sortKey to either $name or $date.
code pen
I made a sample in code pen but I did it with my template which is coffeescript and jade. You can probably figure out what I'm doing.
pen - http://codepen.io/jusopi/pen/aZZjgG?editors=1010
Ok, after some research, I found that the easiest solution is upgrading to AngularJS version 1.5.7 which introduces the comparator into the orderBy filter.
So I've changed my repeater to use an order by comparator
<tr dir-paginate="booking in Results | orderBy:Variable:TrueOrFalse:bookingComparator">
Variable is a string which I bound to the table headings so you can change the order by key, TrueOrFalse is a boolean which alternates between ascending and descending if you click the table heading and bookingComparator is my actual comparator.
My booking comparator looks like this
$scope.bookingComparator = function (a, b) {
var getTitle = /((Mrs|Mr|Mstr|Miss|Dr)\s*)/g;
var isDate = /(-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-)/g
if (getTitle.test(a.value)) {
var aName = a.value, bName = b.value;
return aName.replace(getTitle, '') < bName.replace(getTitle, '') ? -1 : 1
}
if (isDate.test(a.value)) {
var aDate = new Date(a.value), bDate = new Date(b.value);
return aDate.getTime() < bDate.getTime() ? -1 : 1
}
return a.index < b.index ? -1 : 1
}
The comparator is basically a function acting like the javascript .sort() method.
If the value contains a title (Mr, Mrs, etc) it is a name so I strip the titles and compare the actual names regardless of title.
If the variable matches a -Month- pattern, it's a date string and I compare the parsed date objects.
Hope this is helpful to someone, took me a while to figure out. I'm open to suggestions if you think there's a better way of doing this, and feel free to post an answer for people who want to use AngularJS =< 1.5.6

create date object from string in angualrjs

I am working with angularjs and the angularjs bootstrap ui (http://angular-ui.github.io/bootstrap/).
I want to use the datepicker directive (http://angular-ui.github.io/bootstrap/#/datepicker).
I am getting a string value from a database
2015-07-30 15:10
Angular wants to have a date object as model but I wasnt able to create a date object with that string. the error I get is
Error: [ngModel:datefmt] http://errors.angularjs.org/1.4.3/ngModel/datefmt?p0=2015-07-30
Can anyboy help me create a date object in angular with a string which has this format -> YYYY-MM-DD
more Information:
the string is in my scope
$scope.event.startdate
and I am splitting it in date, hours and minutes.
$scope.startpoint = {
date: $scope.event.startdate.substring(0, 10),
hours: $scope.event.startdate.substring(11, 13),
mins: $scope.event.startdate.substring(14, 16)
};
The database is MongoDB
Thank you
Adrian
You can use use a generic javascript solution. For example, you can use serega386's answer to a similar javascript question:
var st = "26.04.2013";
var pattern = /(\d{2})\.(\d{2})\.(\d{4})/;
var dt = new Date(st.replace(pattern,'$3-$2-$1'));
You can have the below code in your controller
$scope.newDate =new Date($scope.event.startdate);
and below code in your template
{{newDate | date:'yyyy-MM-dd'}}
Ref: AngularJS/javascript converting a date String to date object
If you are getting the date as a single set of numbers like this
1288323623006
you can use the date formatter directly on that.(from angular doc here)
<span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
<span>{{1288323623006 | date:'medium'}}</span><br>
<span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
<span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
Expected result
I hope that solves your problem, let me know if I'm missing something.

Angular JS Date format filter inside Ng-Repeat not formatting

Actual Date coming from JSON
Need to format it as below .
Effective Date : 2010-08-31 (trim the time stamp)
End Date : 2010-08-31 (trim the time stamp)
Am using the below code for Formatting the date inside Ng-Repeat.
<li ng-repeat="product in data | startFrom:currentPage*pageSize | limitTo:pageSize"
ng-click="getAttributes(product)">
{{product.prod_start_date| date:'MM/dd/yyyy'}}
{{product.prod_end_date| date:'MM/dd/yyyy'}}
</li>
But it doesnt work still displays the same.
Should the Date be passed as new Date as shown in the below jsfiddle Example
http://jsfiddle.net/southerd/xG2t8/
Note sure how to do that inside ng-repeat.?? Kindly help me on this. Thanks in Advance
I created my own filter to address this.
The date filter cant take a string, needs a date object.
.filter('cmdate', [
'$filter', function($filter) {
return function(input, format) {
return $filter('date')(new Date(input), format);
};
}
]);
then you can do:
{{product.prod_start_date| cmdate:'MM/dd/yyyy'}}
I use moment.js for my UI date time handling (there even a nice angular-moment bower package as well)
http://momentjs.com
https://github.com/urish/angular-moment
usage:
<span>{{product.prod_start_date | amDateFormat:'MM/dd/yyyy'}}</span>
It has a bunch of other options as well with relative dates etc.
I have updated the controller that you showed in the fiddle and here is your updated filter
Here I made use of the $filter('date') which is a feature of Angular itself in order to format the date in the desired format.
Here is the controller:
function Scoper($scope,$filter) {
$scope.s = "2012-10-16T17:57:28.556094Z";
var dateObj = new Date($scope.s);
$scope.dateToShow = $filter('date')(dateObj,'yyyy-MM-dd');
console.log($scope.dateToShow);
}

Order By Date and truncate date strings in Angular

I have a json file with a released field that comes back with such format:
released: "2002-01-28"
I intend to display them sorted by date (earlier first) and only showing the year. I've used the truncate module (in my example, release: 4) and so far its showing only the first 4 characters, but I haven't succeed using orderby to sort it correctly.
Any pointers?
Also, in some items the released field comes back empty, any quick way to display just a "unknown" instead of a blank space?
Thanks!
<li ng-show="versions" ng-repeat="version in versions | filter: '!file' | orderBy: version.released">
{{version.released | release:4}} - {{version.format}} - {{version.label}}
</li>
Here is a date formatting filter I use. It takes a date and converts it into whatever format you wish, in your case, 'yyyy'. Bind the raw date stamp in your template and then 'orderBy' should work fine. This is how I always do it. Oh, you might not want the replace() function... that was specific to my last project.
.filter('DateFormat', function($filter){
return function(text){
if(text !== undefined){
var tempdate = new Date(text.replace(/-/g,"/"));
return $filter('date')(tempdate, "MMM. dd, yyyy");
}
}
})
You can show unknown by doing {{version.released || 'unknown'}}.
If you only want to show the year do this {{ (version.released | date : date : 'YYYY' ) || 'unknown'}}

AngularJS: How to format ISO8601 date format?

I am using bootstrap-datetimepicker and using ISO8601 datetime format as yyyy-mm-ddThh:ii:ssZ as mentioned in their options section
In my controller, I do
transaction.date = $('.form_datetime input').val();
which sends the data to backend as (console.log)
created_on: "Wed, 08 May 2013 23:18:32 -0000"
and saves in database as
2013-05-08 16:18:32-07
In my template, I do
<td>{{ transaction.created_on | date:'medium'}}</td>
and I see the output on my HTML as
Wed, 08 May 2013 23:18:32 -0000
But as per the Angular doc, it should be for format Oct 28, 2010 8:40:23 PM
What is that I am missing?
I don't understand why no one provided the simple answer of using the correct format in the filter?
{{item.date | date:'yyyy-MM-ddTHH:mm:ssZ'}}
That will format as ISO-8601
For now, I have created a filter
angular.module('customFilters', []).
filter('dateInMillis', function() {
return function(dateString) {
return Date.parse(dateString);
};
});
added as dependency in app.js as
var app = angular.module('myApp', [
'$strap.directives', 'ngCookies', 'categoryServices', 'transactionServices',
'customFilters'
]);
and in HTML used it as
<!-- added dateInMillis to pass to date to filter Angular way -->
<td>{{ transaction.created_on | dateInMillis | date: 'medium'}}</td>
and that presents date on HTML as
May 8, 2013 5:14:36 PM
If you know a better idea, please let me know
In Brazil (and most of Europe, Australia, etc.), we use the default MySQL DATETIME on DB's:
"Y-m-d HH:ii:ss"
But use date() to display it like this:
"d/m/Y HH:ii:ss"
So in order to display that date in angular, "correctly", create a filter:
var app = angular.module(...
// Converts MySQL datetime into readable BR format
/*
Converts 2013-10-18 18:47:15 into 1382122035000 so angular can format date
using brazilian standards
*/
app.filter('brDateFilter', function() {
return function(dateSTR) {
var o = dateSTR.replace(/-/g, "/"); // Replaces hyphens with slashes
return Date.parse(o + " -0000"); // No TZ subtraction on this sample
}
});
Then, on your angular app, just call the filter and format the value for display:
{{ item.datetime_value | brDateFilter | date:"dd/MM/yyyy HH:mm" }}
That covers date format in Brazilian, UK, New Zealand, etc. date format for angular, just subtract the timezone correctly.
Beside all this, just you have change like this,
<td>{{ transaction.created_on | date:'medium'}}</td>
try to wirte it as
<td>{{ transaction.created_on | date:'MMM d, y h:mm:ss a'}}</td>

Resources