Error When Calling from Spreadsheet, works fine from menu [duplicate] - google-apps-script

This question already has an answer here:
No permission to call msgBox in Google Apps Scripting
(1 answer)
Closed 6 years ago.
So I did some work with Google Apps Scripts when they were first released, but I haven't worked with them much lately. This morning, I decided to develop a new script. Everything looks great and I love the new features. However, one very simple thing that worked before is now broken (or I'm just dumb).
When I call a particular function from a menu, it works fine. But when I call it from the spreadsheet directly I get:
You do not have permission to call inputBox (line 17)
What's weird is that I'm not even calling an inputBox. There is a set of events where an input box can be invoked but only if a particular variable isn't set (global) which in this case it is set.
I thought that maybe I just had a bug. So, I looked at my old apps scripts (which at one time were definitely working). And I'm now getting the same problem. So, whatever changed it has broken old scripts as well. For completeness, I'm now including my script code. The functions I'm trying to call directly are Pipeline and Activity:
var webhookurl = "";
var jsondata = [];
function __urlCheck_(str) {
var v = new RegExp();
v.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
if (!v.test(str)) {
return false;
}
return true;
}
function __getWebHook_(){
var newwebhookurl = UserProperties.getProperty('webhookurl_HCR');
if((newwebhookurl == null || newwebhookurl.length==0) && (webhookurl.length==0 || webhookurl==null)){
var newwebhookurl = Browser.inputBox("Paste your web hook url here");
var newwebhookurl = newwebhookurl.replace(/^\s*/, '').replace(/\s*$/, '');
if('cancel' == newwebhookurl.toLowerCase()){
Browser.msgBox('Before this connection will work, you will have to enter a webhook url.');
}else if(newwebhookurl.length==0 || newwebhookurl == null || __urlCheck_(newwebhookurl) == false){
Browser.msgBox('Sorry, you must specify a webhook url.');
__getWebHook_();
}else{
UserProperties.setProperty('webhookurl_HCR',newwebhookurl);
webhookurl = newwebhookurl;
}
}else if(webhookurl.length==0 || webhookurl==null){
webhookurl = newwebhookurl;
}
}
function __ClearWebHook_(){
UserProperties.setProperty('webhookurl_HCR','');
webhookurl = '';
__getWebHook_();
}
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{name: "Pipeline", functionName: "__PipelineMenu__"},
{name: "Activity", functionName: "__ActivityMenu__"},
{name: "Reset WebHook", functionName: "__ClearWebHook_"}
];
ss.addMenu("Heap CRM Reports", menuEntries);
}
function onInstall(){
onOpen();
}
function __PipelineMenu__(){
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var myapp = UiApp.createApplication().setTitle('Pipeline');
var mygrid = myapp.createGrid(5, 2);
mygrid.setWidget(0, 0, myapp.createLabel('Category:'));
mygrid.setWidget(0, 1, myapp.createTextBox().setName('category'));
mygrid.setWidget(1, 0, myapp.createLabel('Label:'));
mygrid.setWidget(1, 1, myapp.createTextBox().setName('label'));
mygrid.setWidget(2, 0, myapp.createLabel('User:'));
mygrid.setWidget(2, 1, myapp.createTextBox().setName('user'));
mygrid.setWidget(3, 0, myapp.createLabel('Type:'));
var lbt = myapp.createListBox(false).setName('type');
lbt.setVisibleItemCount(1);
lbt.addItem('Lead');
lbt.addItem('Opportunity');
lbt.addItem('Customer');
mygrid.setWidget(3, 1, lbt);
mygrid.setWidget(4, 0, myapp.createLabel('Kind:'));
var lbk = myapp.createListBox(false).setName('kind');
lbk.setVisibleItemCount(1);
lbk.addItem('Expected Value');
lbk.addItem('Value');
lbk.addItem('Count');
mygrid.setWidget(4, 1, lbk);
var panel = myapp.createVerticalPanel();
panel.add(mygrid);
var button = myapp.createButton('Submit');
var handler = myapp.createServerClickHandler('__processPipeline');
handler.addCallbackElement(mygrid);
button.addClickHandler(handler);
panel.add(button);
myapp.add(panel);
mydoc.show(myapp);
}
function __ActivityMenu__(){
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var myapp = UiApp.createApplication().setTitle('Activity');
var mygrid = myapp.createGrid(7, 2);
mygrid.setWidget(0, 0, myapp.createLabel('Category:'));
mygrid.setWidget(0, 1, myapp.createTextBox().setName('category'));
mygrid.setWidget(1, 0, myapp.createLabel('Label:'));
mygrid.setWidget(1, 1, myapp.createTextBox().setName('label'));
mygrid.setWidget(2, 0, myapp.createLabel('User:'));
mygrid.setWidget(2, 1, myapp.createTextBox().setName('user'));
mygrid.setWidget(3, 0, myapp.createLabel('Date:'));
mygrid.setWidget(3, 1, myapp.createDateBox().setId('date'));
mygrid.setWidget(4, 0, myapp.createLabel('Range:'));
var lb = myapp.createListBox(false).setName('range');
lb.setVisibleItemCount(1);
lb.addItem('Week');
lb.addItem('Month');
lb.addItem('Year');
mygrid.setWidget(4, 1, lb);
mygrid.setWidget(5, 0, myapp.createLabel('Type:'));
var lbt = myapp.createListBox(false).setName('type');
lbt.setVisibleItemCount(1);
lbt.addItem('Lead');
lbt.addItem('Opportunity');
lbt.addItem('Customer');
mygrid.setWidget(5, 1, lbt);
mygrid.setWidget(6, 0, myapp.createLabel('Kind:'));
var lbk = myapp.createListBox(false).setName('kind');
lbk.setVisibleItemCount(1);
lbk.addItem('Expected Value');
lbk.addItem('Value');
lbk.addItem('Count');
mygrid.setWidget(6, 1, lbk);
var panel = myapp.createVerticalPanel();
panel.add(mygrid);
var button = myapp.createButton('Submit');
var handler = myapp.createServerClickHandler('__processActivity');
handler.addCallbackElement(mygrid);
button.addClickHandler(handler);
panel.add(button);
myapp.add(panel);
mydoc.show(myapp);
}
function __processActivity(inputvalues){
var category = inputvalues.parameter.category;
var label = inputvalues.parameter.label;
var user = inputvalues.parameter.user;
var date = inputvalues.parameter.date;
var range = inputvalues.parameter.range;
var type = inputvalues.parameter.type;
var kind = inputvalues.parameter.kind;
var answer = Activity(kind,type,date,range,category,user,'',label);
var mysheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
mysheet.getActiveCell().setValue(answer);
var app = UiApp.getActiveApplication();
app.close();
return app;
}
function Activity(kind,type,date,range,category,user,mylabel,label){
var kind = kind || '';
var type = type || '';
var category = category || '';
var user = user || '';
var mylabel = mylabel || '';
var label = label || '';
var range = range || '';
var date = date || '';
var data = __getData_('activity ' + kind,category,user,label,mylabel,date,range);
var type = type.toLowerCase();
if(type=='lead' && data.hasOwnProperty('lead')==true){
return data['lead'];
}else if(type=='customer' && data.hasOwnProperty('customer')==true){
return data['customer'];
}else if(type=='opportunity' && data.hasOwnProperty('opportunity')==true){
return data['opportunity'];
}else{
return 0;
}
}
function Pipeline(kind,type,category,user,mylabel,label){
var kind = kind || '';
var type = type || '';
var category = category || '';
var user = user || '';
var mylabel = mylabel || '';
var label = label || '';
var data = __getData_('pipeline ' + kind,category,user,label,mylabel);
var type = type.toLowerCase();
if(type=='lead' && data.hasOwnProperty('lead')==true){
return data['lead'];
}else if(type=='customer' && data.hasOwnProperty('customer')==true){
return data['customer'];
}else if(type=='opportunity' && data.hasOwnProperty('opportunity')==true){
return data['opportunity'];
}else{
return 0;
}
}
function __processPipeline(inputvalues){
var category = inputvalues.parameter.category;
var label = inputvalues.parameter.label;
var user = inputvalues.parameter.user;
var type = inputvalues.parameter.type;
var kind = inputvalues.parameter.kind;
var answer = Pipeline(kind,type,category,user,'',label);
var mysheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
mysheet.getActiveCell().setValue(answer);
var app = UiApp.getActiveApplication();
app.close();
return app;
}
function __getData_(mlist,mcategory,muser,label,mlabel,mdate,mrange) {
var addon = '';
var mlist = mlist || '';
var mcategory = mcategory || '';
var muser = muser || '';
var label = label || '';
var mlabel = mlabel || '';
var mdate = mdate || '';
var mrange = mrange || '';
if(mcategory.length>0){
addon = addon + "&category=" + encodeURIComponent(mcategory);
}
if(muser.length>0){
addon = addon + "&user=" + encodeURIComponent(muser);
}
if(mlabel.length>0){
addon = addon + "&mylabel=" + encodeURIComponent(mlabel);
}
if(label.length>0){
addon = addon + "&label=" + encodeURIComponent(label);
}
if(mdate.length>0){
addon = addon + "&date=" + encodeURIComponent(mdate);
}
if(mrange.length>0){
addon = addon + "&range=" + encodeURIComponent(mrange);
}
__getWebHook_();
if(webhookurl.length==0 || webhookurl == null){
return [];
}
addon = "&list=" + encodeURIComponent(mlist) + addon;
for(i=0;i<jsondata.length;i++){
if(jsondata[i]['addon'].toLowerCase() == addon.toLowerCase()){
return jsondata[i]['json'];
}
}
var url = webhookurl + addon;
var response = UrlFetchApp.fetch(url);
if (response.getResponseCode() == 200) {
var newid = jsondata.length;
jsondata[newid] = {};
jsondata[newid].json = Utilities.jsonParse(response.getContentText());
jsondata[newid].addon = addon.toLowerCase();
return jsondata[newid].json;
}
}

