Prefill current date in Google Form with Google Apps Script - forms

I have a Google Form to a spreadsheet and I need a date field pre-filled with the current date.
Something like an "onOpen trigger", which updates the date field or a date field with now().
Is this possible in Google Apps Script?

In your case, some of the points of using the Form remain unclear. Suppose that you have the ability to edit a link to the Form or your users agree to add the bookmarklet to their browser.
Common code
let id='1FAIpQLScx-1H1moCzBfkTEOZnVgBScbJeHZ4YE5E6IY2mNZvMuVcOXA';
window.open(
`https://docs.google.com/forms/d/e/${id}/viewform?usp=pp_url&entry.1000000=`+
(new Date()).toISOString().split('T')[0]
);
Bookmarklet
Just add the next string to the bookmarks bar
javascript:let id = '1FAIpQLScx-1H1moCzBfkTEOZnVgBScbJeHZ4YE5E6IY2mNZvMuVcOXA'; window.open(`https://docs.google.com/forms/d/e/${id}/viewform?usp=pp_url&entry.1000000=` + (new Date()).toISOString().split('T')[0]);

I put a static HTML page on S3 with a few line of Javascript for redirecting. See https://jsfiddle.net/barryku/3etd8qf0/
var formId = "1FAIpQLSc_acGSzp2VeJIyG0tNJwqcNdUPOweLROGenY0Fe56I635VGQ";
var dateField = "entry.1608430301";
var formsUrl = "https://docs.google.com/forms/d/e/"+ formId + "/viewform?usp=pp_url&" + dateField + "=$$today&entry.747437339=Yes";
var today = new Date();
var redirectUrl = formsUrl.replace("$$today", new Date(today.getTime() - (today.getTimezoneOffset() * 60000)).toISOString().split('T')[0]);
window.location.replace(redirectUrl);

Related

Google Forms - Change date format for all respondents

In Google Forms the date format is changed according to Language settings in Google account of the respondent.
I want the date format to be the same for all respondents.
Can I put some code in Apps script?
I tried the following to prefill the date:
function doGet(){
var form = FormApp.openById('1esX110YGnCOK8SJcz3jrll9ZiZZAhiIlpHxCTYbGcMg');
var questions = form.getItems();
var question2=questions[0];
var time=Utilities.formatDate(new Date(), "GMT+2", "dd-MM-yyyy");
var prefilledTime=form.createResponse().withItemResponse(question2.asTextItem().createResponse(time));
var URL=prefilledTime.toPrefilledUrl();
return HtmlService.createHtmlOutput("<script>window.top.location.href=\"" + URL + "\";</script>");
}
Thank you in advance!

How to return a normal javascript date object?

Is it possible to return a javascript date object from this? I have an text input field with the calendar and want to return a standard date object from it's value... Is this possible?
Is this what you are looking for?
var date = '2016-06-12'; // Can be document.getElementById('myField').value that points to your date field.
var date_parts = date.split('-');
var date_obj = new Date(date_parts[0],date_parts[1],date_parts[2]);
console.log(date_obj);
You can also simply use
new Date(document.getElementById('myField').value)
and see if it works. The date function is smart enough to parse based on browser's locale. This should work for time as well. Eg. new Date('2016-06-12 04:15:30')

Manipulate google form associated with a google sheet from app script in that sheet

I have a google spreadsheet which contains multiple sheets (or tabs) within it. Each sheet is populated from its own unique form. None of the forms are embedded in the spreadsheet.
Periodically, I need to delete all the data in the sheets, and also delete all the old responses which are saved in each of the forms. I can do this using a .gs script which resides in the spreadsheet. It accesses the form by its ID (the long string which appears in its URI). This requires the ID string to be hardcoded in my .gs script.
Ideally, I would like to access each form from the sheet object (i.e. the destination for each forms entries). Mock up code would look like this...
var ss = SpreadSheedApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var form = sheet.getMyAssociatedSourceForm(); // my dream method :-)
form.deleteAllResponses() // this method already exists
Does anyone know if this is possible? Or will I have to continue to use the ID (which is currently working)?
rgds...
I think you can do this without literally typing in ID's into your script. But, you would need to get every Form in your drive, loop through them all and get the destinationId() of every Form.
Google Documentation
Then compare the destinationId with the current spreadsheets ID, which you can get without needing to "hard code" it:
function deleteAllResponses() {
var thisSS_ID = SpreadsheetApp.getActiveSpreadsheet().getId();
var allForms = DriveApp.getFilesByType(MimeType.GOOGLE_FORMS);
var thisFormFile, thisFormFileID = "", thisForm, theDestID = "";
while (allForms.hasNext()) {
thisFormFile = allForms.next();
thisFormFileID = thisFormFile.getId();
thisForm = FormApp.openById(thisFormFileID);
try {
theDestID = thisForm.getDestinationId();
} catch(err) {
continue;
};
if (theDestID === "" || theDestID === undefined) {
continue;
};
if (theDestID === thisFormFileID) {
thisForm.deleteAllResponses();
};
};
};
I have not tested this, so don't know if it works. If it does, let me know in the comments section.

Getting a Google Form Script generated email to pipe data into Reponse Sheet

