I am using google app script to create a form for uploading file. This is my Code.gs file:
var SPREADSHEET_FILE_ID = '1oQn6OLMzys8tVk1FLriOAmpzFJNazLRP-SwM7--eA58';
var folderId = "0B9TN_-yt-h0WZ0dnWndGWkw3UkE";
function doGet() {
var template = HtmlService.createTemplateFromFile('index');
// Build and return HTML in IFRAME sandbox mode.
return template.evaluate()
.setTitle('Web App Window Title')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
};
And I am using all other codes almost similar to the url https://script.google.com/d/125dG42eB9lM4SPq64p0dpR2CBH4ohfHiqu9TvFNM8s4Ra7pt-7kHXoTM/edit?usp=sharing.
I am getting the following error.
3402363213-mae_html_user_bin_i18n_mae_html_user.js:42 Uncaught ReferenceError: "doc" is not defined.
Can anyone please help why this error is coming and how to prevent this. No for is not being submitted. It is hanged after I click the button of submission.
Since the problem started when you added these values, I think you need to recheck them.
var SPREADSHEET_FILE_ID = '1oQn6OLMzys8tVk1FLriOAmpzFJNazLRP-SwM7--eA58';
var folderId = "0B9TN_-yt-h0WZ0dnWndGWkw3UkE";
var SPREADSHEET_FILE_ID is expecting an spreadsheet ID like "1386834576" where as you provided "1oQn6OLMzys8tVk1FLriOAmpzFJNazLRP-SwM7--eA58", which is wrong. I think you got that from something like "https://docs.google.com/forms/d/1BqxyEG8RhtlM3MNuSbln6C1L1GLl3axdiSEijcwB5gY/edit" that's why it's asking you "doc" is not defined.
Related
I have a button on a spreadsheet that I want users to click that will run a script. The script modifies some protected ranges so I published it as a web app and set it to run as me.
I found these instructions explaining what I am trying to accomplish:
You can create a function with the doGet() reserved function name in your project, and publish the project as a Web App. A link is a GET request. When you click the link, a GET request will be made to the published URL of the Web App. Then the doGet() function will run. The GET request is the "event" and the doGet() function is triggered by the GET request event. doGet() "listens" for the GET request to be made. You can pass information to the doGet(e) function by adding an "event" parameter in the parenthesis. Typically the letter "e" is used, but any letter can be used
My questions are once I have the web app url, how do I create a link that goes to the web app and runs it? Right now I am using a button on the spreadsheet and assigning a script to it. Screenshot of this: https://imgur.com/OeMlczb But this is not working.
And here is the code I turned into a web app that need to be called and ran when the button is clicked:
function confirm(){
var ui = SpreadsheetApp.getUi();
var response = ui.alert('This will submit the timesheet. Do you want to continue?', ui.ButtonSet.YES_NO);
if(response == ui.Button.NO) return;
emailGoogleSpreadsheetAsPDF();
}
/* Email Google Spreadsheet as PDF */
function emailGoogleSpreadsheetAsPDF() {
// Send the PDF of the spreadsheet to this email address
var email = "email#gmail.com";
var exclA=['Timesheet','Note','Settings','Data'];//and others
var timeS=SpreadsheetApp.getActive().getSheetByName('Timesheet')
var ss=SpreadsheetApp.getActive();
var name=ss.getRange("Timesheet!J6").getValue();//trimmed the range down to match the getValue();
var tname=ss.getRange("Timesheet!J6").getValue();
var agency=ss.getRange("Timesheet!B4").getValue();//same here
var fldr=DriveApp.getFolderById('abc123thu8h7r8888tbgyru');
var fA=[];
var today=Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM/dd/yyyy");
var subject=Utilities.formatString('%s has Submitted Their Timesheet and Notes',name);
var body=Utilities.formatString('This was submitted on %s',today);
var shts=ss.getSheets();
SpreadsheetApp.flush();//this may not be necessary...not sure
var file=fldr.createFile(ss.getBlob().getAs('application/pdf')).setName(Utilities.formatString('%s_%s_%s_timesheet_notes.pdf', tname,agency,today));
fA.push(file)
for(var i=0;i<shts.length;i++) {
var sh=shts[i];
var name=sh.getName();
if(exclA.indexOf(name)==-1) {
sh.showSheet();
for(var j=0;j<shts.length;j++) {
if(shts[j].getName()!=name) {
shts[j].hideSheet();
}
}
SpreadsheetApp.flush();//this may not be necessary...not sure
var file=fldr.createFile(ss.getBlob().getAs('application/pdf')).setName(Utilities.formatString('%s_%s_%s_note.pdf', name,agency,today));
fA.push(file);
}
}
for(var i=0;i<shts.length;i++) {
if(exclA.indexOf(shts[i].getName())==-1) {
shts[i].showSheet();
}
}
timeS.showSheet();
GmailApp.sendEmail(email,subject,body, {attachments:fA});
for(var i=0;i<fA.length;i++) {
fA[i].setTrashed(true);
}
//CopyDataToNewFile();
}
function makeCopy() {
var ss =SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Note');
var dSheet = sheet.copyTo(SpreadsheetApp.openById(ss.getId()))
dSheet.showSheet()
};
function CopyDataToNewFile(targetSheetName,targetSsId, sourceSheetName,sourceSsId) {
var ss = SpreadsheetApp.openById('gnu84uw84nwutnst9ntrgbrn').getSheetByName('Timesheet');
var ssd = SpreadsheetApp.openById('h3487g8bg8ybw4gy8wytb').getSheetByName('Sheet1');
var therapist = ss.getRange('J6').getValues();
var thedate = ss.getRange('A10').getValues();
var theagency = ss.getRange('B4:C4').getValues();
var thepayperiod = ss.getRange('B6:C6').getValues();
var thecost = ss.getRange('E24').getValues();
var themileage = ss.getRange('E27').getValues();
ssd.getRange(ssd.getLastRow()+1,1,therapist.length,therapist[0].length).setValues(therapist);
ssd.getRange(ssd.getLastRow()+0,2,thedate.length,thedate[0].length).setValues(thedate);
ssd.getRange(ssd.getLastRow()+0,3,theagency.length,theagency[0].length).setValues(theagency);
ssd.getRange(ssd.getLastRow()+0,4,thepayperiod.length,thepayperiod[0].length).setValues(thepayperiod);
ssd.getRange(ssd.getLastRow()+0,5,thecost.length,thecost[0].length).setValues(thecost);
ssd.getRange(ssd.getLastRow()+0,6,themileage.length,themileage[0].length).setValues(themileage);
}
I am just unsure how to structure this and any help is greatly appreciated, thank you!
A Link to a Webapp is just a bookmark in my browser
Here's a simple example of a webapp that I just put together for you.
html:(This is the user interface) It's all done in html and so there is a wide latitude of techniques that can be deployed here depending upon your knowledge of html, javascript, css etc.....
But this one just has one text box and one button and I didn't use any JQuery or other libraries. It's just basic old school JavaScript and html.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
window.onload=function() {
document.getElementById('hdg1').innerHTML="You are now connected to the server";
};
function runMyFunction() {
var txt=document.getElementById('txt1').value;
if(!txt) {
alert("You have not entered any text");
}else{
google.script.run
.withSuccessHandler(function(msg){
document.getElementById('msg1').innerHTML=msg;
})
.myFunction(txt);
}
}
console.log('aq4.html');
</script>
</head>
<body>
<h1 id="hdg1"></h1>
<input type="text" id="txt1" placeholder="Put some text here" />
<input type="button" value="myfunction" onclick="runMyFunction()" />
<div id="msg1"></div>
</body>
</html>
Google Script:
function myFunction(txt) {
return "<h1>I have received your message and ran myFunction():</h1><strong>" + txt + "</strong>";
}
function doGet() {
return HtmlService.createHtmlOutputFromFile('aq4');
}
The link that I was referring to is the simply the url of the web app and all you have to do is bookmark that url and then click on the bookmark from your browser. I describe that a little in this video
You have a problem because code runs 'as the user' (who has no access rights).
You talk as if deploying as a WEB APP to make code run with developer permissions is the only way to go. First of all, I know another way to go.
Deploy as WEB App may prove unsuitable or complex, for many situations, like yours, and mine.
I am new for a month working and the way I have found to execute code 'as ME' -developer- is having ME fire execution. That may get accomplished with installable triggers.
Please find in: Apps Scrip Guides listed under "Restrictions" this point. It says nothing about advantages. I found this point an advantage, because I don't need to give access rights to users on sensible tables !!!
Per my testings, I can .openById(...) and modify objects on which active user has no access rights. Just login as Permissions holding user to https://script.google.com/home and create the installable triggers needed. Code will then run as the user creating the trigger, with all his permissions.
I'm still looking for a simpler way to inherit access rights from developer (...or maybe an ad-hoc created user) to the code written. Or to stop some 'editors' of a Spreadsheet from viewing & modifying the code. But this is for another question.
I have a function launchForm within a Google Sheet which calls another function createForm with a single question. I get the URL of the newly created form and pass it into a sandbox Iframe using UrlFetchApp, as shown below:
function launchForm() {
var form = createForm(); // separate function that works fine
formUrl = form.getPublishedUrl()
var response = UrlFetchApp.fetch(formUrl,{"followRedirects" : true}); // true if automatic redirecting works
var formHtml = response.getContentText();
var htmlApp = HtmlService
.createHtmlOutput(formHtml)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL) // did this to prevent error but didn't help
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.show(htmlApp);
}
I have created a custom menu in sheets to run the launchForm function.
The trouble is, that the new form URL is at docs.google.com/a/, while the sheet is at docs.google.com/spreadsheets/d/...
This means that the iframe, instead of loading the form, opens up to a sign-in screen in when I (the creator of the form) tries to run it. When someone else with edit permissions runs the script, he sees the form as expected, but is then unable to make any inputs into the form.
I have read about CORS, X-frame-options, OAuth2, and nothing seems to provide the precise answer about what I must do. Any help will be much appreciated.
I'm was trying to show html body of gmail message in modal dialog window but faced an error calling SpreadsheetApp.getUi() method.
...
var html = HtmlService.createHtmlOutput(threads[i].getMessages()[0].getBody());
SpreadsheetApp.getUi().showModalDialog(html, 'My add-on');
...
How I can call that dialog? Or may be there is better aproach to display message(some panel or sidebar)?
This prompt box is misleading, as the error must be elsewhere. The new version of Sheets not only does support the getUI method, I believe it's specifically designed for for the new version of sheets.
I've expanded on your previous question and tested this myself with the following code in the new version of sheets:
function getMail() {
var threads = GmailApp.getInboxThreads();
var messages = threads[0].getMessages()[0];
var raw = messages.getPlainBody();
return raw;
}
function dialogueBox(){
var raw = getMail();
var htmlOutput = HtmlService.createHtmlOutput(raw);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'For mk_yo');
}
and it displays the prompt with no issues, as shown here. Try creating a new sheet with a new script and run the code above. Additionally, you can try ensuring that the sheet that you're adding this to is definitely using the new version of sheets.
In relation to if there's a better approach by displaying a side panel, yes you can use custom sidebars in the new version of Google sheets(and only the new version), but as this still uses the 'getUI' method, this won't resolve your current error, as this is not where the issue lies.
I have a script that I run from the menu of a google document. It essentially functions like this one: https://webapps.stackexchange.com/questions/47173/how-to-automatically-open-a-created-text-document-after-it-being-created/47649#47649.
I want a function that is similar the one in the link above except that the popup with the link is shown in a google doc rather than a google spreadsheet. That part of my script looks like this (title and url are defined above that part):
var docnew = DocumentApp.getActiveDocument();
var app = UiApp.createApplication().setTitle("Open Doc")
.setHeight(50).setWidth(400);
var vPanel = app.createVerticalPanel().add(app.createAnchor(title, url));
app.add(vPanel);
docnew.show(app);
I then get the following error. "TypeError: Funktion show in Objekt Document nicht gefunden", which is German and means "TypeError: Function show not found in object Document".
Can somebody help me with this?
Thanks a lot in advance.
Best,
Phil
The show method works only in spreadsheets, in Google Documents (and also in the new version of spreadsheets) you can use this code :
SpreadsheetApp.getUi().showModalDialog(argument);
The documentation shows some examples.
Your code snippet would be like this :
function showUi(){
var docnew = DocumentApp.getActiveDocument();
var app = UiApp.createApplication()
.setHeight(50).setWidth(400);
var vPanel = app.createVerticalPanel().add(app.createAnchor(title, url));
app.add(vPanel);
DocumentApp.getUi().showModelessDialog(app,"Open Doc");
}
I have a Google Spreadsheet that a form is linked to and all form responses are stored in. What I am trying to find is the ID of the FORM itself. I tried this but this does not work..
(I'm running the following code FROM The script editor IN the spreadsheet that the form is linked to.)
function getID()
{
var form = FormApp.getActiveForm();
var formID = form.getId();
Logger.log(formID);
}
That returns NULL since the script is container-bound to the spreadsheet itself. Is there any other way to get the ID of the linked form or even the URL of the linked form?
I can MANUALLY get it by doing the following from the Spreadsheet.
Form > Edit form
This will show me the URL.
IF I knew the NAME of the form I could get it by name using the DriveApp.getFilesByName(), iterate through it and then use the File.getId() but I don't necessarily know the name.
Any ideas?
To avoid parsing the url, the safest way would be:
Logger.log( (FormApp.openByUrl(SpreadsheetApp.getActiveSpreadsheet().getFormUrl())).getId() );
or long hand version:
function logFormId_LongHand(){
var formURL = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
var form = FormApp.openByUrl(formURL);
var formId = form.getId();
Logger.log( formId );
}
To get the form object in a spreadsheet app script I use the following function:
function getLinkedForm(){
return FormApp.openByUrl( SpreadsheetApp.getActiveSpreadsheet().getFormUrl() );
}
To anyone else who stumbles upon this: The new spreadsheets allow this. I've tried it already and it works for me. Here is how I get the ID:
var formUrl = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
var formID = formUrl.match(/[-\w]{25,}/);
I got the regex from this question: Easiest way to get file ID from URL on Google Apps Script
Hope this helps.
If you only want the Form ID for the attached Form, and don't need to keep the Form URL for any reason, this one-liner should suffice:
var formID = SpreadsheetApp.getActiveSpreadsheet().getFormUrl().match(/\/d\/(.{25,})\//)[1];
Yes.
It would be a script like this that would be ran from within the spreadsheet:
function getFormUrl()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formUrl = ss.getFormUrl();
Logger.log(formUrl);
}
However, if you try and run this in the new spreadsheets you receive this error message:
The api method 'getFormUrl' is not available yet in the new version of Google Sheets.
So, until they add support it will only work in older versions.
You can also find out / connect to the original form from the "Help" menu. Type form and then click "Edit Form." It will locate the original form. This was helpful when a search in drive was unsuccessful through the name of the form (???). So if you need the original editable form for whatever reason, can't find it, and have the linked Sheets doc, then you can now backtrack and go from there. :)