JavaScript calculate difference between two dates, display number in text input - javascript

I have been working for some time on an application form for an insurance company. They sell travel insurance.
As an additional small feature they have asked me to take the dates the depart and return dates the user inputs, calculate the number of days between them and then display number in the 'days' box. The goal of which is so that the user can enter the two dates and have the number of days auto-calculated.
I have already created a function which properly calculates the date and I have tested it using manually assigned date values.
My issue has come up when using the JS calendar.
What I tried to do was use the onblur of the second box to access the function and spit the date out into the 'days' box. I quickly realized that the onblur is triggered before the code for the JS calendar puts in the date, hence there is no date for the function and the function does not run.
I then tried to use onchange and realized it would not work either because the user is not actually changing the date, code is.
So what I tried to do next was use an Interval to trigger the function, this is where I have run into issues.
Below is my code in my caldate.js file which is attached to my HTML form.
var namestart = new Array ();
namestart[0] = "trav_emer_single_date_go";
namestart[1] = "trav_emer_extend_date_go";
namestart[2] = "allinc_single_date_go";
namestart[3] = "allinc_annual_date_go";
namestart[4] = "cancel_date_go";
namestart[5] = "visitor_supervisa_date_go";
namestart[6] = "visitor_student_date_go";
namestart[7] = "visitor_xpat_date_go";
var namend = new Array ();
namend[0] = "trav_emer_single_date_ba";
namend[1] = "trav_emer_extend_date_ba";
namend[2] = "allinc_single_date_ba";
namend[3] = "allinc_annual_date_ba";
namend[4] = "cancel_date_ba";
namend[5] = "visitor_supervisa_date_ba";
namend[6] = "visitor_student_date_ba";
namend[7] = "visitor_xpat_date_ba";
var names = new Array ();
names[0] = "trav_emer_single_days";
names[1] = "trav_emer_extend_days";
names[2] = "allinc_single_days";
names[3] = "allinc_annual_days";
names[4] = "cancel_days";
names[5] = "visitor_supervisa_days";
names[6] = "visitor_student_days";
names[7] = "visitor_xpat_days";
function daysBetween() {
for (var i = 0; i < 8; i++) {
//Get the value of the current form elements
var start = document.getElementById(namestart[i]).value;
var end = document.getElementById(namend[i]).value;
//Duration of a day
var d = 1000*60*60*24;
// Split Date one
var x = start.split("-");
// Split Date two
var y = end.split("-");
/// // Set Date one object
var d1 = new Date(x[0],(x[1]-1),x[2]);
// // Set Date two object
var d2 = new Date(y[0],(y[1]-1),y[2]);
//
// //Calculate difference
diff = Math.ceil((d2.getTime()-d1.getTime())/(d));
//Show difference
document.getElementById(names[i]).value = diff;
}
}
function interval() {
var int = setInterval(function(){daysBetween()},500);
}
The list of arrays at the beginning is the names of the elements which I need to access. What I intend to do with my function is on each interval run through a loop which checks all 8 of these elements. namestart[] and namend[] are the start and end dates entered by the user. names[] lists the names of the boxes where days are to be displayed.
I have not been able to even test the interval portion because I can't even get the daysBetween() to run once with manually assigned value="date" for testing purposes, it just won't run at all.
The issue is quite simple really: document.getElementById(namestart[i]).value isn't pullig out a value, it just hangs the script because it can't find the value. I have also tried using the form_name.elements().value notation and the form_name.element_name.value notation to no avail.
I am really stumped here as far as I can tell the code should be working, I give a list of the names of the items and I tell the script to access them using - what I have used, and seen many times to work getElementByID.
Any assistance would be greatly appreciated as I am not quite sure where to go from here.
As requested here is a JS fiddle link: http://jsfiddle.net/L2H9N/ - pure JS no libraries.

What I think is happening is your daysBetween function is executing before the DOM is ready, which is throwing an error and nuking the rest of your javascript. To fix it, you'll need to put the call to daysBetween into a callback for window.onload or attach it to a callback in your calender.
It would also be a good idea to coalesce your nulls or at least check for them before proceeding to do calculations on the variables.

