Add previous responses to form - google-apps-script

I am creating a sign up sheet where people list what they will bring to an event. I would like to modify a Section Header at the start of the form that shows who has signed up to bring what, (pulled from the spreadsheet that collect the data) such that people can see what is already being brought to the event. I am trying to set this on the "On Open" event such that each time the form is loaded people can see other's responses.
I can connect to the spreadsheet via SpreadsheetApp.getActiveSheet() and then get the data. I thought I could add the info from the spreadsheet to the section header when the form is being opened. When I open the form it does not seem to execute this code:
function onFormLoad() {
var s = SpreadsheetApp.getActiveSheet();
var form = FormApp.getActiveForm();
var items = form.getItems();
for (var i = 0; i < items.length; i++){
if (items[i].getType() == FormApp.ItemType.SECTION_HEADER){
items[i].setTitle("Yes");
items[i].setHelpText("This is where I want to put the data...");
}
}
}
If I run this code from the editor it does indeed add the section header. I need it to run when others open the form.

You should add this code in the onFormSubmit event, you can learn more about the various events here https://developers.google.com/apps-script/understanding_events.
If I am not mistaken, you will need to add the trigger explicitly, read more about triggers here : https://developers.google.com/apps-script/understanding_triggers

Related

How to dynamically change an existing text item value on Google Forms using Google Apps Script

I have an existing Google Form in which there is a TextItem with a title "Which location was this performed at?".
Whenever the form is loaded (opened), I need to set a location value (loc) to this existing textbox and show it to the user.
function populateMemberIds(loc){
var form = FormApp.openById(formUrl);
var questions = form.getItems();
for (var i=0; i<questions.length; i++){
if(questions[i].getTitle()=="Which location was this performed at?"){
var textItem = questions[i].asTextItem();
//I get stuck here
}
}
I already setup the openForm trigger which allows to run the populateMemberIds function to be run on each form load. Again, what I need is to change the value of the "Your answer" section of the text item with the location value (loc).
I would appreciate any help.
You can't modify a form response filled by a user, you can either create a form response programmatically or edit a response after being submitted. The onOpen form trigger runs when someone opens the form to edit it rather than answer it [1]:
This event does not occur when a user opens a form to respond, but
rather when an editor opens the form to modify it.
Moreover, triggers functions comes with an event parameter already defined [1] so you can't set your own function parameter(s) as you're doing with your loc parameter.
EDIT
You can programmatically create and submit a form response [2], from which you can also get a URL with a prefilled form for the user to finish [3].
function populateMemberIds(loc){
var form = FormApp.openById("[FORM-ID]");
var questions = form.getItems();
var response = form.createResponse();
for (var i=0; i<questions.length; i++){
if(questions[i].getTitle()=="title form"){//Which location was this performed at?"){
var textItem = questions[i].asTextItem();
var itemResponse = textItem.createResponse(loc) ;
response.withItemResponse(itemResponse);
}
}
//Submit programmatically the form response
response.submit();
//URL with prefilled form response
Logger.log(response.toPrefilledUrl());
}
function test () {
populateMemberIds("US");
}
[1] https://developers.google.com/apps-script/guides/triggers/events#google_forms_events
[2] https://developers.google.com/apps-script/reference/forms/form-response
[3] https://developers.google.com/apps-script/reference/forms/form-response#toprefilledurl
The onOpen Google Apps Script triggers (simple and installable) for Google Forms are executed only when the form is opened in the form editor, not when the form is opened by using the view / edit response links.
There are two ways to "prefill" a Google Forms response:
Use the prefilled response URL
Create a response programmatically, then use the editResponseUrl
Related
Is it possible to 'prefill' a google form using data from a google spreadsheet?
How to generate a pre-filled form URL for Google Form

Highlight a name of current user in Google Sheets using Google Apps Script

I'm working on spreadsheet with table that contains names of workers and their availability during whole year. My goal is to highlight cell with proper name when specific person opens the sheet. All users have their google mail in first_name.last_name#gmail.com schema.
I've already made some code which find name and do bold action on active user's name, you can see it below:
function onOpen(e)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for(var k = 0; k<sheets.length; k++)
{
var data = sheets[k].getDataRange().getValues();
var user = Session.getActiveUser().getEmail();
var splitname = user.split("#")[0];
var first = splitname.split(".")[0];
var last = splitname.split(".")[1];
var formatted_first = first.charAt(0).toUpperCase() + first.slice(1);
var formatted_last = last.charAt(0).toUpperCase() + last.slice(1);
var name = formatted_first + " " + formatted_last;
for(var i = 0; i<data.length;i++)
{
if(data[i][0] == name)
{
var a = i+1;
}
}
sheets[k].getRange(a,1).setFontWeight("bold");
}
}
The problem is that:
I don't know how to perform an action temporarily, only for time when sheets is open.
After writing code I realized that bold action will be visible for all active users, so if one user opens the sheet when the other has it already open and not close yet, he will see not only his name highlighted but also that other user's name.
Soo, my question is whether there is any possibility to make changes visible only for user that made them and how to perform the highlighting only while sheet is open.
If you know any google feature which makes it possible without using the macro, it would be the best solution. Maybe my research wasn't good enough.
Thank you in advance for help!
Soo, my question is whether there is any possibility to make changes visible only for user that made them and how to perform the highlighting only while sheet is open.
No, there isn't any possibility to do that. The alternatives are to have one spreadsheet for each user or to edit the sharing settings to allow only one user to access the spreadsheet besides the owner but you will have to assume that the owner and the current editor will be able to see the changes made by the other.
NOTE: Filter Views allow users to apply filter settings visible only for the user who is using the filter view but any change made to the filtered data will be viewable by the other users.

