ExtJS Parsing Date Incorrectly - extjs

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,

Related

How to set date range selection in react JS DateRangePicker?

I am using 'DateRangePicker' component in my react JS application.
I am trying to restrict start date to last 6 month only and difference between
start and end date should not be more than 1 month.
I wrote following code
isOutsideRange = (day) => {
if (day > moment()) return true;
else if (this.state.startDate) {
if (day > moment(this.state.endDate)) return true;
if (day < moment().subtract(6, 'months')) return true;
else return false;
} else if (this.state.endDate) {
if (day > moment(this.state.endDate)) return true;
if ((moment(this.state.endDate) > (moment(this.state.startDate).subtract(1, 'month')))) return true;
else return false;
}
}
and here is the UI code
<DateRangePicker
startDate={this.state.startDate}
startDateId="validFromDate"
endDate={this.state.endDate}
endDateId="validToDate"
onDatesChange={({ startDate, endDate }) =>
this.handleValidDatesChange(startDate, endDate)
}
focusedInput={this.state.ofrFocusedInput}
onFocusChange={(ofrFocusedInput) => this.setState({ ofrFocusedInput })}
isOutsideRange={(e) => this.isOutsideRange(e)}
showDefaultInputIcon={true}
small={true}
minimumNights={0}
hideKeyboardShortcutsPanel={true}
showClearDates={true}
min={this.maxDate}
shouldDisableDate={({ startDate }) => this.disablePrevDates(startDate)}
// minDate={subDays(new Date(), 10)}
displayFormat={() => "DD/MM/YYYY"}
/>;
I tried to debug but it is not working.
Can someone suggest the solution ?
To check if a moment is between two other moments, optionally looking at unit scale (minutes, hours, days, etc), you should use:
moment().isBetween(moment-like, moment-like, String, String);
// where moment-like is Moment|String|Number|Date|Array
For instance, if you need to check today - 6months <= someDate <= today, you would use something like:
// returns TRUE if date is outside the range
const isOutsideRange = date => {
const now = moment();
return !moment(date)
.isBetween(now.subtract(6, 'months'), now, undefined, '[]');
// [] - match is inclusive
}
For more details, please check Is Between docs. This method is very flexible, for instance, you can have exclusive or inclusive match.
Now, the second condition. If you would like to check if endDate - startDate <= 1 month, you can play with moments as well to achieve this.
// so if you add 1 month to your startDate and then your end date
// is still before the result or the same - you can say the duration
// between them is 1 month
const lessThanMonth = (startDate, endDate) => {
return endDate.isSameOrBefore(moment(startDate).add(1, 'months'));
}
if (day.isAfter(moment()) ||
!day.isAfter(moment().subtract(6,'months'))) return true;

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

How to parse /Date(-62135596800000)/ to null

I get from the server dates, sometimes null, and my filter parse /Date(-62135596800000)/ to 0001-01-01 but I would like to have empty string.
How can I do this?
Here's my filter:
filter('myDateFormat', function() {
return function (data) {
return moment(data).format("YYYY-MM-DD");
};
})
Well your server is returning you null or a date string.
null can be handled by simple null check but for your other input "Date(-62135596800000)" which is a valid date, you can't return empty string, without explicitly checking for it.
moment(Date(-62135596800000)).isValid() // return 'true'
you may try below code.
// if inputDate not defined or null
if (!inputDate || inputDate == null) {
return '';
} else if (moment(inputDate).isValid()){
return moment(inputDate).format("DD MM YYYY");
} else {
return '';
}
but if your server is returning this specific date occasionally 'Date(-62135596800000)' and you want to avoid this, you can put explicit check for it.
if (!inputDate || inputDate == null) {
return '';
}
if (inputDate == 'Date(-62135596800000)') {
return '';
} else if (moment(inputDate).isValid()) {
return moment(inputDate).format("DD MM YYYY");
} else {
return '';
}
The filter could be improved like this:
filter('myDateFormat', function() {
return function (data) {
return data > 0 ? moment(data).format("YYYY-MM-DD") : "";
};
})
First of all decide what should be your minimum date.
For example SQL's minimum date is 1753-01-01
After that compare your date with this minimum date like:
filter('myDateFormat', function() {
return function (data) {
var minDate = moment('1753-01-01');// decide your minimum date
return moment(data).diff(minDate) > 0 ? moment(data).format("YYYY-MM-DD") : "";
};
})

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.

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
};
...

Resources