md-datepicker input format - angularjs

When using the md-datepicker directive in angular material, the date format doesn't seem to work for direct input.
If I select a date in the calendar, it will be displayed as specified (in my case DD-MM-YYYY) but if I try to change the input manually, my entry is analysed as MM-DD-YYYY.
So far, my datepicker is set using this code from this question
angular.module('MyApp').config(function($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
return date ? moment(date).format('DD-MM-YYYY') : '';
};
});
Here is a codepen to see the problem in action.
Is there a way to setup the entry format?

Format date event is not enough. You should also configure parse date event.
$mdDateLocaleProvider.parseDate = function(dateString) {
var m = moment(dateString, 'DD-MM-YYYY', true);
return m.isValid() ? m.toDate() : new Date(NaN);
};
See updated pen: http://codepen.io/anon/pen/GpBpwZ?editors=101

The complete solution base it's:
$mdDateLocaleProvider.formatDate = function(date) {
return date ? moment(date).format('DD-MM-YYYY') : '';
};
$mdDateLocaleProvider.parseDate = function(dateString) {
var m = moment(dateString, 'DD-MM-YYYY', true);
return m.isValid() ? m.toDate() : new Date(NaN);
};

config($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
if(date !== null) {
if(date.getMonthName == undefined) {
date.getMonthName = function() {
var monthNames = [ "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" ];
return monthNames[this.getMonth()];
}
}
var day = date.getDate();
var monthIndex = date.getMonth();
var year = date.getFullYear();
return day + ' ' + date.getMonthName() + ' ' + year;
}
};
}

Two more definitions need to provide apart from formatDate -
parseDate - this to make sure manually entered date is valid
isDateComplete - this to make sure not to start validating partially entering date
Reference
/**
* #param date {Date}
* #returns {string} string representation of the provided date
*/
$mdDateLocaleProvider.formatDate = function (date) {
return date ? moment(date).format('DD-MM-YYYY') : '';
};
/**
* #param dateString {string} string that can be converted to a Date
* #returns {Date} JavaScript Date object created from the provided dateString
*/
$mdDateLocaleProvider.parseDate = function (dateString) {
var m = moment(dateString, 'DD-MM-YYYY', true);
return m.isValid() ? m.toDate() : new Date(NaN);
};
/**
* Check if the date string is complete enough to parse. This avoids calls to parseDate
* when the user has only typed in the first digit or two of the date.
* Allow only a day and month to be specified.
* #param dateString {string} date string to evaluate for parsing
* #returns {boolean} true if the date string is complete enough to be parsed
*/
$mdDateLocaleProvider.isDateComplete = function (dateString) {
dateString = dateString.trim();
// Look for two chunks of content (either numbers or text) separated by delimiters.
var re = /^(([a-zA-Z]{3,}|[0-9]{1,4})([ .,]+|[/-]))([a-zA-Z]{3,}|[0-9]{1,4})/;
return re.test(dateString);
};

Related

How to convert readable date time in timestamp which comes from backend

I want to convert the commit date and time to time stamp which I get from my APIs.
But I don't know how to do this in angular?
Here is my controller code :
var commitDate = item.commitMetaData.commitDate;
var dat = new Date(commitDate);
But it says "Invalid Date"
PS: Thanks in advance
What you could do is generate the date from the values montValue , year, dayOfMonth
with plain Javascript you could just do
var d = new Date();
d.setMonth(commitDate.monthValue +1); //see explanation below
d.setDate(commitDate.dayOfMonth);
d.setYear(commitDate.year);
be careful the months start at 0 so January is actually 0 so in your example you would have to add +1
You can also create a filter for this
.filter('createDate', function ($filter) {
return function (input) {
if (input != null && input != undefined) {
var d = new Date();
d.setMonth(input.monthValue +1); //see explanation below
d.setDate(input.dayOfMonth);
d.setYear(input.year);
return d;
}
};
})
and call it like
var commitDate = item.commitMetaData.commitDate;
var dat = $filter('createDate')(commitDate);
reference JS Date

Angular Material - Datepicker