Reject Google Forms submission or remove response

I'm using the current, "new" version of Google Forms. I have a form, Form A, and the associated script Script A. That script contains a function, onFormSubmit, associated with Form A's form submit trigger. The function receives one argument, an event, which contains the Form and the submitted FormResponse in the fields "source" and "response" respectively.
In the body of this function, how can I prevent the event/reject the form submission?
Alternatively, if this is not possible, how can I quietly prevent the FormResponse from being stored, or quietly remove it from the list of responses?
I see there is a Form.deleteAllResponses method. Do I have to delete all responses and then add all responses back again, except for the current one? Or is there a better way?
Try experimenting with the event trigger and use:
setAcceptingResponses(enabled)
Sets whether the form is currently accepting responses. The default for new forms is true.
Here is a code sample from a related SO post:
function onFormSubmit(){
var af = FormApp.getActiveForm();
var defaultClosedFor = af.getCustomClosedFormMessage();
af.setCustomClosedFormMessage("The form is currently processing a submission, please refresh the page.");
af.setAcceptingResponses(false);
<put your script stuff here>
af.setAcceptingResponses(true);
af.setCustomClosedFormMessage(defaultClosedFor);
}
Hope this helps.
The way I have handled this is by having a second sheet (tab within the same Google Sheet) into which Form responses are copied. The first thing that happens in the onFormSubmit() function is that the newest row in the responses sheet is copied to the duplicate sheet. You could implement a selection statement that chooses whether to make the copy or not depending on your criteria.
This means that there is always a copy of the raw responses from the form (important for auditing purposes) but also a means for correcting/modifying responses if errors were made by the submitter.
In case it is useful, this is my function that does the copy (note that my settings object is abstracted elsewhere but hopefully there is enough to make clear what is going on).
/**
* Copies form submissions from the responses sheet to another sheet.
*
* #param {event object} e the event object received from a form submit trigger
* #param {Settings} settings an object containing the settings this function expects to use
* #return {integer} the position of the new row in the destination sheet
*/
function copyFormSubmissionToSheet(e, settings) {
var sourceSheet = SpreadsheetApp.getActive().getSheetByName(settings.nameOfFormResponsesSheet);
var destinationSheet = SpreadsheetApp.getActive().getSheetByName(settings.name OfApprovalsSheet);
var newRow = e.range["rowStart"];
var columnCount = sourceSheet.getLastColumn();
var newResponseRange = sourceSheet.getRange(newRow, 1, 1, columnCount);
var newResponseDestinationRange = destinationSheet.getRange(destinationSheet.getLastRow()+1, 1, 1, columnCount);
newResponseRange.copyTo(newResponseDestinationRange);
var newDataSheetRow = destinationSheet.getLastRow();
return newDataSheetRow;
}

Dynamically fill form fields based on other responses before submit

