I am creating a form with input elements that are leveraging a jquery datepicker. Here is an example of what my HTML looks like for these inputs:
<td style="width:15%"><input type="text" name="datepicker" id="Tb3fromRow10"/></td>
<td style="width:15%"><input type="text" name="datepicker" id="Tb3toRow10"/></td>
I'm running into an issue where I need the date format to be mm/dd/yyyy, but the database only accepts formats in yyyy-mm-dd. As a result, I'm trying to hack it by having it show up as mm/dd/yyyy on the form, but have an eventlistener onSubmit that changes all the date formats to yyyy-mm-dd so that the database can record it. To do this, I am trying to write a loop that creates an array based on getElementsByName (since I named all of these elements "datepicker"), changes all of their formats, and then reassigns all of their ID's. I think I've done the first two steps, but am stuck on the last step of reassigning ID's:
var myArray = document.getElementsByName('datepicker[]');
for(var i = 0; i < myArray.length; i++) {
var sep = myArray.split('/');
var newDate = sep[2]+'-'+sep[0]+'-'+sep[1];
}
**document.getElementsByName('datepicker[]').value = newDate;**
I know the last line is incorrect, can someone help me with reassigning all of the date elements to their appropriate ID's?
Thanks!
You are not reassigning IDs. But you are not using the myArray correctly. Here is what you need to change assuming name="datepicker[]" and not name="datepicker" like in the HTML part of your example:
var myArray = document.getElementsByName('datepicker[]'); // or ("datepicker") depending on their name
for(var i = 0; i < myArray.length; i++) {
var sep = myArray[i].split('/');
var newDate = sep[2]+'-'+sep[0]+'-'+sep[1];
myArray[i].value = newDate;
}
anyway, why not validate and reformat on the server before storing?
Related
I have a Google site and am currently using the following script to populate my select box with data from the google sheet that is serving as my database:
<? var stringified = getData(); ?>
<?var data = JSON.parse(stringified)?>
<select size="10" id="userChoice">
<? for (var i = 0; i < data.length; i++) { ?>
<option>
<?= data[i] ?>
<? } ?>
</select>
This loads the page with the select box populated with every entry in the database. I'm wondering if this is the best way to go about it. What I would really like to do is have the contents of the select box be a little more dynamic.
I wrote out a script to filter through (by date) the contents of the Google Sheet, but I can't quite figure out how to have those filtered results show up in the above select box. I've tried several possible solutions, but keep hitting road blocks with them. Below is the function on the client side that passes the dates to the server side (note that I realize nothing in the below scripts would pass the data back to the select box. This is just to show how I am filtering through the data):
//Takes the dates that were entered into the first two date pickers and sends them over to the server side stringified. The server side then uses these dates to filter out jobs not within the given time period.
function dateFilter(){
var date = {};
//dates pusehd into array
date[0] = document.getElementById("startDate").value;
date[1] = document.getElementById("endDate").value;
//array stringified
var dates = JSON.stringify(date);//Convert object to string
google.script.run
.getData2(dates);
Then here is the code that filters through the database on the server side:
function getData2(dates) {
var ss = SpreadsheetApp.openById('1emoXWjdvVmudPVb-ZvFbvnP-np_hPExvQdY-2tOcgi4').getSheetByName("Sheet1");
var date = JSON.parse(dates);
var dateArray = [];
for (var k in date) {//Loop through every property in the object
var thisValue = date[k];//
dateArray.push(thisValue);
};
var startDate = Date.parse(dateArray[0]);
var endDate = Date.parse(dateArray[1]);
var jobReference = [];
var job;
var dateCell1;
var dateCell;
if ((startDate==NaN) || (endDate==NaN)){
for (var i = 2; job!=""; i++){
job = ss.getRange(i,43).getValue();
jobReference.push(job);
};
}
else{
for (var i = 2; job!=""; i++){
dateCell1 = ss.getRange(i,3).getValue();
dateCell = Date.parse(dateCell1);
if (startDate<=dateCell&&endDate>=dateCell){
job = ss.getRange(i,43).getValue();
jobReference.push(job);
Logger.log("here it is"+jobReference);
}
else{
}
}
};
var jR = JSON.stringify(jobReference);
return jR;
}
Now I've tried several things, having a success handler change the line <? var stringified = getData();?> to use getData2 doesn't seem to work (it yells at me that variable I'm trying to parse is undefined on the server side). So I tried putting an if/else in that would only have it parse if the variable was != to undefined, that didn't work either. Any suggestions would be appreciated.
I figured it out! This is functional, but perhaps not best practices, so if someone has any input, feel free to chime in.
So the first bit of code on the client side for the select box I left the same.
The next bit, where I send the dates over to the server side was changed to this:
function dateFilter(){
var sdate = document.getElementById("startDate").value;
var edate = document.getElementById("endDate").value;
google.script.run.withSuccessHandler(dateSuccess)
.getData2(sdate,edate);
}
So, since it was only two variables I took out the part that pushed it to an array. This eliminated the problem of parsing on the server side and thus having an undefined variable. I also added a success handler.
The server side code was left essentially the same, however I did change the for loop slightly. Instead of having it loop through the database until it found a blank cell in a particular column, I added var last = ss.getLastRow(); and had it loop though until i<= last. This kept the code from timing out on me.
Next I added the function I used for the success handler:
function dateSuccess(jobs){
document.getElementById('userChoice').options.length = 0;
var data = JSON.parse(jobs)
for (var i = 0; i < data.length; i++) {
var option = document.createElement("option");
option.text = data[i]
var select = document.getElementById("userChoice");
select.appendChild(option);
}
}
Works like a charm!
Scriptlets i.e. <? ?> are compiled and run when the page is created using execute function. They are not for dynamic modification of the web page. To modify the options based on a server returned data, in this case from getData(). You would do something like this
Firstly you set your google.script to call modifyoptions function on success
google.script.run.withSuccessHandler(modifyOptions)
.getData2(dates);
The above will code will automatically pass the return value of getData2 i.e Jr value to modifyOptions function
function modifyOptions(jobReference){
var selOpt = document.getElementById("userChoice")
selOpt.innerHTML ="" // Remove previous options
var options = ""
var data = JSON.parse(jobReference)
for (var i = 0; i < data.length; i++) {
options += "<option>"+data[i] +</option> //New string of options based on returned data
}
selOpt.innerHTML = options //Set new options
}
You can find a working example of how to modify the select-options in javascript here
Hope that helps!
I have the below code, is there a way to put this in a simpler format.
I am having to blank out 50 or more fields when a date in a certain key field is changed or made blank.
if (zEntry ==""){
document.getElementById("Q229I1226").value="";
document.getElementById("DQ230I1227").value="";
document.getElementById("DQ231I1228").value="";
document.getElementById("Q4I1001").value="";
//Date from fall to arrival
document.getElementById("Q232I1229").value="";
document.getElementById("DQ233I1230").value="";
document.getElementById("DQ234I1231").value="";
document.getElementById("Q5I1002").value="";
//Date Time of referral to T&O surgery
document.getElementById("Q238I1235").value="";
document.getElementById("DQ239I1236").value="";
document.getElementById("DQ240I1237").value="";
document.getElementById("Q15I1012").value="";
document.getElementById("Q17I1014").value="";
//Date seen T&O 1st on call
document.getElementById("Q241I1238").value="";
document.getElementById("DQ242I1239").value="";
document.getElementById("DQ243I1240").value="";
document.getElementById("Q16I1013").value="";
}
Thank you
You have to add common class to your inputs.
var array = document.getElementsByClassName('className');
for (var i = 0, lng = array.length; i < lng; i++) {
array[i].value = '';
}
If you want to clear out all fields with same tag you can just use
document.getElementsByTagName(arg) while arg being 'input', 'option' etc.
But if you want specific inputs to be cleared, you have to give them a class and use
document.getElementsByClassName(arg)
Add class to the input fields and try
var array_container = document.getElementsByClassName('example');
for (var i = 0, i < array_container.length; i++) {
array_container[i].value = '';
}
You may try this approach too:
// store all the element ids in an array
var element_ids = ['Q229I1226', 'DQ230I1227', 'DQ231I1228', 'Q4I1001',
'Q232I1229'];
element_ids.forEach(function(element_id){
document.getElementById(element_id).value = '';
});
Here is a solution of how to clear all input boxes/fields by looping.
Loop though all input boxes and clear them
I'm trying to parse multiple subreddit feeds in a Google Script. I can call this Google Script (redditFeeds()) and it returns the title, link, and date to my spreadsheet. However, I want to sort the posts by date so I can see the most recent posts first. I've tried using sort() on the array in various ways and can't get anything sort by descending date. I've even tried converting the date to a Date object and that didn't fix it.
function redditFeeds() {
var entries_array = [];
var subreddit_array = ['https://www.reddit.com/r/funny/top/.rss','https://www.reddit.com/r/news/top/.rss']
for (var s = 0; s < subreddit_array.length; s++) {
var xml = UrlFetchApp.fetch(subreddit_array[s]).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement();
var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
var entries = document.getRootElement().getChildren('entry', atom);
for (var i = 0; i < entries.length; i++) {
var title = entries[i].getChild('title', atom).getText();
var title = entries[i].getChild('link', atom).getText();
var link = entries[i].getChild('link', atom).getAttribute('href').getValue();
var date = entries[i].getChild('updated', atom).getValue();
entries_array.push([title, link, date]);
}
}
//return entries_array;
//doesn't work
//entries_array.sort(function(a,b) {
// return a.date - b.date;
//});
//also not working
return entries_array.sort(function(a,b) {
new Date(a.date).getTime() - new Date(b.date).getTime();
});
}
I think you want the below, assuming entries_array looks like I think it does. I have no idea what start was supposed to be in your code... I think each entry in entries_array is an array with three members in it, the third being some sort of representation of a date. If it's one that can be parsed by new Date, then this code should work:
return entries_array.sort(function (a, b) {
return new Date(a[2]) - new Date(b[2]);
});
If that's not right, please share what entries_array looks like.
I see a return missing, in the inner sort function and you should not need the getTime()
return entries_array.sort(function(a,b) {
return new Date(a.start) - new Date(b.start);
});
An easy way of sorting date objects is by converting them into UNIX time stamps using dateObj.getTime(). This creates an integer of the seconds since midnight on New Years day 1970. It's very useful if you are working in multiple time zones.
So, I'm using Kendo UI MVC where I want to create a type of request. However, the number of user controls is dynamic and depends of how many requests of that type the user wants to make. So to create them, I have this:
#while(number!=numberAdds){
<br />
<label style="margin-right:1em;margin-top:1.5em">Start time:</label>
#(Html.Kendo().TimePicker()
.Name("startTime"+(number+1))
.Min("8:00")
.Max("19:50")
.Interval(10)
)
<label style="margin-left:2.5em; margin-right:1em">End time:</label>
#(Html.Kendo().TimePicker()
.Name("endTime"+(number+1))
.Min("8:10")
.Max("20:00")
.Interval(10))
number++;}
And it works. Now, when I click the submit button, what I'm trying to do is to create an array of StartTimes and EndTimes so I can send it via Ajax Post to the controller. However, I'm not able to do so, because of the TimePickers ID. I'm trying to do something like this:
$(document).on("click", "#confirm-request", function (e) {
var date = $("#date").data("kendoDatePicker").value();
var stringDate = kendo.toString(date, "yyyy-MM-dd");
var number = 0;
var numberAdds = parseInt(document.getElementById("number-adds").textContent);
var timeStartStrings = new Array();
var timeEndStrings = new Array();
for (number; number < numberAdds; i++) {
var startTime = $("#startTime"+number).data("kendoTimePicker");
var endTime = $("#endTime"+number).data("kendoTimePicker");
var timeStartString = kendo.toString(startTime.value(), 'yyyy-MM-dd hh:mm');
var timeEndString = kendo.toString(endTime.value(), 'yyyy-MM-dd hh:mm');
timeStartStrings[number] = timeStartString;
timeEndStrings[number] = timeEndString;
}
However I can't get values for StartTime and EndTime, I always get undefined and I know it's because of $("#startTime"+number).data("kendoTimePicker");
What can I do?
Thanks :)
Is your number-variable in the razor code (top code block) starting initially with -1 (because of .Name("startTime"+(number+1))? Otherwise your javascript code will on its first iteration try to find $("#startTime0") without it existing. This probably leads to an error and thus stopping the execution of the JS-function.
So please check the names existing in your DOM vs the names questioned by Javascript and make sure, that they align properly.
I have an issue with a function I have been working on. The purpose of this function is to take the dates that are inside two sets of text input boxes, calculate the difference between the two, and then place that number of days in a third set of boxes. My function is shown below.
function daysBetween() {
for (var i = 0; i < 8; i++) {
//Get the value of the current form elements
var start = namestart[i];
var end = namend[i];
var out = names[i];
//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(out).value = diff;
}
}
The three arrays referenced by the variables at the beginning contain simply the names of the form elements I wish to access. I've tested the start, end, and out variables with an alert box and the loop runs fine if I do not have the line under the Show Difference comment in the code. I have also gone through and made sure that all names match and they do. Also I have manually run the page eight times (there is eight sets of boxes) with each set of names and it successfully displays 'NaN' in the day box (I have no data in the source boxes as of yet so NaN is the expected behaviour).
When I run the function as shown here what happens is that the first set of text boxes works as intended. Then the loop stops. So my question is quite simple, why does the loop hangup with getElementById even though the names[0] value works, it finds the text box and puts the calculated difference in the box. The text box for names[1] does not work and the loop hangs up.
If you need more detailed code of my text boxes I can provide it but they follow the simple template below.
// namestart[] array
<input type="text" name="start_date_one" id="start_date_one" value=""/> <br />
// namend[] array
<input type="text" name="end_date_one" id="end_date_one" value=""/> <br />
// names[] array
<input type="text" name="day_difference_one" id="day_difference_one" value=""/>
Thanks for any help in advance.
Edit: Noticing the comments I figured I would add my array definitions for refernece. These are defined immediately above the function in my calcdate.js file.
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";
I reference the file and call my function in my header as such:
<script type="text/javascript" src="calcdate.js"></script>
<script type="text/javascript">
window.onload = daysBetween;
</script>
First and foremost, you can't reference an object by its ID when it doesn't have an ID.
<input type="text" id="start_date_one" name="start_date_one" />
since you say out contains a name you might want to change
document.getElementById(out).value = diff;
to
document.getElementsByName(out)[0].value = diff;
or you could actually just add the id attribute to your html and set it to the same value as the name attribute and you can avoid changing your javascript.
getElementById gets the element by its id attribute, getElementsByName gets all of the elements with the specified name attribute and returns it as an array. In HTML id is supposed to be unique which is why getElementById returns only 1 element