Can anyone explain why the Datepicker expects value to be date object as per the official example?
https://material.angularjs.org/latest/demo/datepicker
To be honest this is a pain because before binding server response to the form I have to determine if a field is data type and convert the value:
$scope.myDate = new Date('2015-01-11');
Is there any way I could simply populate datepicker with a string value?
$scope.myDate = '2015-01-11';
The problem with a string value would be parsing. May 10, 2016 and October 5, 2016 could be confused. 2016-05-10 or 2016-10-05. The date object protects against that. Can you not use a defined filter to convert your string data to a date object?
I quickly modified some code below from a Date Filter I have for Angular 1.x, which uses a numeric date format of YYYYMMDD (20160516).
/**
* #name yourDate
* #ngdoc filter
* #requires $filter
* #param DateValue {string} Date Value (YYYY-MM-DD)
* #returns Date Filter with the Date Object
* #description
* Convert date from the format YYYY-MM-DD to the proper date object for future use by other objects/filters
*/
angular.module('myApp').filter('yourDate', function($filter) {
var DateFilter = $filter('date');
return function(DateValue) {
var Input = "";
var ResultData = DateValue;
if ( ! ( (DateValue === null) || ( typeof DateValue == 'undefined') ) ) {
if ( Input.length == 10) {
var Year = parseInt(Input.substr(0,4));
var Month = parseInt(Input.substr(5,2)) - 1;
var Day = parseInt(Input.substr(8, 2));
var DateObject = new Date(Year, Month, Day);
ResultData = DateFilter(DateObject); // Return Input to the original filter (date)
} else {
}
} else {
}
return ResultData;
};
}
);
/**
* #description
* Work with dates to convert from and to the YYYY-MM-DD format that is stored in the system.
*/
angular.module('myApp').directive('yourDate',
function($filter) {
return {
restrict: 'A',
require: '^ngModel',
link: function($scope, element, attrs, ngModelControl) {
var slsDateFilter = $filter('yourDate');
ngModelControl.$formatters.push(function(value) {
return slsDateFilter(value);
});
ngModelControl.$parsers.push(function(value) {
var DateObject = new Date(value); // Convert from Date to YYYY-MM-DD
return DateObject.getFullYear().toString() + '-' + DateObject.getMonth().toString() + '-' + DateObject.getDate().toString();
});
}
};
}
);
This code just uses the standard Angular Filter options, so you should then be able to combine this with your Material date picker.

convert birthday date to age in meanjs