Related

Google Scripts - "If" comparison not working

I want to protect the document from other users if a date in Column B1 + 2days is greater than today.
I had no problem with protection part, but I can't get the IF statements to work for some weird reason I can't understand.
This is the script where i compare dates:
ss = SpreadsheetApp.getActiveSheet();
send_date = ss.getRange("B1").getValue();
limit = new Date(send_date.setDate(send_date.getDate()-2))
limit.setHours(0,0,0,0)
day0 = new Date();
day0.setHours(0,0,0,0)
ss.getRange("D1").setValue(day0);
ss.getRange("D2").setValue(limit);
ss.getRange("D3").setValue(limit>day0);
ss.getRange("D4").setValue(limit<=day0);
if (day0>limit) { ss.getRange("C1").setValue("can be edited");}
else if (day0<=limit) { ss.getRange("C1").setValue("cannot be edited");}
I set hours/minutes/seconds etc to 0 because I only need to compare the dates day by day.
What happens after I run the script?
For example, if B1 = '2017-10-24', D1 sets to today ('2017-10-26'), D2 sets to ('2017-10-22').
D3, with limit>day0 comparison gets value FALSE, D4 limit<=day0 gets TRUE.
So far so good, but when it comes to IF statements, it seems that these comparisons are reversed.
In this example, C1 is set to 'can be edited'.
For me, that means that first comparison return FALSE, the second returned TRUE.
When I set date to a date in future (i.e. '2017-10-30'), D1-D4 fields get the right values, but C1 is set to 'cannot be edited'.
I'll be grateful for any help.
You can not compare two objects (day0 and limit) like that.
But, you can compare a value of those two objects. For example, using getTime().
var day0Time = day0.getTime();
var limitTime = limit.getTime();
if (day0Time > limitTime) {
// do stuff
}

Set Qualtrics Embedded Data with Javascript for loop

I am working on a survey in qualtrics, and need to be able to set many embedded data fields with different values, depending on a random selection of the experimental condition.
In the Survey Flow, I've entered all the names of the desired embedded data values.
I want this code to execute at the start of the survey, and to go through and set the values of those Embedded data variables.
The reason I use a for loop is because the variables are named things like:
set1a
set1b
set1c
var condition = Math.floor((Math.random() * 3) + 1)
var conditions =[ [8,8,8,5,5,5,5,2,2,2], [8,8,8,7,7,7,7,2,2,2], [10,10,10,5,5,5,5,2,2,2], [10,10,10,7,7,7,7,2,2,2]]
var values = condition[conditions]
var letters ="abcdefghij"
Qualtrics.SurveyEngine.addOnload(function(values)
{
for (var i = 0; i < values.length; i++ ) {
var dataname = "set1" + letters.charAt(i)
Qualtrics.SurveyEngine.setEmbeddedData(dataname,values[i]);
}
});
However, this code doesn't work.
When I try to call the variables using piped text later on in the survey (after a page break) they do not appear to have stored.
You have two issues.
First, you can only set Javascript in Qualtrics if it's inside of the .addOnload function, e.g.:
Qualtrics.SurveyEngine.addOnload(function(values)
{
// Your code
});
Second, your method for assigning - values - throws an error message.
Qualtrics doesn't have an issue saving embedded data in a for loop, so if you fix these two points, you should be good to go.

SharePoint/Javascript: comparing calendar date times in javascript