This is the same as:
No permission to call msgBox in Google Apps Scripting
Custom functions will do nothing but return a value to a cell in which they reside unless they return an array which may affect contiguous cells.
A custom function cannot initiate a input box(Browser.inputBox())
A custom function is a function entered as all or part of a formula in a spreadsheet cell that calls a function from the script editor.
As you stated: 'It used to work' but has been disabled

Related

Required permissions: https://www.googleapis.com/auth/spreadsheets in a custom function

I have read through the official documentation that states, you are not allowed to use services that require authorization such as SpreadsheetApp.openById within a custom function.
I am using a script to call a spreadsheet in its functions and it's doing that fluently. My custom function is not using the service SpreadsheetApp.openById, but still tells me that I do not have the permission. I just want to know whether it is possible to run the custom function or not, even though I am not calling a spreadsheet in the function itself?
Updated:
My custom function build's a reference id for a particular quotation.
I've also tried using https://www.googleapis.com/auth/spreadsheets in oauthScopes in the json file, didn't work.
This is the function calling openById:
var ss1 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var dukeid = "1WGbEo1Xr99HwHY_4ZaeTRIgCOuNcjVfqCzZx4dcQX4I"
var duke = SpreadsheetApp.openById(dukeid);
var totalstockd = duke.getSheetByName("Total Stock").getRange(2,3,2500,7).getValues();
var avmid = "1a6bm2O_iljHZUoF2BhYeyxUT13tB06-JJCYeYCZZ10Q"
var avm = SpreadsheetApp.openById(avmid);
var totalstocka = avm.getSheetByName("Total Stock").getRange(2,3,1000,7).getValues();
function when(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var ssName = activeCell.getSheet().getName();
if (ssName=="General Information" && (r==3 || r==6) && c==3){
var rescell = ss1.getRange(r,6);
var unitcell = ss1.getRange(r,7);
rescell.clearContent();
if(val[0]=="A"){
var result = sumalt(val,totalstocka,unitcell);
rescell.setValue(result);
}
else {
var result = sumalt(val,totalstockd,unitcell);
rescell.setValue(result);
}
}
else{
console.log("No Edit");
}
}
And this is my custom function:
function QREF(Company,ID){
var td=new Date().valueOf();
var year = new Date().getFullYear();
var hd=new Date(year, 0, 0).valueOf();
var year2 = year - 2000
var sec=1000;
var min=60*sec;
var hour=60*min;
var day=24*hour;
var diff=td-hd;
var julian=Math.floor(diff/day);
Logger.log(year2);
string = Company + ID + "-"+ "" + julian + "/" + year2 + "-";
return string;
}
Modification points:
When I saw your script, I noticed that SpreadsheetApp.openById is used as the global. By this, when your custom function is run, SpreadsheetApp.openById is run. So, such error occurs. I think that this is the reason of your issue.
When you want to use both script in your Google Apps Script, how about the following modification?
Modified script:
function when(e) {
// These scripts are included in a function.
var ss1 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var dukeid = "1WGbEo1Xr99HwHY_4ZaeTRIgCOuNcjVfqCzZx4dcQX4I"
var duke = SpreadsheetApp.openById(dukeid);
var totalstockd = duke.getSheetByName("Total Stock").getRange(2, 3, 2500, 7).getValues();
var avmid = "1a6bm2O_iljHZUoF2BhYeyxUT13tB06-JJCYeYCZZ10Q"
var avm = SpreadsheetApp.openById(avmid);
var totalstocka = avm.getSheetByName("Total Stock").getRange(2, 3, 1000, 7).getValues();
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var ssName = activeCell.getSheet().getName();
if (ssName == "General Information" && (r == 3 || r == 6) && c == 3) {
var rescell = ss1.getRange(r, 6);
var unitcell = ss1.getRange(r, 7);
rescell.clearContent();
if (val[0] == "A") {
var result = sumalt(val, totalstocka, unitcell);
rescell.setValue(result);
} else {
var result = sumalt(val, totalstockd, unitcell);
rescell.setValue(result);
}
} else {
console.log("No Edit");
}
}
function QREF(Company, ID) {
var td = new Date().valueOf();
var year = new Date().getFullYear();
var hd = new Date(year, 0, 0).valueOf();
var year2 = year - 2000
var sec = 1000;
var min = 60 * sec;
var hour = 60 * min;
var day = 24 * hour;
var diff = td - hd;
var julian = Math.floor(diff / day);
Logger.log(year2);
string = Company + ID + "-" + "" + julian + "/" + year2 + "-";
return string;
}
By this modification, when QREF() is run as the custom function, SpreadsheetApp.openById is not run. By this, such error can be removed.
Note:
If you are using the following script at other function, please be careful this. In that case, please include the script to the function. Or, please include the following script as new function, and call the function from other function.
var ss1 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var dukeid = "1WGbEo1Xr99HwHY_4ZaeTRIgCOuNcjVfqCzZx4dcQX4I"
var duke = SpreadsheetApp.openById(dukeid);
var totalstockd = duke.getSheetByName("Total Stock").getRange(2, 3, 2500, 7).getValues();
var avmid = "1a6bm2O_iljHZUoF2BhYeyxUT13tB06-JJCYeYCZZ10Q"
var avm = SpreadsheetApp.openById(avmid);
var totalstocka = avm.getSheetByName("Total Stock").getRange(2, 3, 1000, 7).getValues();

