XPages DateTextBox - setting constraints - javascript

I am working with the date text box and had a few questions. This is with designer 9, so its using dojo 1.8 not that it should make too much difference.
Setting Min / Max dates
I don't see a way to do this in designer. There isn't anything in xe:djDateTimeConstraints that matches, so is this something I need to do via javascript?
I have an example below that changes the EndDate control once StartDate is selected, but didn't see a way to set StartDate other then beforeRenderResponse or some such.
Selectable Dates
http://dojotoolkit.org/reference-guide/1.8/dijit/form/DateTextBox.html
"also validates against developer-provided constraints like min, max, valid days of the week, etc."
Valid days of the week - I'd love to set it to just weekdays that are selectable, but there is no example, and the link does not go to a page with a dayofweek constraint. What term should I be searching for? In the example below I have a validator, but I didn't know if the date text box could just have the weekends be unselectable.
Here is my example control - when start date is set, it changes constraints of end date
<xp:label value="Start Date" id="lblStartDate"></xp:label>
<xe:djDateTextBox id="djDateStart">
<xe:this.constraints>
<xe:djDateTimeConstraints datePattern="M/dd/yyyy"></xe:djDateTimeConstraints>
</xe:this.constraints>
<xp:eventHandler event="onChange" submit="false">
<xe:this.script><![CDATA[
var startDateID = "#{id:djDateStart}";
var endDateID = "#{id:djDateEnd}";
var hiddenEndDateID = "#{id:hiddenEndDate}";
require(["dojo/date/locale"], function(locale){
var x = new Date (dojo.byId(startDateID).value);
// Fails if current date is the weekend or empty
if(locale.isWeekend(x) || dojo.byId(startDateID).value == "") {
dojo.style(hiddenEndDateID, "display", "none");
dojo.byId(endDateID).value = "";
dojo.byId(startDateID).value = "";
dijit.byId(startDateID).displayMessage("dates must be weekdays");
} else {
// Set display value and constraint for End Date
dojo.byId(endDateID).value = dojo.byId(startDateID).value;
dijit.byId(endDateID).constraints.min = arguments[0];
dijit.byId(endDateID).constraints.max = dojo.date.add(arguments[0], "week", 3);
// Make End Date and Comment visible.
dojo.style(hiddenEndDateID, "display", "inline");
}
})
]]></xe:this.script>
</xp:eventHandler>
</xe:djDateTextBox>

the solution I came up with was to use the Range check - not constraints. So in the script block below, it returns false when the day is sunday/saturday (0, 6) and if its not within the range.
Perhaps this will help someone else.
fyStart = new Date ("#{applicationScope.fyStart}");
fyEnd = new Date ("#{applicationScope.fyEnd}");
calendarEnd = new Date ("#{applicationScope.calendarEnd}");
require(["dojo/ready", "dojo/parser", "dijit/registry", "dijit/Dialog"], function(ready, parser, registry){
ready(function(){
dijit.byId('#{id:djDateStart}').rangeCheck = function(date,constraints) {
var day=date.getDay();
return day !==0 && day !== 6 && date >= fyStart && date <= calendarEnd;
}
dijit.byId('#{id:djDateEnd}').rangeCheck = function(date,constraints) {
var day=date.getDay();
return day !==0 && day !== 6 && date >= fyStart && date <= calendarEnd;
}
});
});

Related

Is there a way to set default date when navigating to a new month or year in date range picker?