I am currently trying to setup an approval workflow. I'm fairly junior when it comes to some of this stuff. But so far have it working at respectable level to fit our needs with the assistance of an example.
I was using the template/example from Email Approval using Google Script and a Form.
The issue I am running into, with a lack of functionality is that at the time of Accept or Deny via the Email that is generated for approval I would like it to then record that data back into the Google Form row in the last column that the email was generated from.
I may end up adding 2nd timestamp, reply email etc later.
So then that row would show the initial form filled out and then either blank/accepted/deny as the status.
Thank you for any time or assistance.
The approval workflow that James Ferreira originally wrote was intentionally very basic. Enhancing it to provide correlation between approvals and the original requests is simple in concept, yet complicates the code because of details and limitations.
Things that need to considered:
Form responses include a timestamp, which we can use as a sort of "serial number" for responses, since it has a very high probability of being unique in an application like this.
We can pass this identifier along with the rest of the URL embedded in the approval email, which will give it back as a parameter to the webapp, in turn.
Passing an object like a timestamp between applications can be troublesome. To ensure that the URL embedded in the approval email works, we need to encode the string representation of the timestamp using encodeURIComponent(), then decode it when the webapp consumes it.
Searching for matches is simplified by use of ArrayLib.indexOf() from Romain Vaillard's 2D Array library. This function converts all array data to strings for comparisons, so it fits nicely with our timestamp.
Alternatively, we could put effort into creating some other identifier that would be "guaranteed" to be unique.
The approval-response web app (doGet()) does not understand what "activeSpreadsheet" means, even though it is a script contained within a spreadsheet. This means that we need a way to open the spreadsheet and record the approval result. To keep this example simple, I've assumed that we'll use a constant, and update the code for every deployment. (Ick!).
So here's the Better Expense Approval Workflow script.
// Utilizes 2D Array Library, https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library
// MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T
function sendEmail(e) {
// Response columns: Timestamp Requester Email Item Cost
var email = e.namedValues["Requester Email"];
var item = e.namedValues["Item"];
var cost = e.namedValues["Cost"];
var timestamp = e.namedValues["Timestamp"];
var url = ScriptApp.getService().getUrl();
// Enhancement: include timestamp to coordinate response
var options = '?approval=%APPROVE%&timestamp=%TIMESTAMP%&reply=%EMAIL%'
.replace("%TIMESTAMP%",encodeURIComponent(e.namedValues["Timestamp"]))
.replace("%EMAIL%",e.namedValues["Requester Email"])
var approve = url+options.replace("%APPROVE%","Approved");
var reject = url+options.replace("%APPROVE%","Rejected");
var html = "<body>"+
"<h2>Please review</h2><br />"+
"Request from: " + email + "<br />"+
"For: "+item +", at a cost of: $" + cost + "<br /><br />"+
"Approve<br />"+
"Reject<br />"+
"</body>";
MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
"Approval Request",
"Requires html",
{htmlBody: html});
}
function doGet(e){
var answer = (e.parameter.approval === 'Approved') ? 'Buy it!' : 'Not this time, Keep saving';
var timestamp = e.parameter.timestamp;
MailApp.sendEmail(e.parameter.reply, "Purchase Request",
"Your manager said: "+ answer);
// Enhancement: store approval with request
var sheet = SpreadsheetApp.openById(###Sheet-Id###).getSheetByName("Form Responses");
var data = sheet.getDataRange().getValues();
var headers = data[0];
var approvalCol = headers.indexOf("Approval") + 1;
if (0 === approvalCol) throw new Error ("Must add Approval column.");
// Record approval or rejection in spreadsheet
var row = ArrayLib.indexOf(data, 0, timestamp);
if (row < 0) throw new Error ("Request not available."); // Throw error if request was not found
sheet.getRange(row+1, approvalCol).setValue(e.parameter.approval);
// Display response to approver
var app = UiApp.createApplication();
app.add(app.createHTML('<h2>An email was sent to '+ e.parameter.reply + ' saying: '+ answer + '</h2>'))
return app
}
So, I tried this, but there an issue with the formatting for date when it's in the data array. In order to get this to work, you have to reformat the time stamp in the doGet using formatDate.
I used the following to get it to match the formatting that appears in the array.
var newDate = Utilities.formatDate(new Date(timestamp) , "PST", "EEE MMM d yyyy HH:mm:ss 'GMT'Z '(PST)'");
Lastly, of course update the indexof parameter that is passed to newDate.

XPages convert a date in a view column that is displayed as HTML

In a view panel, I have one col that is displayed as HTML because I am pointing to documents created with a traditional form. So, I can't set the "Display type" to anything except a String. I've tried to convert the value by using toJavaDate, but that didn't work.
Here is the formula for my HTML column where rowData is the var or view panel. myserver/folder/myapp.nsf part I changed so that I could paste it here...
if (!rowData.isCategory())
var disp = rowData.getColumnValue("PayPeriod");
"<a href='https://myserver/folder/myapp.nsf/0/"+rowData.getUniversalID()+"?OpenDocument'>"
+disp+"</a>"
The link works properly in my view, but the value displayed shows a full date & time value (6/15/13 8:51 AM). All I am trying to do is display it as 06/15/2013 (MM/DD/YYYY)
if the column is set to date you could use this to get the correct date format
if (!rowData.isCategory())
var formatter
if(viewScope.formatter){
formatter=viewScope.formatter
}else{
formatter = new java.text.SimpleDateFormat( "MM/dd/yyyy" );
viewScope.formatter=formatter
}
var d = rowData.getColumnValue("PayPeriod");
var disp=formatter.format(d)
"<a href='https://myserver/folder/myapp.nsf/0/"+rowData.getUniversalID()+"?OpenDocument'>"
+disp+"</a>"