Google script custom trigger onEdit(e) issue

I am getting error in line 29. But the same code works when pasted in another sheet. Separate trigger is used. Edit-> Current project's trigger.
var Team_email='abc#gmail.com';
function TriggerOnEdit(e)
{
Logger.log("stg1");
sendEmailOnassigned(e);
}
function showMessageOnApproval(e)
{
var edited_row = checkStatusIsAssigned(e);
if(edited_row > 0)
{
SpreadsheetApp.getUi().alert("Row # "+edited_row+" approved!");
}
}
function showMessageOnUpdate(e)
{
var range = e.range;
SpreadsheetApp.getUi().alert("range updated " + range.getA1Notation());
}
function checkStatusIsAssigned(e)
{
Logger.log("stg3");
var range = e.range;
if(range.getColumn() <= 12 &&
range.getLastColumn() >=12 )
{
var edited_row = range.getRow();
var status = SpreadsheetApp.getActiveSheet().getRange(edited_row,11).getValue();
if(status == 'Assigned')
{
return edited_row;
}
}
return 0;
}
function sendEmailOnassigned(e)
{
Logger.log("stg2");
var approved_row = checkStatusIsAssigned(e);
if(approved_row <= 0)
{
return;
}
Logger.log("stg4");
sendEmailByRow(approved_row);
}
function sendEmailByRow(row)
{
Logger.log("stg5");
var values = SpreadsheetApp.getActiveSheet().getRange(row,1,row,13).getValues();
var row_values = values[0];
var mail = composeAssignedEmail(row_values);
MailApp.sendEmail(Team_email,mail.subject,mail.message);
var Requester_email = composeRequesterEmail(row_values);
MailApp.sendEmail(Requester_email.email,Requester_email.subject,Requester_email.message);
}
function composeAssignedEmail(row_values)
{
Logger.log("stg6");
var Request_Number = row_values[1];
var email = row_values[2];
var Project_Name = row_values[4];
var Nature_Of_Work = row_values[5];
var Quantity = row_values[6];
var Estimated_Hours = row_values[7];
var Name = row_values[12];
var message = "Hello Requester, \n "+" \n The following Resource "+ Name ;
var subject = "Request_Number - " + Request_Number ;
return({message:message,subject:subject});
}
function composeRequesterEmail(row_values)
{
Logger.log("stg7");
var Request_Number = row_values[1];
var email = row_values[2] ;
var Project_Name = row_values[4];
var Nature_Of_Work = row_values[5];
var Quantity = row_values[6];
var Estimated_Hours = row_values[7];
var Name = row_values[12];
var message = "Hello Requester, \n "+" \n The following Resource "+ Name;
var subject = "Request_Number - " + Request_Number;
return({message:message,subject:subject, email:email });
}
Please tell me the error where is the mistake.
We can not use debug function to understand the mistake. because trigger is on edit.
Also when we use 'e' what are the information do we feed the function?
How to correct this?

Re-execute all matching functions in a spreadsheet