I am using DateRangePicker library in a project and faced an issue, my goal was when opening the calendar for the first time, the current date is selected by default(done) and when navigating to another month or year the same day becomes selected as I go so that there is always a selected day in the calendar. there are some speical cases to consider like if the selected day is 31 and the next month doesn't contain it so it should select 30 instead and so on but it's not the problem now. The problem is I tried to use setStartDate() to do that but it didn't work, although the date changes correctly when I logged it but it's not selected in the calendar (missing the css class that highlights it). So does anyone knows how to fix that or what to use instead to achieve my goal?
Thanks
ngAfterViewChecked() {
if (this.isCalendarShown) {
var element = $(document.getElementsByClassName("daterangepicker show-calendar"))
.filter(function(){
return $(this).css('display') === 'block';
}).get(0);
var monthSelected = element.getElementsByClassName("monthselect")[0];
if (monthSelected != null) {
var month = (<HTMLInputElement>monthSelected).value;
var year = (<HTMLInputElement>element.getElementsByClassName("yearselect")[0]).value;
var isStartDateExist = element.getElementsByClassName("left")[0].querySelector(".start-date");
var isStartDateValid = element.getElementsByClassName("left")[0].querySelector(".off.start-date");
if ( isStartDateExist != null && isStartDateValid == null ) {
this.currentMonth = month;
this.currentYear = year;
}
if (month != this.currentMonth || year != this.currentYear) {
const date = String(parseInt(month)+1).padStart(2, '0')+'/01/'+year;
this.picker.setStartDate(date.toString());
this.picker.setEndDate(date.toString());
}
}
}
}

Doing math towards future date

I am trying to figure out how to calculate future date compared to current date. For Example: (think of Deadline as a Date field)
- If Deadline (value form) is in the future but <= 12/31 of the current year, “This Year”
- If Deadline (value form) is in the future but > 12/31 of the current year, “Future”
So far, I am unable to figure this out within my code.
I need help with var theFuture AND to create a var for "is future but <= 21/31 of current year.
var theFuture = new Date("January 01 2020");
//theFuture.setDate(today.getDate());
//Compare the two numbers
if (dateToCheck < rightNow || dateToCheck == rightNow) {
theTiming = "Overdue";
g_form.setValue('u_timing', theTiming);
}
else if (dateToCheck >= approaching) {
theTiming = "Deadline Approaching";
g_form.setValue('u_timing', theTiming);
}
else if (dateToCheck > theFuture){
theTiming = "Future";
g_form.setValue('u_timing, theTiming');
}
}
So, results should be: When the user selects a date from Deadline, another field called Timing will generate Text. Current, I am able to calculate if the date selected is today or before today, Timing will say "Overdue". Next, if the date selected is greater than today BUT within 180 days, Timing will say "Deadline Approaching". But, to get the rest that I mentioned above, I am stuck.
We use moment.js for working with dates it makes things a lot easier.
This will tell you if the date selected is today or not:
var iscurrentDate = moment().isSame(dateToCheck, "day");
if(iscurrentDate)
{
}
You can also do a similar thing for year
var iscurrentDate = moment().isSame(dateToCheck, "year");
if(iscurrentDate)
{
}
More info on moment here: https://momentjs.com/docs/

How to check if a date reached or expired for every year

I have a date field that only has the month and the date say, 02/03 (dd/mm). For every year when the date reaches '2nd of march' I want to generate an alert. Usually we can do date comparison like this:
var mdate='01-04-2010';
date = Date.parse(mdate.split('-')[1]+'-'+mdate.split('-')[0]+'-'+mdate.split('-')[2]);
if (parseInt(date) < parseInt(Date.now()))
{
alert('small');
} else {
alert('big');
}
Now I have dd/mm and that should be checked every day and at each year when it reaches that particular date I need to generate an alert.
Can some one please help me?
Try this:
var today = new Date();
if (parseInt(today.getDate()) == 2 && parseInt(today.getMonth()) == 2) {
alert('It is 2nd of march');
}

How can I dynamically set an end date based on a given start date and term duration?

