Display Form in Sidebar - google-apps-script

I am not sure if what I am trying to do is even possible.
I am trying to put a google form into the sidebar of a google doc.
Right now I have an apps script document plugin that opens the sidebar fine, and I am able to open the form using var form = FormApp.openById('form_id');
But I don't know how to get a html object or blob from a form element that I could use to embed the form in the sidebar.
I also can't use iframes as those are disallowed.

While you can display a google form in a sidebar in a spreadsheet/document (see sample code below), there is one significant gotcha with it: the form does not work, i.e. you can't submit the form. Not sure exactly why, but my guess it is due to the sandbox restrictions and/or caja sanitization.
I suggest you code your own form using HTML and HTML Service (or UI Service) and show that in a sidebar. If you need you form to save the responses to a spreadsheet, you can also do that rather easily. See this for more on info and code samples of using forms in HTML Service and this for using forms in UI Service. Your server-side script can open a spreadsheet and write form values to it, if that's what you need to do.
Sample code for an Add-on to show Google Form in a Sidebar in Google Sheet:
NOTE: The form does not actually work - it does not submit when shown in a sidebar!
function showFormInSidebar() {
var form = FormApp.openById('YOUR-FORM-ID-HERE');
var formContent = UrlFetchApp.fetch(form.getPublishedUrl()).getContentText();
var ui = HtmlService.createHtmlOutput(formContent).setTitle("Google Form in Sidebar Example");
SpreadsheetApp.getUi().showSidebar(ui);
};
function onOpen(e) {
// Add this add-on to Add-ons menu
SpreadsheetApp.getUi().createAddonMenu()
.addItem('Show form', 'showFormInSidebar')
.addToUi();
};

Related

How to show the Load Indicator while running the google app script

How to show the Load Indicator while running the google app script
If you want to stop the interaction with the sheets while the image is showing and the is executing you could try to use the UI method showModalDialog().
So something like this would do the trick for what you are trying to achieve:
function showDialog() {
var ui = SpreadsheetApp.getUi();
// Display a modal dialog box with custom HtmlService content.
var htmlOutput = HtmlService
.createHtmlOutput('<img src=https://i.stack.imgur.com/AuqJU.gif>')
.setWidth(250)
.setHeight(300);
ui.showModalDialog(htmlOutput, 'Script Running');
}
If you want to have more control over the closing of the dialog you will need to do it from the client side. Modifying the HTML object inside the showModalDialog(). In case you are interested in that I would suggest to take a look into this question.
You can also check the Apps Script documentation about dialogs and other UI elements.

Displaying a Google form on sheets

I am creating a form for users to input information on a Google spreadsheet. They will access the spreadsheet and then click on an image that is linked to a script. When the image is clicked, I want a form to appear. Then I want the input from the form to be accessible in the script.
I am able to create a form but the form does not appear on the sheet. Here is the code thus far for the GS script
function startForm() {
var form = FormApp.create('myForm');
var item = form.addCheckboxItem();
item.setTitle('What would you like to do?');
item.setChoices([
item.createChoice('Budget Inquiry'),
item.createChoice('Add Purchase')
]);
var choices = item.getChoices();
// then I can respond to the user's choice
}
I would like this simple form to just appear on the google sheet. Any input would be appreciated.
Instead of creating you own form with script, just go to the insert menu of your spreadsheet and select form. Enter you question and your two choices. Close the form. You will see a form response sheet created in your spreadsheet. Also, a menu item Form will appear on your menu. Then go to the script editor and from the menu select Resources. Select Current Project Triggers and set a new trigger for onFormSubmit. You can then enter a function onFormSubmit to do whatever you want done when the form is submitted getting data from the form response sheet. There is plenty of documentation you can Google.
The way in Google Sheets to display external content other than images and Google Drawings is by creating a dialog or sidebar with the related content embeded.
There is a similar question that includes an answer that shows how to do this:
Single Google Form for multiple Sheets

Attach a google form to a google spreadsheet

I'd like to create a form by google script.
This is pretty easy but I'd like to attached this form to a spreadsheet (no only the response), like I would have created it by the UI.
Is that possible ? Given the Formclass or FormApp is doesn't seem so. Is there a way around ?
EDIT: My goal was to create the form with the script and having the same result as if the user had had the form created from the UI interface (the main difference being having the form menu in the SS UI). It's apparently not possible.
You're right - it's pretty easy once you have the trick. Use FormApp to get the published URL of the form, UrlFetch to grab its html, then the HtmlService to present the form in the spreadsheet's UI.
See Single Google Form for multiple Sheets.