I have a really simple script to pull the given tab name:
function sheetName() {return SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();}
But this will not update when I change a tab's name. Is there any script that could be written to "re-execute" sheetName(), the function, in all places it is found in a spreadsheet? Would love to just pop in a button that could rerun sheetName() everywhere so that the tab names' references stay current.
I do see some old (~4 years) questions about this, but struggling to find something current. Apologies if this is duplicative!
You can install a trigger to run "On change" I tried editing a sheet tab, and the code did run.
function sheetNameReturn(e) {
Logger.log(e.changeType)
Logger.log('sheetName ran')
return SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
}
Unfortunately, at the time of this post, the triggers are kind of buggy. If you install a trigger, and it doesn't run, you'll need to delete the trigger, close the window, and go through the process again and save it.
I changed the name of the function to sheetNameReturn I had a lot of trouble getting the trigger to run. I had to delete the trigger and install it again.
Keep Your Sheet Names the Same
If you'd like to keep your sheet names the same here's a script just for you. It utilizes a few scripts that I've been working on lately that allow you to save arrays and associative arrays in files rather than utilizing the PropertiesService. It may not be 100 percent bug free...but what is?
Code.gs
function onOpen()
{
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('SaveSheetNames', 'SaveSheetNames')
.addToUi();
}
function SaveSheetNames()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var shts = ss.getSheets();
var s = 'SheetNames:::DICT|***|';
for(var i = 0; i<shts.length;i++)
{
if(i>0){s += '~~~';}
s += shts[i].getSheetId() + '^^^' + shts[i].getSheetName();
}
saveFile(s);
}
function KeepSheetNames()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var shts = ss.getSheets();
var SheetNamesA = getArrayByName('SheetNames');
for(var i = 0; i<shts.length;i++)
{
if(shts[i].getName() !== SheetNamesA[shts[i].getSheetId()])
{
shts[i].setName(SheetNamesA[shts[i].getSheetId()]);
}
}
}
ArrayFileStorage.gs
//A segment is either an Array or an Associative Array obtain by splitting the data string inside the data file with this delimeter |###|
//It returns an actual Associative Array
function getAssociativeArray(segment)
{
var segment = (typeof(segment))?segment:null;
var C = [];
var br = '<br />';
if(segment)
{
var A = segment.split('~~~');//Array of key^^^value strings [key^^^value,key^^^value,key^^^value...]
for(var i = 0;i<A.length;i++)
{
B=A[i].split('^^^');//KeyValueArray[key,val]
C[B[0]]=B[1];//Dictionary or Associative Array {key:'value',key:'value',key:'value'...}
}
}
return C;
}
//A segment is either an Array or an Associative Array obtain by splitting the data string inside the data file with this delimeter |###|
//It returns an actual Array
function getArray(segment)
{
var segment = (typeof(segment))?segment:null;
var br = '<br />';
if(segment)
{
var A=segment.split('~~~');
}
return A;
}
//The above functions are used within this function so that it can return either type of array object requested
function getArrayByName(name)
{
var name = (typeof(name) !== 'undefined')? name : null;
var br = '<br />';
if(name)
{
var data = loadFile('KeepSheetNames').split('|###|');//Array Data String two different forms possible
for(var i=0;i<data.length;i++)
{
var A = data[i].split('|***|');
var B = A[0];
var segment = A[1];
var nametype = B.split(':::');
if(nametype[0]==name)
{
if(nametype[1]=='DICT')
{
var obj = getAssociativeArray(segment)
}
if(nametype[1]=='ARRAY')
{
var obj = getArray(segment);
}
break;
}
}
}
return obj;
}
//This function just displays the data stored within the default data file by splitting it with |###|
function displayData()
{
s='';
var data = loadFile('KeepSheetNames').split('|###|');
for(var i=0;i<data.length;i++)
{
if(i>0)s+='<br />';
s+=data[i];
}
s += '<br /><input type="button" value="Exit" onClick="google.script.host.close();" />'
dispStatus('Display Data for Default File',s,1000,400);
}
//This function uses the saveFile function in Utility.gs to save data into default file.
//This function will also add a new array to the end
function saveArray(name,type,array)
{
var name = (typeof(name) !== 'undefined')? name : null;
var type = (typeof(type) !== 'undefined')? type : null;
var array = (typeof(array) !== 'undefined')? array : null;
var types = ['DICT','ARRAY'];
var isSaved = false;
var isAValidType = false;
for(var i=0;i<types.length;i++)
{
if(type == types[i])
{
isAValidType=true;
break;
}
}
if(name && isAValidType && array)
{
var data = loadFile('KeepSheetNames').split('|###|');
var datstr = '';
var idx = getIndexOf(name);
var str = convertArrayToString(name,type,array);
if(idx>-1)
{
data[idx]=str;
}
else
{
data.push(str);
}
for(var i = 0;i<data.length;i++)
{
if(i>0){datstr += '|###|';}
datstr += data[i];
}
isSaved=saveFile(datstr);
}
else
{
SpreadsheetApp.getUi().alert('Invalid Input: Check your parameters in function saveArray().');
}
return isSaved;
}
//This function gets the index of the requested named data array
function getIndexOf(name)
{
var name = (typeof(name) !== 'undefined')? name : null;
var idx = -1;
if(name)
{
var data = loadFile('KeepSheetNames').split('|###|');
for(var i=0;i<data.length;i++)
{
var nametype = data[i].split(':::');
if(name==nametype[0])
{
idx = i;
break;
}
}
}
return idx;
}
//Takes the real arrays and converts them to strings so that they can be saved.
function convertArrayToString(name,type,array)
{
var name = (typeof(name) !== 'undefined')? name : null;
var type = (typeof(type) !== 'undefined')? type : null;
var array = (typeof(array) !== 'undefined')? array : null;
var types = ['DICT','ARRAY'];
var ConvertedString='';
var isAValidType = false;
for(var i=0;i<types.length;i++)
{
if(type == types[i])
{
isAValidType=true;
break;
}
}
if(name && array && isAValidType)
{
ConvertedString += name + ':::' + type + '|***|';
switch(type)
{
case 'ARRAY':
for(var i=0;i<array.length;i++)
{
if(i>0){ConvertedString += '~~~';}
ConvertedString += array[i];
}
break;
case 'DICT':
var firstTime = true;
for(var key in array)
{
if(!firstTime){ConvertedString += '~~~';}
ConvertedString += key + '^^^' + array[key];
firstTime=false;
}
break;
}
}
else
{
SpreadsheetApp.getUi().alert('Invalid Input: Check your parameters in function saveArray().');
}
return ConvertedString;
}
//deletes a current data array
function deleteArrayByName(name)
{
var name = (typeof(name) !== 'undefined')? name : null;
var br = '<br />';
var isSaved = false;
if(name)
{
var delidx = getIndexOf(name);
if(delidx > -1)
{
var datstr = '';
var data = loadFile('KeepSheetNames').split('|###|');//Array Data String two different forms possible
for(var i=0;i<data.length;i++)
{
if(delidx !== i)
{
if(i>0){datstr += '|###|';}
datstr += data[i];
}
}
isSaved=saveFile(datstr);
}
return isSaved;
}
}
function dispFile(filename,folderID)
{
var filename = (typeof(filename) !== 'undefined')? filename : 'KeepSheetNames';
var folderID = (typeof(folderID) !== 'undefined')? folderID : '';
var file = loadFile();
if(file)
{
dispStatus('Displaying File: ' + filename, file, 800, 500);
}
else
{
SpreadsheetApp.getUi().alert('File "' + filename + '" not found in function dispFile.');
}
}
function loadFile(filename,folderID)
{
var filename = (typeof(filename) !== 'undefined')? filename : 'KeepSheetNames';
var folderID = (typeof(folderID) !== 'undefined')? folderID : '';
var fldr = DriveApp.getFolderById(folderID);
var file = fldr.getFilesByName(filename);
var s = '';
while(file.hasNext())
{
var fi = file.next();
var target = fi.getName();
if(target == filename)
{
s = fi.getBlob().getDataAsString();
}
}
return s;
}
function delFile(filename,folderID)
{
var filename = (typeof(filename) !== 'undefined')? filename : 'KeepSheetNames';
var folderID = (typeof(folderID) !== 'undefined')? folderID : '';
var fldr = DriveApp.getFolderById(folderID)
var file = fldr.getFilesByName(filename);
var targetFound = false;
while(file.hasNext())
{
var fi = file.next();
var target = fi.getName();
if(target == filename)
{
targetFound = true;
fldr.removeFile(fi);
SpreadsheetApp.getUi().alert('File: ' + filename + ' was removed from: ' + fldr.getName() + '/' + target);
}
}
return targetFound;
}
function saveFile(datstr,filename)
{
var filename = (typeof(filename) !== 'undefined')? filename : 'KeepSheetNames';
var folderID = (typeof(folderID) !== 'undefined')? folderID : '';
var fldr = DriveApp.getFolderById(folderID);
var file = fldr.getFilesByName(filename);
var targetFound = false;
while(file.hasNext())
{
var fi = file.next();
var target = fi.getName();
if(target == filename)
{
targetFound = true;
fi.setContent(datstr);
}
return targetFound;
}
}
Utility.gs
// Display a modeless dialog box with custom HtmlService content.
function dispStatus(title,html,width,height,modal)
{
var title = typeof(title) !== 'undefined' ? title : 'No Title Provided';
var width = typeof(width) !== 'undefined' ? width : 400;
var height = typeof(height) !== 'undefined' ? height : 300;
var html = typeof(html) !== 'undefined' ? html : '<p>No html provided.</p>';
var modal = typeof(modal) !== 'undefined' ? modal : false;
var htmlOutput = HtmlService
.createHtmlOutput(html)
.setWidth(width)
.setHeight(height);
if(!modal)
{
SpreadsheetApp.getUi().showModelessDialog(htmlOutput, title);
}
else
{
SpreadsheetApp.getUi().showModalDialog(htmlOutput, title);
}
}
You will have to setup a onEdit trigger to call KeepSheetNames() and that should do it. I played with it a bit and it seems to work okay. If you find anything wrong with feel free to fix it. Also you'll have to add the id of your data folder. I decided that it probably wasn't a good idea to publish that.