I want to dynamically set the Term End date based on the Term Type (annual, semiannual, quarter, month) and the Term Start date.
So if we have a term that is set to annual and the start date is set to 03/10/2016, the term end should be set to 03/10/2017.
Here's what I have so far, but not sure how to work in casing the Term Type (annual == 12 months, etc.). I'm also getting a console error for the format of the date. Any help or pointers would be greatly appreciated.
.field
= f.label :term_start_date, 'Term Start', class: 'label'
.input
= f.date_field :term_start_date, id: 'termStart'
.field
= f.label :term_end_date, 'Term End', class: 'label'
.input
= f.date_field :term_end_date, id: 'termEnd'
:javascript
$("#termStart").val();
$("#termEnd").val({
onSelect: function () {
var toDate = $(this).val('getDate');
toDate.setDate(toDate.getDate()+7)
$("#termStart").val("setDate", toDate);
}
});
The specified value "[object Object]" does not conform to the required format, "yyyy-MM-dd".
What you're attempting isn't difficult, but there's a bit of work to do. A date library can help, but it doesn't take a lot of effort to write your own methods. You need to do a few things:
Parse and validate the input start date
Get the term and add some months to the start date
Handle invalid input
Display the result
The following doesn't use any jQuery (you can use it if you like but it doesn't offer any benefits) and should give you some idea of what needs to be done.
var dLib = {
// Given a date string in format m/d/y, return a Date instance
parseMDY: function (s) {
var b = s.split(/\D+/);
var d = new Date(b[2], --b[0], b[1]);
return /\d{1,2}\/\d{1,2}\/\d{1,4}/.test(s) &&
d.getMonth() == b[0]? d : new Date(NaN);
},
// Given a Date, return date string formatted as mm/dd/yyyy
formatMDY: function (date) {
function z(n){return (n<10?'0':'')+n}
if (isNaN(date)) return date.toString();
return z(date.getMonth() + 1) + '/' + z(date.getDate()) + '/' + date.getFullYear();
},
// Add months to a date. If end date itn's equal to start date,
// must have gone past end of month so set to last day of month
addMonths: function (date, months) {
var startDate = date.getDate();
date = new Date(+date);
date.setMonth(date.getMonth() + Number(months))
if (date.getDate() != startDate) {
date.setDate(0);
}
return date;
},
};
function setTermEnd(el) {
var form = el.form;
var term = form.termInMonths.value;
var startDate = dLib.parseMDY(form.termStart.value);
// Check that a valid date was entered. If no date entered
// yet, do nothing. Else, put error message in termEnd
if (isNaN(startDate)) {
form.termEnd.value = form.termStart.value == ''? '' : 'Term start date is invalid';
// Add months and set term end
} else {
form.termEnd.value = dLib.formatMDY(dLib.addMonths(startDate, term));
}
}
// Attach listeners and run to initialise
window.onload = function() {
var form = document.forms[0];
form.termInMonths.onchange = function() {setTermEnd(this)};
form.termStart.onchange = function() {setTermEnd(this)};
form.termStart.onchange(form.termStart);
}
.hint {
color: #999999;
font-size: 75%;
}
<form>
<table>
<tr><td>Term:<td><select name="termInMonths">
<option value="12" selected>Annual
<option value="6">Semi-annual
<option value="3">Quarter
<option value="1">Month
</select>
<tr><td>Term start:<td><input name="termStart" value="1/31/2016"><span class="hint">m/d/y</span>
<tr><td>Term End:<td><input name="termEnd" readonly><span class="hint">m/d/y</span>
</table>
</form>
Javascript's built-in datetime manipulation is very limited.
Your best bet is to use a javascript datetime library. moment.js is a good one
Your second best bet is going to be to work with the time in seconds as that is how javascript does it. Use Date.parse(toDate) to convert it to seconds since the epoch, then add the number of seconds, then convert it back to a date.

JavaScript - Validate Date