Google Forms, sidebar for live form

I would like to create a sidebar to a live google form, ideally in order to pick from a (google) map coordinates to be entered in the form.
From the documentation and from my trials I can create a sidebar to the form editor/designer (https://docs.google.com/forms/d/ID/edit), not the live form itself (https://docs.google.com/forms/d/ID/viewform). Forms are different in regard to the Doc and Sheet Apps, that there exist these two views.
For example:
function onOpen() {
var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
.setTitle('Maps');
FormApp.getUi().showSidebar(ui);
}
First problem is that the trigger for onOpen() fires when opening the form designer, not when the end user will open the form (/viewform URL) to fill it out.
Then FormApp.getUI().showSidebar(ui); gets the UI of the forms designer and opens up a sidebar there and not in the Form the end user has to fill out.
Documentation seems to confirm this.
So, is it possible to get access to the live form, including any associated triggers?
So, is it possible to get access to the live form, including any
associated triggers?
No
However, you could embed your form in a page that also hosts the map in a separate frame, enabling users to browse the map, click to see coordinates, and then copy them to the form. There would be no interaction between the google-hosted form and the map.

Single Google Form for multiple Sheets [duplicate]

This question already has answers here:
Google Forms embedded in Google Sheets Unclickable - CORS conflict
(2 answers)
Closed 2 years ago.
Due to ongoing development versioning, plus seemingly insurmountable problems implementing user permissions workarounds, I need to capture form data linked to a sheet which is not exposd to the users. Instead I want to launch the form from a separate spreadsheet app using a custom menu. Yet despite thorough Google searches, and the tantalizingly named 'FormApp.openById' method, I can't find a way to accomplish this.
I know I'm off track here; could anyone please point me to the way back?
Step 1: Create Form
Normal operating procedure - create your form either through a script or using the Forms UI. Capture the ID of the form. For instance, from the URL when in the editor:
https://docs.google.com/forms/d/1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ/edit
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Attach a spreadsheet to capture responses. (We're not going to do anything more with that here.)
Step 2: Client Script
In the user-accessible spreadsheet, create a container-bound script (so it has access to the Spreadsheet UI). The following script produces a custom menu with a selection that launches a form in a Ui popup.
/**
* Uses the Forms service to get a handle on an existing form, then retrieve its published URL.
* Uses the UrlFetch Service to get a copy of the HTML for the form.
* Uses the HtmlService to embed the form's HTML in a Spreadsheet UI.
* ... which is finally shown using Spreadsheet.show().
*/
function launchForm() {
var formID = '1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ';
var form = FormApp.openById(formID);
var formUrl = form.getPublishedUrl();
var response = UrlFetchApp.fetch(formUrl);
var formHtml = response.getContentText();
var htmlApp = HtmlService
.createHtmlOutput(formHtml)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Ta Daaa!')
.setWidth(500)
.setHeight(450);
SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
}
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Launch Form",
functionName : "launchForm"
}];
sheet.addMenu("Custom Menu", entries);
};
Demo
Here's what you see when you select "Launch Form" from the "Custom Menu". One little annoyance, though - when the form is submitted, the user is taken to another browser window or tab. In the spreadsheet, the UI remains open, and needs to be manually closed. That problem is gone with IFRAME sandboxing!
EDIT: Changes in the ECMA sandbox defaults were introduced recently, which require that the sandbox mode be explicitly set to NATIVE for this technique to work. Code has been updated.
EDIT Again: The newer IFRAME sandbox mode keeps the whole form experience inside the dialog.
Mogsdad got me on the right track, but in order for the submit button to work, I had to embed it directly in the code.
1) Create a form and in the forms menu, select "Embed form in a webpage"
2) Copy the entire block of code that appears. It should look similar to this:
<iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>
3) Add this function to your script page
function launchForm() {
var embeddedHtml = '<iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>'
var htmlApp = HtmlService.createHtmlOutput(embeddedHtml)
SpreadsheetApp.getUi().showModalDialog(htmlApp, 'Title');
}
If you'd like the formatting and banner of your form to stay, remove the ?embedded=true off of the embedded link https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true