Google App Script: Auto Refresh after form submission

So I have an app script gadget embedded in a google site. What the app script does is get objects from scriptdb and display it on the screen. There also is an add button clicking on which you get a form to enter information and add objects. What I am trying to do is that after an object is saved, I repopulate the object and display them so the newly created object can be seen without manually refreshing the page.
I have a function called update() that is called after an object is saved and this function takes care of the "auto refresh".
In the save() function, I call the update function with this syntax, update(). Here is the submit() function
function SaveAssignment(e){
var db = ScriptDb.getMyDb();
var app = UiApp.getActiveApplication();
var name = e.parameter.assignmentname;
var date = e.parameter.assignmentdate.toString();
var desc = e.parameter.assignmentdesc;
var category = e.parameter.assignmentcategory;
var totalscore = e.parameter.assignmenttotalscore;
var site = SitesApp.getActiveSite();
var assignment = { name: name,
date: date,
description: desc,
url: pageUrl + '?name='+name+'&date='+date+'&description='+desc+'&id='+sheetId,
sheetid: sheetId,
totalScore: totalscore,
Category: category
};
db.save(assignment);
update();
}
and here is my update() method
function update(){
var app = UiApp.createApplication();
var oldGrid = app.getElementById('grid');
app.remove(oldGrid);
var handler = app.createServerHandler('AddAssignment');
var addAssignmentButton = app.createButton('Add Assignment', handler);
var assignments = db.query({});
var i = 1;
var j = 1;
var grid;
if(assignments.getSize() < 1){
grid = app.createGrid(3, 5).setId('grid');
}
else{
grid = app.createGrid(assignments.getSize() + assignments.getSize() + assignments.getSize(), 5).setId('grid');
}
handler.addCallbackElement(grid);
grid.setWidget(0, 2, addAssignmentButton);
while(assignments.hasNext()){
var assignment = assignments.next();
var name = assignment.name;
var date = assignment.date;
var description = assignment.description;
var nameLabel = app.createLabel('Assignment ' + i + ' : ' + name).setVisible(true);
var dateLabel = app.createLabel('Date: ' + date).setVisible(true);
var idLabel = app.createLabel(assignment.getId()).setVisible(false);
var deletebutton = app.createButton('Delete Assignment');
var handler = app.createServerHandler('deleteAssignment');
handler.addCallbackElement(idLabel);
deletebutton.addClickHandler(handler);
grid.setWidget(j, 0, nameLabel);
j = j + 1;
grid.setWidget(j, 0, dateLabel);
grid.setWidget(j, 1, deletebutton);
grid.setWidget(j, 3, idLabel);
i++;
j = j + 2;
}
app.add(grid);
return app;
I made some little test on your code. you need to do some little changes:
You need to change "var app = UiApp.createApplication();" for "var app = UiApp.getActiveApplication()" (already saw that in comment).
You didn't declared "db" your script will systematically be in error if you don't correct that.
Bellow your code where the update function actually update the grid:
function doGet(){
var app = UiApp.createApplication();
var grid = app.createGrid(3, 3).setId("grid").setWidget(1, 2, app.createLabel("test"));
grid.addClickHandler(app.createServerHandler("update"));
app.add(grid);
return(app);
}
function update(){
var app = UiApp.getActiveApplication(); // getActiveApplication
var oldGrid = app.getElementById('grid');
app.remove(oldGrid);
var handler = app.createServerHandler('AddAssignment');
var addAssignmentButton = app.createButton('Add Assignment', handler);
var db = ScriptDb.getMyDb();
var assignments = db.query({}); // YOU DIDNT DECLARED db
var i = 1;
var j = 1;
var grid;
if(assignments.getSize() < 1){
grid = app.createGrid(3, 5).setId('grid');
}
else{
grid = app.createGrid(assignments.getSize() + assignments.getSize() + assignments.getSize(), 5).setId('grid'); // assignments.getSize()*3
}
handler.addCallbackElement(grid);
grid.setWidget(0, 2, addAssignmentButton);
while(assignments.hasNext()){
var assignment = assignments.next();
var name = assignment.name;
var date = assignment.date;
var description = assignment.description;
var nameLabel = app.createLabel('Assignment ' + i + ' : ' + name).setVisible(true);
var dateLabel = app.createLabel('Date: ' + date).setVisible(true);
var idLabel = app.createLabel(assignment.getId()).setVisible(false);
var deletebutton = app.createButton('Delete Assignment');
var handler = app.createServerHandler('deleteAssignment');
handler.addCallbackElement(idLabel);
deletebutton.addClickHandler(handler);
grid.setWidget(j, 0, nameLabel);
j = j + 1;
grid.setWidget(j, 0, dateLabel);
grid.setWidget(j, 1, deletebutton);
grid.setWidget(j, 3, idLabel);
i++;
j = j + 2;
}
app.add(grid);
return app;
}

Add Apps to StackPanel

Is there any way to add an app script that I created to a StackPanel? or do I have to create the StackPanel integrated with the existing app script code?
function doGet() {
var app = UiApp.createApplication();
//Create stack panel
var stackPanel = app.createStackPanel().setSize('100%', '100%');
//add widgets to each stack panel, and name the stack panel
stackPanel.add(, 'Instructions: Scheduling the Lab');
stackPanel.add(, 'Lab Calendar');
stackPanel.add(, 'Lab Request Form');
//Add the panel to the application
app.add(stackPanel);
return app;
}
You can in a way but there can be only one Uinstance in a webapp so instead of returning app in each function that builds a stackPanel you'll have to return a widget that will be added to each stackPanel. The functions can be in different script files but must be part of the same project.
Your app will need a few modifications : see the code below (look also at the end of the formBuild function that has changed a bit ;-).
function doGet() {
var app = UiApp.createApplication().setTitle('DHS: Kurzweil Calendar');
//Create stack panel
var stackPanel = app.createStackPanel().setSize('100%', '100%');
var form = formBuild(app);
var p1 = app.createVerticalPanel().setId('Panel1').add(form);
var cal = calendar(app);
var p2 = app.createVerticalPanel().setId('Panel2').add(cal);
var ins = instruction(app);
var p3 = app.createVerticalPanel().setId('Panel3').add(ins);
//add widgets to each stack panel, and name the stack panel
stackPanel.add(p1, 'Instructions: Scheduling the Lab');
stackPanel.add(p2, 'Lab Calendar');
stackPanel.add(p3, 'Lab Request Form');
//Add the panel to the application
app.add(stackPanel);
return app;
}
function instruction(app){
var lab = app.createLabel('label').setPixelSize(100,100);
return lab
}
function calendar(app){
return app.createLabel('label').setPixelSize(100,100);
}
function formBuild(app) {
//Create a panel which holds all the form elelemnts
var vrtMainPanel = app.createVerticalPanel().setId('vrtMainPanel');
//Create Spreadsheet Source
var spSheet = SpreadsheetApp.openById('0AnqSFd3iikE3dEtBQndOYVNEbFVWcDlyQmFoaUV3a1E');
var spTeacherList = spSheet.getSheetByName('TeacherList');
var spSubjectList = spSheet.getSheetByName('SubjectList');
var spPeriodList = spSheet.getSheetByName('PeriodList');
var spCountList = spSheet.getSheetByName('CountList');
//Create the form elements
var hdlTeacherName = app.createServerHandler('getTeacherName').addCallbackElement(vrtMainPanel);
var lbxTeacherName = app.createListBox().setId('lbxTeacherName').setName('lbxTeacherName').addChangeHandler(hdlTeacherName);
var lstTeacherNames = spTeacherList.getRange(1,1,spTeacherList.getLastRow(),1).getValues();
lstTeacherNames.sort();
for (var l = 0; l < lstTeacherNames.length; l++) {
lbxTeacherName.addItem(lstTeacherNames[l],l);
}
var lblTeacherName = app.createLabel('Teacher Name:');
var txtTeacherName = app.createTextBox().setName('txtTeacherName').setId('txtTeacherName').setVisible(false);
var vldTeacherName = app.createLabel().setId('vldTeacherName').setVisible(false);
var lblExt = app.createLabel('Ext:');
var txtExt = app.createTextBox().setName('txtExt').setId('txtExt');
var vldExt = app.createLabel().setId('vldExt').setVisible(false);
//Set DateBox to Tomorrow's Date
var tomorrow =new Date(new Date(new Date().setHours(0,0,0,0)).setDate(new Date().getDate() + 1));// set hours, min, sec & milliSec to 0 and day=day+1
Logger.log(tomorrow);
var lblDate = app.createLabel('Date of Test:');
var boxDate = app.createDateBox().setId('boxDate').setName('boxDate').setFormat(UiApp.DateTimeFormat.DATE_SHORT).setValue(tomorrow);
var vldDate = app.createLabel().setId('vldDate').setVisible(false);
var lbxSubject = app.createListBox().setId('lbxSubject').setName('lbxSubject');
var vldSubject = app.createLabel().setId('vldSubject').setVisible(false);
var lstSubjects = spSubjectList.getRange(1,1,spSubjectList.getLastRow(),1).getValues();
lstSubjects.sort();
for (var l = 0; l < lstSubjects.length; l++) {
lbxSubject.addItem(lstSubjects[l]);
}
var lbxPeriod = app.createListBox().setId('lbxPeriod').setName('lbxPeriod');
var vldPeriod = app.createLabel().setId('vldPeriod').setVisible(false);
var lstPeriods = spPeriodList.getRange(1,1,spPeriodList.getLastRow(),1).getValues();
lstPeriods.sort();
for (var l = 0; l < lstPeriods.length; l++) {
lbxPeriod.addItem(lstPeriods[l]);
}
var lblStudentNum = app.createLabel('Number of Students:');
var vldStudentNum = app.createLabel().setId('vldStudentNum').setVisible(false);
var lbxStudentNum = app.createListBox().setId('lbxStudentNum').setName('lbxStudentNum');
var lstStudentNums = spCountList.getRange(1,1,spCountList.getLastRow(),1).getValues();
lstStudentNums.sort();
for (var l = 0; l < lstStudentNums.length; l++) {
lbxStudentNum.addItem(lstStudentNums[l]);
}
var txtSourceGrp = app.createTextBox().setName('txtSourceGrp').setVisible(false);
var txtTypeGrp = app.createTextBox().setName('txtTypeGrp').setVisible(false);
var vldSourceGrp = app.createLabel().setId('vldSourceGrp').setVisible(false);
var vldTypeGrp = app.createLabel().setId('vldTypeGrp').setVisible(false);
var txtElementsID = app.createTextBox().setName('txtElementsID').setText('Elements Test ID').setVisible(false);
var txtQuiaLink = app.createTextBox().setName('txtQuiaLink').setText('Quia Test Link').setVisible(false);
var txtQuiaPass = app.createTextBox().setName('txtQuiaPass').setText('Quia Test Passphrase').setVisible(false);
//Create Source Radio Button Group
var radHCopy = app.createRadioButton('group1', 'Hard-Copy').setFormValue('Hard-Copy').addClickHandler(app.createClientHandler().forTargets(txtSourceGrp).setText('Hard-Copy'));
var radECopy = app.createRadioButton('group1', 'Electronic-Copy').setFormValue('Electronic-Copy').addClickHandler(app.createClientHandler().forTargets(txtSourceGrp).setText('Electronic-Copy'));
//Create Type Radio Button Group
var radTExam = app.createRadioButton('group2', 'Teacher-Made Exam').setFormValue('Teacher-Made Exam').addClickHandler(app.createClientHandler().forTargets(txtTypeGrp).setText('Teacher-Made Exam'));
var radEExam = app.createRadioButton('group2', 'Elements Exam').setFormValue('Elements Exam').addClickHandler(app.createClientHandler().forTargets(txtTypeGrp).setText('Elements Exam'));
var radQExam = app.createRadioButton('group2', 'Quia Exam').setFormValue('Quia Exam').addClickHandler(app.createClientHandler().forTargets(txtTypeGrp).setText('Quia Exam'));
var btnCreate = app.createButton('Create Event');
//Client Handlers for textBoxes
var showTxtElementHandler = app.createClientHandler().forTargets(txtElementsID).setVisible(true);
var hideTxtElementHandler = app.createClientHandler().forTargets(txtElementsID).setVisible(false);
var vldElementsID = app.createLabel().setId('vldElementsID').setVisible(false);
radEExam.addClickHandler(showTxtElementHandler);
radTExam.addClickHandler(hideTxtElementHandler);
radQExam.addClickHandler(hideTxtElementHandler);
var showTxtQuiaLinkHandler = app.createClientHandler().forTargets(txtQuiaLink).setVisible(true);
var hideTxtQuiaLinkHandler = app.createClientHandler().forTargets(txtQuiaLink).setVisible(false);
var vldQuia = app.createLabel().setId('vldQuia').setVisible(false);
radQExam.addClickHandler(showTxtQuiaLinkHandler);
radTExam.addClickHandler(hideTxtQuiaLinkHandler);
radEExam.addClickHandler(hideTxtQuiaLinkHandler);
var showTxtQuiaPassHandler = app.createClientHandler().forTargets(txtQuiaPass).setVisible(true);
var hideTxtQuiaPassHandler = app.createClientHandler().forTargets(txtQuiaPass).setVisible(false);
radQExam.addClickHandler(showTxtQuiaPassHandler);
radTExam.addClickHandler(hideTxtQuiaPassHandler);
radEExam.addClickHandler(hideTxtQuiaPassHandler);
//Create validation handler
var valSubmit = app.createServerClickHandler('valSubmit');
valSubmit.addCallbackElement(vrtMainPanel);
//Add this handler to the button
btnCreate.addClickHandler(valSubmit);
//Add all the elemnts to the panel
var formGrid = app.createGrid(18,3).setCellPadding(3);
vrtMainPanel.add(formGrid);
formGrid
.setWidget(0,0,vldTeacherName)
.setWidget(0,1,vldExt)
.setWidget(1,0,lbxTeacherName)
.setWidget(1,1,txtExt)
.setWidget(1,2,txtTeacherName)
.setWidget(2,0,vldPeriod)
.setWidget(2,1,vldSubject)
.setWidget(3,0,lbxPeriod)
.setWidget(3,1,lbxSubject)
.setWidget(4,1,vldDate)
.setWidget(5,0,lblDate)
.setWidget(5,1,boxDate)
.setWidget(1,1,vldStudentNum)
.setWidget(7,0,lblStudentNum)
.setWidget(7,1,lbxStudentNum)
.setWidget(8,0,vldSourceGrp)
.setWidget(9,0,radHCopy)
.setWidget(9,1,radECopy)
.setWidget(10,0,vldTypeGrp)
.setWidget(11,0,radTExam)
.setWidget(11,1,vldElementsID)
.setWidget(12,0,radEExam)
.setWidget(12,1,txtElementsID)
.setWidget(13,0,radQExam)
.setWidget(13,1,vldQuia)
.setWidget(14,1,txtQuiaLink)
.setWidget(15,1,txtQuiaPass)
.setWidget(16,0,txtSourceGrp)
.setWidget(16,1,txtTypeGrp)
.setWidget(17,0,btnCreate)
//Add this panel to the application
return(vrtMainPanel);
}
function getTeacherName(e){
var spSheet = SpreadsheetApp.openById('0AnqSFd3iikE3dEtBQndOYVNEbFVWcDlyQmFoaUV3a1E');
var spTeacherList = spSheet.getSheetByName('TeacherList');
var lstTeacherNames = spTeacherList.getRange(1,1,spTeacherList.getLastRow(),2).getValues();
var app = UiApp.getActiveApplication();
var txtTeacherName = app.getElementById('txtTeacherName');
var txtExt = app.getElementById('txtExt');
txtTeacherName.setText(lstTeacherNames[e.parameter.lbxTeacherName][0]);// sets Teacher's Name
txtExt.setText(lstTeacherNames[Number(e.parameter.lbxTeacherName)][1]);// sets Ext
return app;
}
function valSubmit(e) {
var flag = 0;
var app = UiApp.getActiveApplication();
var Teacher = e.parameter.txtTeacherName;
var Ext = e.parameter.txtExt;
var Subject = e.parameter.lbxSubject;
var Period = e.parameter.lbxPeriod;
var Date = e.parameter.boxDate;
var StudentNum = e.parameter.lbxStudentNum;
var Source = e.parameter.txtSourceGrp;
var Type = e.parameter.txtTypeGrp;
var ElementsID = e.parameter.txtElementsID;
var QuiaLink = e.parameter.txtQuiaLink;
var QuiaPass = e.parameter.txtQuiaPass;
if (Teacher == '' || Teacher == '-- Select Teacher --') {
app.getElementById('vldTeacherName').setText('* Select Teacher').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (Ext == '') {
app.getElementById('vldExt').setText('* Select Teacher Again').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (Subject == '' || Subject == '-- Select Subject --') {
app.getElementById('vldSubject').setText('* Select Subject').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (Period == '' || Period == '-- Select Period --') {
app.getElementById('vldPeriod').setText('* Select Period').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (Date == '' || Date == Utilities.formatDate(Date, 'EST', 'yyyy-mm-dd')) {
app.getElementById('vldDate').setText('* Date must be entered as yyyy-mm-dd').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (StudentNum == '' || StudentNum == '-- Select # --') {
app.getElementById('vldStudentNum').setText('* Select Student #').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (Source == '' || Source == false) {
app.getElementById('vldSourceGrp').setText('* Select either Hard Copy or Electronic Copy').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (Type == '' || Type == false) {
app.getElementById('vldTypeGrp').setText('* Select either Teacher-Made Exam, Elements Exam, or Quia Exam').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (ElementsID == '' && Type == 'Elements Exam') {
app.getElementById('vldElementsID').setText('* Enter Elements ID').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (QuiaLink == '' || QuiaPass == '' && Type == 'Quia Exam') {
app.getElementById('vldQuia').setText('* Enter Quia Link and/or Passphrase').setStyleAttribute("color", "#F00").setVisible(true);
flag = 1;
}
if (flag == 0) {
//Create handler which will execute 'createEvents(e)' on clicking the button
var evtHandler = app.createServerClickHandler('createEvents');
var vrtMainPanel = app.getElementById(vrtMainPanel)
evtHandler.addCallbackElement(vrtMainPanel);
}
}
function createEvents(e){
//Get the active application
var app = UiApp.getActiveApplication();
try{
//Get the entries
var ssTeacher = e.parameter.txtTeacherName;
var ssExt = e.parameter.txtExt;
var ssSubject = e.parameter.lbxSubject;
var ssPeriod = e.parameter.lbxPeriod;
var ssStudentNum = e.parameter.lbxStudentNum;
var ssSource = e.parameter.txtSourceGrp;
var ssType = e.parameter.txtTypeGrp;
var ssElementsID = e.parameter.txtElementsID;
var ssQuiaLink = e.parameter.txtQuiaLink;
var ssQuiaPass = e.parameter.txtQuiaPass;
var eventDate = e.parameter.boxDate;
var eventCalSubject = ssPeriod + ": " + ssTeacher + " (" + ssStudentNum + ")";
var eventCalDetails = "Extension: " + ssExt + "\n" +
"Subject: " + ssSubject + "\n\n" +
"Source: " + ssSource + "\n" +
"Type: " + ssType + "\n" +
"Elements ID: " + ssElementsID + "\n" +
"Quia Test Link: " + ssQuiaLink + "\n" +
"Quia Passphrase: " + ssQuiaPass;
//Get the calendar
var cal = CalendarApp.getCalendarById('davie.k12.nc.us_d2mv2eb8aspuant1vb5j6r3sis#group.calendar.google.com');//Change the calendar id
//Create the events
var newID = cal.createAllDayEvent(eventCalSubject, eventDate, {description:eventCalDetails}).getId();
//Log the entries in a spreadsheet
var sheet = SpreadsheetApp.openById('0AnqSFd3iikE3dEtBQndOYVNEbFVWcDlyQmFoaUV3a1E').getActiveSheet();//Change the spreadhseet key to yours
var lastRow = sheet.getLastRow();
var targetRange = sheet.getRange(lastRow+1, 1, 1, 13).setValues([[new Date(),eventDate,ssTeacher,ssExt,ssSubject,ssPeriod,ssSource,ssType,ssElementsID,ssQuiaLink,ssQuiaPass,ssStudentNum,newID]]);
return app;
//Show the confirmation message
app.add(app.createLabel('Kurzweil Calendar Event created successfully...'));
//Make the form panel invisible
app.getElementById('vertMainPanel').setVisible(false);
return app;
}
//If an error occurs, show it on the panel
catch(e){
app.add(app.createLabel('Error occured: '+ e));
return app;
}
}