I want to display age of all users in my meanjs app.
How can i display age instead of displaying birthdate. my plunk demo
Controller:
$scope.agedate = new Date();
$scope.calculateAge = function calculateAge(birthday) {
var ageDifMs = Date.now() - birthday.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch
return Math.abs(ageDate.getUTCFullYear() - 1970);
}
Html:
<p ng-bind="items.user.displayName"></p>
<p ng-bind="items.user.dateofbirth | date"></p>
<p ng-bind="calculateAge(items.user.dateofbirth)"></p>
my data:-
$scope.items = {
"_id": "5733163d4fc4b31d0ff2cb07",
"user": {
"_id": "5732f3954fc4b31d0ff2cb05",
"displayName": "karthi keyan",
"dateofbirth": "1991-10-04T18:30:00.000Z",
"profileImageURL": "./modules/users/client/img/profile/uploads/ed948b7bcd1dea2d7086a92d27367170"
},
"__v": 0,
"comments": [],
"content": "this is testing purpose for e21designs",
"categoryone": "Moral Ethics",
"category": "Anonymous Question",
"title": "Worried",
"created": "2016-05-11T11:23:41.500Z",
"isCurrentUserOwner": true
};
My plunk demo
Your code almost does what you want.
It has a problem in dateofbirth property, because it's a string (according your example.
To display it as the date you're using date filter which handles this for you.
But, in your calculateAge function you need to convert your string into Date.
Try the following:
$scope.calculateAge = function calculateAge(birthday) { // birthday is a string
var ageDifMs = Date.now() - new Date(birthday).getTime(); // parse string to date
var ageDate = new Date(ageDifMs); // miliseconds from epoch
return Math.abs(ageDate.getUTCFullYear() - 1970);
}
Hope it will help.
Please note that this problem is completely unrelated to angularjs. It is pure Javascript date differences calculation.
I strongly suggest to use a third party library like (momentjs)[http://momentjs.com/] to make such calculation, and in order to help you parse the string formatted date.
Here is a simple function in javascript to calculate age for the date format "YYYY-MM-DD". Where the dateString parameter to the function is the birth date.
function calculateAge(dateString) {
var today = new Date();
var birthDate = new Date(dateString);
var age = today.getFullYear() - birthDate.getFullYear();
var m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
}
You could use this as an angular function by applying $scope to it. Like this:
$scope.calculateAge = function(dateString) {
var today = new Date();
var birthDate = new Date(dateString);
var age = today.getFullYear() - birthDate.getFullYear();
var m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
}

How to change view date dynamically (which is filter event by date time)

I Want to filter event by date but date is pass by normal input type="text" not kendo default datepicker.And display passing date in kendo schduler header But cant not change view date.This is my code.........
$scope.searchEventByDate = function (item) {
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.view().startDate(item.StartDate);
scheduler.view().endDate(item.EndDate);
scheduler.view(("day"));
$scope.scheduler.dataSource.read();
};
This is my filter param
parameterMap: function (options, operation) {
var popupheight = $(window).height() - 180 + 'px';
$scope.popupWraperForTryout = popupheight;
var scheduler = $("#scheduler").data("kendoScheduler");
if (searchCount != 0) {
if (operation === "read") {
return {
filterByPersonalEvent: $scope._filterParamObj.filterBypersonal,
filterBySignUpRequired: $scope._filterParamObj.filterBySingupRequired,
filterByPaidOrFree: $scope._filterParamObj.filterByPaid,
filterByEventStatus: $scope._filterParamObj.eventStatusId,
filterByEventType: $scope._filterParamObj.eventTypeId,
selectedTeam: $scope._filterParamObj.seasonTeamId,
filterByStartDate: scheduler.view().startDate(),
filterByEndDate: scheduler.view().endDate(),
OrgId: _orgId,
UserTimezone: global.userTimezoneOffset
}
}
}
},
I am so tired.This code is not change in view date.Please help me
Several issues here - the day view shows just one day; you can't set startDate and endDate - just date.
$scope.searchEventByDate = function (item) {
var scheduler = $("#scheduler").data("kendoScheduler");
//scheduler.view().startDate(item.StartDate);
//scheduler.view().endDate(item.EndDate);
scheduler.view("day");
// item.StartDate should be Date object - like scheduler.date(new Date("2013/6/6"));
scheduler.date(item.StartDate);
$scope.scheduler.dataSource.read();
};
If you need to set some explicit date range to filter - you can do it, but still you can't show more than just one day in day view.
$scope.searchEventByDate = function (item) {
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler._myFilterStartDate = item.StartDate;
scheduler._myFilterEndDate = item.EndDate;
scheduler.view("day");
scheduler.date(item.StartDate);
$scope.scheduler.dataSource.read();
};
And in parameter map:
...
return {
filterByStartDate: scheduler.view().startDate(),
filterByEndDate: scheduler.view().endDate(),
myFilterStartDate: scheduler._myFilterStartDate,
myFilterEndDate: scheduler._myFilterEndDate,
OrgId: _orgId,
UserTimezone: global.userTimezoneOffset
};
...

ExtJS Parsing Date Incorrectly

When I enter "31/12/2012" in my field (date format is MM/DD/YYYY), it changes the date to "7/12/2014" in the field. I would rather it error with a "not valid" error message.
I have inherited this code from a previous developer:
function dateRangeCheck(val, field) {
field.vtypeText = '';
var date = field.parseDate(val);
if (!date) {
field.vtypeText = val + ' is not a valid date - it must be in the format (MM/DD/YYYY).';
return false;
}
var retVal = true;
if (field.fromField) {
var fromField = Ext.getCmp(field.fromField);
var fromDate = fromField.parseDate(fromField.getValue());
// If we don't have a fromDate to validate with then return true
if (!fromDate)
return true;
retVal = (date >= fromDate);
if (retVal)
fromField.clearInvalid();
}
else if (field.toField) {
var toField = Ext.getCmp(field.toField);
var toDate = toField.parseDate(toField.getValue());
// If we don't have a toDate to validate with then return true
if (!toDate)
return true;
retVal = (date <= toDate);
if (retVal)
toField.clearInvalid();
}
if (!retVal) {
field.vtypeText = 'From Date must be less than or equal to To Date.';
}
return retVal;
}
When I try to use the default 'daterange' vtype, as soon as I type a "3" in the field, it throws a JS runtime exception 'object doesn't support this property or method'.
Note that you can set Date.useStrict = true globally and the DateField will use that by default.
For Ext 4+ it would be Ext.Date.useStrict = true instead.
It looks like your call to parseDate just needs to have the strict switch set.
strict (optional) True to validate date strings while parsing (i.e.
prevents javascript Date "rollover")(defaults to false). Invalid date
strings will return null when parsed.
> Date.parseDate('31/12/2012','m/d/Y')
Sat Jul 12 2014 00:00:00 GMT-0500 (Central Daylight Time)
> Date.parseDate('31/12/2012','m/d/Y', true)
null
The parseDate method in DateField is private and undocumented, and the discussion to allow strict date parsing in ExtJS 3.x never bore any fruit. I think your best bet is to use an override to allow strict date parsing.
// before you use your DateFields
Ext.override(Ext.form.DateField, {
safeParse : function(value, format) {
if (Date.formatContainsHourInfo(format)) {
// if parse format contains hour information, no DST adjustment is necessary
return Date.parseDate(value, format, this.strict);
} else {
// set time to 12 noon, then clear the time
var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat, this.strict);
if (parsedDate) {
return parsedDate.clearTime();
}
}
}
});
//... and in your DateField config:
strict: true,

Resources