I am trying to find the best approach to comparing date/times using Javascript in order to prevent double booking on a SharePoint calendar. So I load an array with items that contain each event, including their start date/time and end date/time. I want to compare the start date/time and end date/time against the start/end date/times in the object, but I am not sure how to ensure that dates will not lapse.
like:
//date that is created from user controls
var startDate = new Date(startDat + 'T' + startHour + ':' + startMin + ':00');
var endDate = new Date(endDat+ 'T' + endHour+ ':' + endMin+ ':00');
for ( var i = 0; i < allEvents.length; i++ ) {
var thisEvent = allevents[i];
//having trouble with the compare
//i have tried silly ifs like
if (thisEvent.startDate >= startDate && thisEvent.endDate <= endDate) {
// this seems like I am going down the wrong path for sure
}
}
I then tried breaking apart the loaded object into seperate values (int) for each component of the date
var thisObj = { startMonth: returnMonth(startDate), startDay: returnDay(startDate), etc
but I am not sure this isn't just another silly approach and there is another that just makes more sense as I am just learning this.
I have a similar requirement in progress but chose to solve it at the booking stage, with jQuery/SPServices.
The code is still in build (ie not finished) but the method may help.
I attach an event handler to a column, then on selection, fetch all the dates booked in the same list to an array, then display that array on a rolling 12 month cal, as below.
I'm not checking to ensure a new booking doesn't overlap but a quick scan through the array on Pre-Save would provide a strict Go/No Go option for me. Relies on client side JS though, so not going to work in a datasheet or web services context.

Javascript prototype function: decimal time value to a time string

On a project I'm currently working on in JavaScript, I'm using decimal formats so it's easier to calculate with rather than using an hour/minute format in strings (calendar related project). To display the time on the user's screen though, the timecode has to be shown as hh:mm.
I thought it would be great to use a String prototype function for this as it would allow me to use code like:
var time = 8.75;
document.write("Meeting at "+time.toTime()); // writes: Meeting at 8:45
So far, I've got that almost working, using:
String.prototype.toTime = function(){
var hrs = this.toString().slice(0,this.indexOf("."));
var min = Math.round(this.toString().slice(this.indexOf("."))/100*60);
min = min<10 ? "0"+min : min.toString();
return hrs+":"+min;
}
The problem, though, is that this will only work if the variable time is a string. Otherwise it will give an undefined error.
Would there be any way of applying the prototype to a different object in JavaScript, so that I don't have to use time.toString().toTime()?
Thanks!
Firstly, you can add to the Number prototype. Many people will warn against modifying prototypes, which in many cases is justified. If there is a chance 3rd party scripts will be running alongside yours, it is a danger to modify prototypes.
Secondly, I simplified your code a little, using modulus, and floor to calculate the hrs and mins...
Number.prototype.toTime = function(){
var hrs = Math.floor(this)
var min = Math.round(this%1*60)
min = min<10 ? "0"+min : min.toString();
return hrs+":"+min;
}
var time = 8.25;
console.log("Meeting at "+time.toTime());
You can use Object.prototype.toTime.

Passed Variable not working with my function - Javascript

I've got text entry box and a countdown on the same page. I want to take the time from the box and enter it into the counter. I've got a variable back from the text box "setTime". I wanted to put that directly into my timeSplit function (to convert the time into seconds) but when I do I get an error that "time.split is not a function". What am I doing wrong here?
When I have a static variable enter the function (e.g. time = "12:12:12") everything works perfectly. - except its not using the right time
When I run the pop up alert on setTime before the timeSplit function I see my time like this "12:12:12" so its coming from the counter without a problem and I don't get a NaN error
Why would a time variable work when its static but not when its passed
I tried converting the setTime to a string but that just lead to NaN errors even when I tried to convert the sec variable back to an int.
I think this is the relevant code let me know if you need more.
var setTime = 0;
var $fromTime = $("#formEntry");
$("#setTime").off("click").on("click", function(){
setTime = $fromTime.val();
});
function timeSplit(){
//time = "12:12:12";
tt = time.split(":");
sec = tt[0]*3600+tt[1]*60+tt[2]*1;
return sec;
}
var time = setTime;
//var time = "12:12:12";
var sec = timeSplit(time);
Your function timeSplit() does not take any arguments. It needs to be timeSplit(time) so that JavaScript knows you are talking about calling the method .split() on an object called time rather than a function just called time.split().
If this wasn't just a typo (I've done that before), I suggest you read up some on function arguments and parameters so you know you understand how this works, it's really important.

Categories

Resources