How to recover apps scripts if they were deleted? [closed] - google-apps-script

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
My apps script was suddenly deleted and i couldn't locate any logs within the revision history. Any idea if there are ways I could recover the scripts?

Here's how I backup my scripts:
function saveScriptBackupsDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('backupscripts1'), 'Script Files Backup Dialog');
}
function scriptFilesBackup(obj) {
console.log(JSON.stringify(obj));
var scriptId = obj.script.trim();
var folderId = obj.folder.trim();
var saveJson = obj.saveJson;
var saveFiles = obj.saveFiles;
var all = true;
var fA = [];
if (obj.selected.length > 0) {
all = false;
fA = String(obj.selected).split(',').map(n => n.trim());
}
if (scriptId && folderId) {
const base = "https://script.googleapis.com/v1/projects/"
const url1 = base + scriptId + "/content";
const url2 = base + scriptId;
const options = { "method": "get", "muteHttpExceptions": true, "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
const res1 = UrlFetchApp.fetch(url1, options);
const data1 = JSON.parse(res1.getContentText());
const files = data1.files;
const folder = DriveApp.getFolderById(folderId);
const res2 = UrlFetchApp.fetch(url2, options);
const data2 = JSON.parse(res2.getContentText());
let dts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyyMMdd-HH:mm:ss");
let subFolderName = Utilities.formatString('%s-%s', data2.title, dts);
let subFolder = folder.createFolder(subFolderName)
console.log(all);
if (saveFiles) {
files.forEach(file => {
if (file.source && file.name) {
let ext = (file.type == "HTML") ? ".html" : ".gs";
if (!all) {
if (fA.indexOf(file.name) > -1) {
subFolder.createFile(file.name + ext, file.source, MimeType.PLAIN_TEXT)
}
} else {
subFolder.createFile(file.name + ext, file.source, MimeType.PLAIN_TEXT)
}
}
});
}
if (saveJson) {
subFolder.createFile(subFolderName + '_JSON', res1, MimeType.PLAIN_TEXT)
}
}
return { "message": "Process Complete" };
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>input{margin:2px 5px 2px 0;}</style>
</head>
<body>
<form>
<input type="text" id="scr" name="script" size="60" placeholder="Enter Apps Script Id" />
<br /><input type="text" id="fldr" name="folder" size="60" placeholder="Enter Backup Folder Id" />
<br /><input type="text" id="sltd" name="selected" size="60" placeholder ="Enter Desired Files separated by commas or nothing if you want all files." />
<br /><input type="checkbox" id="files" name="saveFiles"/><label for="files">Save Files</label>
<br /><input type="checkbox" id="json" name="saveJson" checked /><label for="json">Save JSON</label>
<br /><input type="button" value="Submit" onClick="backupFiles(this.parentNode);" />
</form>
<script>
function backupFiles(obj) {
google.script.run
.withSuccessHandler(function(obj){google.script.host.close();})
.scriptFilesBackup(obj);
console.log(JSON.stringify(obj));
}
</script>
</body>
</html>

Related

Script for selecting sheets using control

I have in a spreadsheet, a MENU with buttons linked to other sheets.
Since I have many sheets, I want that when selecting a button it is the same for a group of those sheets.
Ex: btn "Enter approved teachers", there are 4 sheets that are to enter that data, each one corresponds to a different area.
That when I click on this button, I skip a "popup" that shows me a list of that sheets and lets me select it with an "OK".
The part of selecting the sheet with a script is easy to do with a youtube tutorial, but the control of sheets and selection I can not find anywhere.
I haven't been able to try anything, as I don't have experience coding in Apps Script or Js.
Hopefully this is close to what you are looking for:
This a dialog I use for selecting which files I wish to backup from my spreadsheets.
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
input {margin: 2px 5px 2px 0;}
#btn3,#btn4{display:none}
</style>
</head>
<body>
<form>
<input type="text" id="scr" name="script" size="60" placeholder="Enter Apps Script Id" onchange="getFileNames();" />
<br /><input type="text" id="fldr" name="folder" size="60" placeholder="Enter Backup Folder Id" />
<div id="shts"></div>
<br /><input type="button" value="0" onClick="unCheckAll();" size="15" id="btn3" />
<input type="button" value="1" onClick="checkAll();"size="15" id="btn4"/>
<br /><input type="checkbox" id="files" name="saveFiles" checked /><label for="files">Save Files</label>
<br /><input type="checkbox" id="json" name="saveJson" checked /><label for="json">Save JSON</label>
<br /><input type="button" value="Submit" onClick="backupFiles();" />
</form>
<script>
function getFileNames() {
const scriptid = document.getElementById("scr").value;
google.script.run
.withSuccessHandler((names) => {
document.getElementById('btn3').style.display = "inline";
document.getElementById('btn4').style.display = "inline";
names.forEach((name,i) => {
let br = document.createElement("br");
let cb = document.createElement("input");
cb.type = "checkbox";
cb.id = `cb${i}`;
cb.name = `cb${i}`;
cb.className = "cbx";
cb.value = `${name}`;
cb.checked = true;
let lbl = document.createElement("label");
lbl.htmlFor = `cb${i}`;
lbl.appendChild(document.createTextNode(`${name}`));
document.getElementById("shts").appendChild(cb);
document.getElementById("shts").appendChild(lbl);
document.getElementById("shts").appendChild(br);
});
})
.getAllFileNames({scriptId:scriptid});
}
function unCheckAll() {
let btns = document.getElementsByClassName("cbx");
console.log(btns.length);
for(let i =0;i<btns.length;i++) {
btns[i].checked = false;
}
}
function checkAll() {
let btns = document.getElementsByClassName("cbx");
console.log(btns.length)
for(let i = 0;i<btns.length;i++) {
btns[i].checked = true;
}
}
function backupFiles() {
console.log('backupFiles');
sObj = {};
sObj.script = document.getElementById('scr').value;
sObj.folder = document.getElementById('fldr').value;
sObj.saveJson = document.getElementById('json').checked?'on':'';
sObj.saveFiles = document.getElementById('files').checked?'on':'';
sObj.selected = [];
console.log("1");
const cbs = document.getElementsByClassName("cbx");
let selected = [];
for(let i = 0;i<cbs.length; i++) {
let cb = cbs[i];
if(cb.checked) {
sObj.selected.push(cb.value)
}
}
console.log("2");
google.script.run
.withSuccessHandler(function(obj){google.script.host.close();})
.scriptFilesBackup(sObj);
console.log(JSON.stringify(sObj));
}
</script>
</body>
</html>
This is what the dialog looks like:

How to reference one apps script file from another

I have multiple files in my apps script project. Some of them are library files that provide utility functions for a larger app. How can I import them into my main file?
For example, in Node, I would be able to import update-cell-1.gs and update-cell-2.gs into my main.gs file like this:
// update-cell-1.gs
export default function() {
// code to update cell 1
}
// update-cell-2.gs
export default function() {
// code to udpate cell 2
}
// main.gs
import updateCell1 from "update-cell-1.gs";
import updateCell2 from "update-cell-2.gs";
function main() {
updateCell1();
updateCell2();
}
main();
What is the equivalent in apps script?
When I try using module.exports, I get this error:
ReferenceError: module is not defined
When I try using export default, I get this error:
SyntaxError: Unexpected token 'export'
Unlike node.js or js web frameworks, You can call any function in any file in the same script project directly without exporting or importing anything. However, the order of the files matter.
Here's a script that backs up all of the files in a script project.
You can choose either separate files or all one JSON file. You can also select which files that you wish to save.
GS:
function saveScriptBackupsDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('backupscripts1'), 'Script Files Backup Dialog');
}
function scriptFilesBackup(obj) {
console.log(JSON.stringify(obj));
const scriptId = obj.script.trim();
const folderId = obj.folder.trim();
const saveJson = obj.saveJson;
const saveFiles = obj.saveFiles;
const fA = obj.selected;
if (scriptId && folderId) {
const base = "https://script.googleapis.com/v1/projects/"
const url1 = base + scriptId + "/content";
const url2 = base + scriptId;
const options = { "method": "get", "muteHttpExceptions": true, "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
const res1 = UrlFetchApp.fetch(url1, options);
const data1 = JSON.parse(res1.getContentText());
const files = data1.files;
const folder = DriveApp.getFolderById(folderId);
const res2 = UrlFetchApp.fetch(url2, options);
const data2 = JSON.parse(res2.getContentText());
let dts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyyMMdd-HH:mm:ss");
let subFolderName = Utilities.formatString('%s-%s', data2.title, dts);
let subFolder = folder.createFolder(subFolderName);
if (saveFiles) {
files.forEach(file => {
if (file.source && file.name) {
let ext = (file.type == "HTML") ? ".html" : ".gs";
if (~fA.indexOf(file.name)) {
subFolder.createFile(file.name + ext, file.source, MimeType.PLAIN_TEXT)
}
}
});
}
if (saveJson) {
subFolder.createFile(subFolderName + '_JSON', res1, MimeType.PLAIN_TEXT)
}
}
return { "message": "Process Complete" };
}
function getAllFileNames(fObj) {
if (fObj.scriptId) {
const base = "https://script.googleapis.com/v1/projects/"
const url1 = base + fObj.scriptId + "/content";
const options = { "method": "get", "muteHttpExceptions": true, "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
const r = UrlFetchApp.fetch(url1, options);
const data = JSON.parse(r.getContentText());
const files = data.files;
const names = files.map(file => file.name);
return names;
}
}
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
input {margin: 2px 5px 2px 0;}
#btn3,#btn4{display:none}
</style>
</head>
<body>
<form>
<input type="text" id="scr" name="script" size="60" placeholder="Enter Apps Script Id" onchange="getFileNames();" />
<br /><input type="text" id="fldr" name="folder" size="60" placeholder="Enter Backup Folder Id" />
<div id="shts"></div>
<br /><input type="button" value="0" onClick="unCheckAll();" size="15" id="btn3" />
<input type="button" value="1" onClick="checkAll();"size="15" id="btn4"/>
<br /><input type="checkbox" id="files" name="saveFiles" checked /><label for="files">Save Files</label>
<br /><input type="checkbox" id="json" name="saveJson" checked /><label for="json">Save JSON</label>
<br /><input type="button" value="Submit" onClick="backupFiles();" />
</form>
<script>
function getFileNames() {
const scriptid = document.getElementById("scr").value;
google.script.run
.withSuccessHandler((names) => {
document.getElementById('btn3').style.display = "inline";
document.getElementById('btn4').style.display = "inline";
names.forEach((name,i) => {
let br = document.createElement("br");
let cb = document.createElement("input");
cb.type = "checkbox";
cb.id = `cb${i}`;
cb.name = `cb${i}`;
cb.className = "cbx";
cb.value = `${name}`;
cb.checked = true;
let lbl = document.createElement("label");
lbl.htmlFor = `cb${i}`;
lbl.appendChild(document.createTextNode(`${name}`));
document.getElementById("shts").appendChild(cb);
document.getElementById("shts").appendChild(lbl);
document.getElementById("shts").appendChild(br);
});
})
.getAllFileNames({scriptId:scriptid});
}
function unCheckAll() {
let btns = document.getElementsByClassName("cbx");
console.log(btns.length);
for(let i =0;i<btns.length;i++) {
btns[i].checked = false;
}
}
function checkAll() {
let btns = document.getElementsByClassName("cbx");
console.log(btns.length)
for(let i = 0;i<btns.length;i++) {
btns[i].checked = true;
}
}
function backupFiles() {
console.log('backupFiles');
sObj = {};
sObj.script = document.getElementById('scr').value;
sObj.folder = document.getElementById('fldr').value;
sObj.saveJson = document.getElementById('json').checked?'on':'';
sObj.saveFiles = document.getElementById('files').checked?'on':'';
sObj.selected = [];
console.log("1");
const cbs = document.getElementsByClassName("cbx");
let selected = [];
for(let i = 0;i<cbs.length; i++) {
let cb = cbs[i];
if(cb.checked) {
sObj.selected.push(cb.value)
}
}
console.log("2");
google.script.run
.withSuccessHandler(function(obj){google.script.host.close();})
.scriptFilesBackup(sObj);
console.log(JSON.stringify(sObj));
}
</script>
</body>
</html>
There maybe some helper functions that I'm missing let me know. I use this all of the time to backup my code.
A typical back up looks like this:

Deleting trigger auto-deleted my script project

When I deleted my only trigger (set to run daily) it took all of my script code with it!
When I now go into Tools/Script Editor it shows a blank project (not the saved code I've been working on for a month!)
Restoring previous versions of the spreadsheet doesn't work and I am using the account that I created it in.
I don't know where Sheets automatically stores the .gs files (they don't show on my Drive) but I'm hoping it still exists on their servers and it's just the link to it from the spreadsheet got broken and can be restored.
Please help as I do not want to start from scratch again 🙏
Here is a script that I use for backing up my files as both separate files and one big JSON file. It won't help you fix your current problem but you can use to avoid it in the future and unlike backing up the entire spreadsheet and creating another unnecessary project, they get saved as ascii text files.
function saveScriptBackupsDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('backupscripts1'), 'Script Files Backup Dialog');
}
function scriptFilesBackup(obj) {
console.log(JSON.stringify(obj));
const scriptId = obj.script.trim();
const folderId = obj.folder.trim();
const saveJson = obj.saveJson;
const saveFiles = obj.saveFiles;
const fA = obj.selected;
if (scriptId && folderId) {
const base = "https://script.googleapis.com/v1/projects/"
const url1 = base + scriptId + "/content";
const url2 = base + scriptId;
const options = { "method": "get", "muteHttpExceptions": true, "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
const res1 = UrlFetchApp.fetch(url1, options);
const data1 = JSON.parse(res1.getContentText());
const files = data1.files;
const folder = DriveApp.getFolderById(folderId);
const res2 = UrlFetchApp.fetch(url2, options);
const data2 = JSON.parse(res2.getContentText());
let dts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyyMMdd-HH:mm:ss");
let subFolderName = Utilities.formatString('%s-%s', data2.title, dts);
let subFolder = folder.createFolder(subFolderName);
if (saveFiles) {
files.forEach(file => {
if (file.source && file.name) {
let ext = (file.type == "HTML") ? ".html" : ".gs";
if (~fA.indexOf(file.name)) {
subFolder.createFile(file.name + ext, file.source, MimeType.PLAIN_TEXT)
}
}
});
}
if (saveJson) {
subFolder.createFile(subFolderName + '_JSON', res1, MimeType.PLAIN_TEXT)
}
}
return { "message": "Process Complete" };
}
The html for the dialog:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
input {margin: 2px 5px 2px 0;}
#btn3,#btn4{display:none}
</style>
</head>
<body>
<form>
<input type="text" id="scr" name="script" size="60" placeholder="Enter Apps Script Id" onchange="getFileNames();" />
<br /><input type="text" id="fldr" name="folder" size="60" placeholder="Enter Backup Folder Id" />
<div id="shts"></div>
<br /><input type="button" value="0" onClick="unCheckAll();" size="15" id="btn3" />
<input type="button" value="1" onClick="checkAll();"size="15" id="btn4"/>
<br /><input type="checkbox" id="files" name="saveFiles" checked /><label for="files">Save Files</label>
<br /><input type="checkbox" id="json" name="saveJson" checked /><label for="json">Save JSON</label>
<br /><input type="button" value="Submit" onClick="backupFiles();" />
</form>
<script>
function getFileNames() {
const scriptid = document.getElementById("scr").value;
google.script.run
.withSuccessHandler((names) => {
document.getElementById('btn3').style.display = "inline";
document.getElementById('btn4').style.display = "inline";
names.forEach((name,i) => {
let br = document.createElement("br");
let cb = document.createElement("input");
cb.type = "checkbox";
cb.id = `cb${i}`;
cb.name = `cb${i}`;
cb.className = "cbx";
cb.value = `${name}`;
cb.checked = true;
let lbl = document.createElement("label");
lbl.htmlFor = `cb${i}`;
lbl.appendChild(document.createTextNode(`${name}`));
document.getElementById("shts").appendChild(cb);
document.getElementById("shts").appendChild(lbl);
document.getElementById("shts").appendChild(br);
});
})
.getAllFileNames({scriptId:scriptid});
}
function unCheckAll() {
let btns = document.getElementsByClassName("cbx");
console.log(btns.length);
for(let i =0;i<btns.length;i++) {
btns[i].checked = false;
}
}
function checkAll() {
let btns = document.getElementsByClassName("cbx");
console.log(btns.length)
for(let i = 0;i<btns.length;i++) {
btns[i].checked = true;
}
}
function backupFiles() {
console.log('backupFiles');
sObj = {};
sObj.script = document.getElementById('scr').value;
sObj.folder = document.getElementById('fldr').value;
sObj.saveJson = document.getElementById('json').checked?'on':'';
sObj.saveFiles = document.getElementById('files').checked?'on':'';
sObj.selected = [];
console.log("1");
const cbs = document.getElementsByClassName("cbx");
let selected = [];
for(let i = 0;i<cbs.length; i++) {
let cb = cbs[i];
if(cb.checked) {
sObj.selected.push(cb.value)
}
}
console.log("2");
google.script.run
.withSuccessHandler(function(obj){google.script.host.close();})
.scriptFilesBackup(sObj);
console.log(JSON.stringify(sObj));
}
</script>
</body>
</html>
If you want the restore just ask. I haven't used it that much I usually the file that I need and paste past it in.

Google Scripts HtmlService returns undefined form data

I am trying to create a web app whereby a user fills out a form and the data gets populated into a google sheet. My problem is after I fill out the form the sheet gets populated with undefined data.
How do I define this data and append to a new row each time I fill out the form.
Example was taken from here.
Code.gs
function doGet(e){
return handleResponse(e);
}
var SHEET_NAME = "Sheet1";
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
function handleResponse(e) {
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return HtmlService.createHtmlOutputFromFile('index');
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
var $form = $('form#test'),
url = 'https://...';
$('#submit-form').on('click', function(e) {
e.preventDefault();
var jqxhr = $.ajax({
url: url,
method: "GET",
dataType: "json",
data: $form.serializeObject()
}).success(
// do something
);
})
</script>
</head>
<body>
<form id="test">
<p><label>ID</label>
<input type="number" name="ID"/></p>
<p><label>Part Number</label>
<input type="text" name="Part Number"/></p>
<p><label>Description</label>
<input type="text" name="Description"/></p>
<p><label>Item Link</label>
<input type="url" name="Item Link"/></p>
<p><label>Supplier</label>
<input type="text" name="Supplier"/></p>
<p><label>Manufacturer</label>
<input type="text" name="Manufacturer"/></p>
<p><label>Pins</label>
<input type="number" name="Pins"/></p>
<p><label>Size</label>
<input type="text" name="Size"/></p>
<p><label>Order Number</label>
<input type="number" name="Order Number"/></p>
<p><label>Location</label>
<input type="text" name="Location"/></p>
<p><input type="submit" value="submit-form"/></p>
</form>
</body>
</html>
Since you've borrowed code from another site it seems overly complicated for my taste. Here is a simpler solution IMHO. I don't see parameter e used anywhere so i removed. Also the use of html form is not needed but I left it as is
Code.gs
function doGet(){
try {
return HtmlService.createHtmlOutputFromFile("HTML_Test");
}
catch(err) {
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": err}))
.setMimeType(ContentService.MimeType.JSON);
}
}
function submitData(data) {
var shid = "your spreadsheet id here";
var ss = SpreadsheetApp.openById(shid);
var sh = ss.getSheetByName("Sheet1");
try {
sh.getRange(sh.getLastRow()+1,1,1,data.length).setValues([data]);
return "success"
}
catch(err) {
sh.getRange(sh.getLastRow()+1,1).setValue(err);
return err;
}
}
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="test">
<p><label>ID</label>
<input type="number" id="ID"/></p>
<p><label>Part Number</label>
<input type="text" id="Part Number"/></p>
<p><label>Description</label>
<input type="text" id="Description"/></p>
<p><label>Item Link</label>
<input type="url" id="Item Link"/></p>
<p><label>Supplier</label>
<input type="text" id="Supplier"/></p>
<p><label>Manufacturer</label>
<input type="text" id="Manufacturer"/></p>
<p><label>Pins</label>
<input type="number" id="Pins"/></p>
<p><label>Size</label>
<input type="text" id="Size"/></p>
<p><label>Order Number</label>
<input type="number" id="Order Number"/></p>
<p><label>Location</label>
<input type="text" id="Location"/></p>
<p><input type="button" value="Submit" onclick="submitForm()"/></p>
</form>
<script>
function submitForm() {
try {
var data = [];
data.push(document.getElementById("ID").value);
data.push(document.getElementById("Part Number").value);
data.push(document.getElementById("Description").value);
data.push(document.getElementById("Item Link").value);
data.push(document.getElementById("Supplier").value);
data.push(document.getElementById("Manufacturer").value);
data.push(document.getElementById("Pins").value);
data.push(document.getElementById("Size").value);
data.push(document.getElementById("Order Number").value);
data.push(document.getElementById("Location").value);
google.script.run.withSuccessHandler(success).submitData(data);
}
catch(err) {
alert(err);
}
}
function success(msg) {
alert(msg);
}
</script>
</body>
</html>

Validation from submitting in Apps Script

Please I need help. I have the same need of this post. I followed the instructions but I can't find my error. I'm frustratred.
When I submit with null fields, the script shows me a blank page.
When I submit with complete fields, the script shows me a blank page also and never upload the file.
This is my final code:
code.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(form) {
try {
var dropbox = "NHD Papers";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var blob = form.myFile;
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.myName + ", Division: " + form.myDivision + ", School: " + form.mySchool + ", State: " + form.myState);
return "<h2>File uploaded successfully!</h2><p>Copy and paste the following URL into registration:<br /><br /><strong>" + file.getUrl() + '</strong></p>';
} catch (error) {
return error.toString();
}
}
form.html
<p>
<form id="myForm" onsubmit="validateForm();">
<h1>NHD Paper Upload</h1>
<label>Name</label>
<input type="text" name="myName" class="required" placeholder="Enter your full name..">
<label>Division</label>
<input type="text" name="myDivision" class="required" placeholder="(ex. Junior or Senior)">
<label>School</label>
<input type="text" name="mySchool" class="required" placeholder="Enter your school..">
<label>Affiliate</label>
<input type="text" name="myAffiliate" class="required" placeholder="Enter your affiliate..">
<label>Select file to upload. </label>
<input type="file" name="myFile">
<input type="submit" value="Submit File" >
<br />
</form>
</p>
<div id="output"></div>
<script>
function validateForm() {
var x=document.getElementsByClassName('required');
for(var i = 0; i <x.length; i++){
if (x[i].value == null || x[i].value == "")
{
alert("All fields must be filled out.");
return false;
}
this.value='Please be patient while your paper is uploading..';
var myFormObject = document.getElementById('myForm');
google.script.run.withSuccessHandler(fileUploaded)
.uploadFiles(myFormObject);
}
}
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
input { display:block; margin: 15px; }
p {margin-left:20px;}
</style>
Regards,
In the IFRAME mode HTML forms are allowed to submit, but if the form has no action attribute it will submit to a blank page.
The solution suggested by the official documentation is to add the following JavaScript code to prevent all form submitions on load:
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
</script>
You can also add a return false; or event.preventDefault() at the end of your validateForm() function.