I have an HTML text field. I want to validate via JavaScript that the value entered is a valid date in the form of "MM/DD/YY" or "MM/D/YY" or "MM/DD/YYYY" or "MM/D/YYYY". Is there a function that does this?
I sort of assumed there was something like isNaN but I don't see anything. Is it true that JavaScript can't validate dates?
You could use javascript's own Date object to check the date. Since the date object allows some mucking around with the month and day values (for example March 32 would be corrected to April 1), you can just check that the date you create matches the one you put in. You could shorten this if you want, but it's longer for clarity.
function checkDate(m,d,y)
{
try {
// create the date object with the values sent in (month is zero based)
var dt = new Date(y,m-1,d,0,0,0,0);
// get the month, day, and year from the object we just created
var mon = dt.getMonth() + 1;
var day = dt.getDate();
var yr = dt.getYear() + 1900;
// if they match then the date is valid
if ( mon == m && yr == y && day == d )
return true;
else
return false;
}
catch(e) {
return false;
}
}
Is it true that JavaScript can't validate dates?
No.
Is there a function that does this?
No.
You will need to write your own validation function to parse the date format (regex comes to mind) and then determine if it is valid within your specific criteria.
Check out http://momentjs.com/. Using it, this snippet
moment(yourCandidateString, 'MM-DD-YYYY').isValid()
should do the job.
This is what I use to validate a date.
Date.parse returns NaN for invalid dates.
This supports both date-only and date+time formats.
Hope this helps.
var msg;
var str = "2013-12-04 23:10:59";
str = "2012/12/42";
var resp = Date.parse(str);
if(!isNaN(resp)) { msg='valid date'; } else { msg='invalid date'; }
console.log(msg);
If you want to venture into the realms of JQuery there are plenty of validation plugins that include date validation. This plugin is one I've used a few times and has served me well.
I use Bootstrap Datepicker. One of the options with the text box disabled should do the trick.
http://www.eyecon.ro/bootstrap-datepicker/
<input type="text" id="dateinput"/>
<script type="text/javascript">
$(#"dateinput").datepicker({
buttonImage: "images/calendar.png",
dateFormat: "yyyy-MMM-dd"
});
function validateDate() {
if ($(#"dateinput").val().trim() == "") {
// Is a blank date allowed?
return true;
}
var oldVal = $(#"dateinput").val(); // Current value in textbox
// Now use jQueryUI datepicker to try and set the date with the current textbox value
$(#"dateinput").datepicker("setDate",$(#"dateinput").val());
// Check if the textbox value has changed
if (oldVal != $(#"dateinput").val()) {
// The datepicker will set something different if the date is invalid
$(#"dateinput").val(oldVal); // Set the textbox back to the invalid date
alert ("date was invalid");
return false;
} else {
// If nothing changed, the date must be good.
return true;
}
}
</script>
There does not appear to be a build-in function which does that. However, this code is probably what you're looking for:
<script type="text/javascript">
/**--------------------------
//* Validate Date Field script- By JavaScriptKit.com
//* For this script and 100s more, visit http://www.javascriptkit.com
//* This notice must stay intact for usage
---------------------------**/
function checkdate(input){
var validformat=/^\d{2}\/\d{2}\/\d{4}$/ //Basic check for format validity
var returnval=false
if (!validformat.test(input.value))
alert("Invalid Date Format. Please correct and submit again.")
else{ //Detailed check for valid date ranges
var monthfield=input.value.split("/")[0]
var dayfield=input.value.split("/")[1]
var yearfield=input.value.split("/")[2]
var dayobj = new Date(yearfield, monthfield-1, dayfield)
if ((dayobj.getMonth()+1!=monthfield)||(dayobj.getDate()!=dayfield)||(dayobj.getFullYear()!=yearfield))
alert("Invalid Day, Month, or Year range detected. Please correct and submit again.")
else
returnval=true
}
if (returnval==false) input.select()
return returnval
}
</script>
Source: http://www.javascriptkit.com/script/script2/validatedate.shtml
Have you googled for something like javascript date validation? It shows up some good information, and a working code example here.
I suggest you a couple of solutions.
guide the user input with a date picker. This way you can control the input format. jQueryui datepicker is a popular implementation.
use a js library to manage datetime data type (not an actual datatype in Javascript!!). I suggest you date.js.
Similar to this answer, Date can be used to check if the parsed version of the string corresponds to the original date string.
> datestring_valid = "2020-02-29";
> parsed_Date = new Date(datestring_valid);
> parsed_Date.toISOString().slice(0,10) == datestring_valid;
true
> datestring_invalid = "2021-02-29";
> parsed_Date = new Date(datestring_invalid);
> parsed_Date.toISOString().slice(0,10) == datestring_invalid;
false
NB: This requires the date string to be ISO formatted.
The reason this works is, that Date parses some invalid dates into something valid as in the example above. However, supplying "2020-01-32" into Date will result in the result being "Invalid Date" that isNaN.
A function that handles all of this is the following:
function isValidDateString(datestring) {
parsed_Date = new Date(datestring);
return (parsed_Date.toISOString().slice(0,10) == datestring) && !isNaN(parsed_Date)
};
> isValidDateString(datestring_valid)
true
> isValidDateString(datestring_invalid)
false

Categories

Resources