I have a form I want to dynamically change, I have read through the documents but I cannot seem to find any definitive answer. Can I make my form remove choices from dropdown lists because they used radio button #2 for the 3rd question? Can I format text from question 1 and use it to pre-fill question 6 with the same answer (by default, needs to be changeable)?
Basically I need to use code to determine if the address was spelled with shortforms (st, rd, cres, ct) and lengthen and capitolize them (Street, Road). I don't even know if this is possible. If it is can anyone provide sample code or point me to the right help docs, it would be appreciated. If not is this doable on a webserver if some of my multiple choice options need to be read from a google spreadsheet? Could i do it through google Sites?
Have you looked at the Form Class of Google Apps Services?
Class Forms
It states:
Forms can be accessed or created from FormApp.
For example, you can use:
addTextItem()
OR:
createChoice(value)
Google Documentation
// Open a form by ID and add a new multiple choice item.
var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
var item = form.addMultipleChoiceItem();
item.setTitle('Do you prefer cats or dogs?')
.setChoices([
item.createChoice('Cats'),
item.createChoice('Dogs')
])
.showOtherOption(true);
You don't want to open a new form, but use the currently open one.
/**
* Adds a custom menu to the active form, containing a single menu item for
* invoking checkResponses() specified below.
*/
function onOpen() {
FormApp.getUi()
.createMenu('My Menu')
.addItem('Check responses', 'checkResponses')
.addToUi();
}
Check current responses?
/**
* Gets the list of responses and checks the average rating from the form
* created in createForm() above.
*/
function checkResponses() {
var form = FormApp.getActiveForm();
var responses = form.getResponses();
var score = 0;
for (var i = 0; i < responses.length; i++) {
var itemResponses = responses[i].getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
if (itemResponse.getItem().getType() == FormApp.ItemType.SCALE) {
score += itemResponse.getResponse();
}
}
var average = score / responses.length;
FormApp.getUi().alert('The score is ' + average);
}
}
You could use Apps Script HTML Service; write HTML to create a custom form; write the JavaScript code to do what you want; then add the Apps Script to the Google Site. Or just run the Apps Script HTML Service as a website on it's own. But this option requires you to be able to write HTML and JavaScript. What you want to do is possible.
As far as creating the custom form, checking the user input and changing it, that can be done in Apps Script HTML Service. Then you need to save the data somewhere. Google Forms is made to be user friendly to people who don't have programming knowledge.
It seems like you are just looking for general information on what is possible and not possible with different products so that you can make a choice.
For reading about HTML Service, click the following link as a place to start:
Google Documentation HTML Service

How to generate a pre-filled form URL for Google Form

I'm looking for a programmatic way to automate the generation of pre-filled URLs for google forms.
In a recent update, Google introduced a new Forms product to Google Docs. If you open the tools menu in a spreadsheet, you'll see some new options.
In the new Form Responses menu, one option is "Get pre-filled URL". This opens up a dialog containing a version of your form that you can fill out, and when you submit it, you receive a URL that can be used to open a Live Form with the data you pre-filled ready and waiting for you. The URL looks something like this...
https://docs.google.com/forms/d/--Form-ID--/viewform?entry.1094330118=Something&entry.1471717973=stack#example.com&entry.540962741&entry.787941281&entry.1873343651
The questions from the form have a fixed identity, e.g. entry.1094330118. They may be pre-filled with a value (entry.1094330118=Something) or blank (entry.7879412).
In apps-script, I'd like to generate these pre-filled URLs for users of my form, so I can provide them for updates. My users are not members of an Apps Domain, so I don't have the option of embedding an Edit your response link.
If I can get the information about the form, I will be able to piece together the URL. While I can go through the UI to create one URL, and dissect it to get the info for that form, I want a solution that will work with arbitrary forms.
How can I programmatically determine the question IDs?
With the new
Forms product, is the form available to me through any apps-script
APIs? (I know about getFormURL() - that's not what I mean.)
Armed with a question ID, can I get more information about the question? (Question text, type, etc.)
I required something similar for users to go and edit their response, take a look here: http://productforums.google.com/forum/#!topic/docs/LSKKCR3VHC8
Copy / paste code below:
function assignEditUrls() {
var form = FormApp.openById('1MonO-uooYhARHsr0xxxxxxxxxxxxxxxxxxxxx');
//enter form ID here
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses');
//Change the sheet name as appropriate
var data = sheet.getDataRange().getValues();
var urlCol = 4; // column number where URL's should be populated; A = 1, B = 2 etc
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [];
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]:'']);
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
}
This is not possible right now but this request is being tracked on the Issue Tracker here. Please add your use cases there and watch it for updates.
I found no way to create a pre-filled URL from the form id itself. It is possible if the form has already an answer:
var form = FormApp.openById('1nGvvEzQHN1n-----_your_for_id_----zemoiYQA');
var responses = form.getResponses();
Logger.log(responses[0].toPrefilledUrl());
referring to this answer, it can be used to create prefilled urls, by replacing the last line like this:
instead of
FormResponse.submit();
it will be
FormResponse.toPrefilledUrl();