I wrote a script that restores calendar data from a backup written in a spreadsheet. Since the amount of data is highly unpredictable I designed a loop that stops after a given number of minutes , asking the user to continue or to cancel while showing the actual counter state (this to prevent issue with Google max execution time limit).
It works pretty well but in this simplified test script I used for testing the idea it works only once : when the first "timeout" occurs, it shows the continue/cancel option as expected and then continues from where it started but when the same condition happens for the second time the continue button doesn't shows up.
My question is simply : why ? or better : what's the difference between both situations ?
The spreadsheet with embedded script is publicly testable here (see menu : test)
and the whole script is shown below (it's a bit long of course but the interresting part is near the end)
I used ScriptProperties to keep track of execution time and to continue the loop from where I left.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [
{name: "test", functionName: "test"},
];
ss.addMenu("test", menuEntries);
}
function test(){
ScriptProperties.setProperty('restorePointers',[0,0].join('#'))
var app = UiApp.createApplication().setTitle("test");
app.setHeight(150).setWidth(250);
var doc = SpreadsheetApp.getActiveSpreadsheet();
var panel = app.createVerticalPanel();
var handlerCancel = app.createServerHandler('canceltest');
var handlerContinue = app.createServerHandler('continuetest');
var contCHandler = app.createClientHandler();
var cancel = app.createButton("cancel.", handlerCancel).setId('cancel').setVisible(false);
var cont = app.createButton('continue',handlerContinue).setId('continue').setVisible(false).addClickHandler(contCHandler);
var button = app.createButton('start').setId('button');
var handler = app.createServerClickHandler('runtest');
handler.addCallbackElement(panel);
contCHandler.forTargets(button).setEnabled(false).forEventSource().setVisible(false);
var cHandler = app.createClientHandler().forTargets(cancel).setVisible(true).forEventSource().setVisible(false);
button.addClickHandler(handler).addClickHandler(cHandler);
app.add(panel.add(button).add(cont).add(cancel))//.add(trig));
doc.show(app);
}
function canceltest(e){
var app = UiApp.getActiveApplication();
ScriptProperties.setProperty('restoreData','')
ScriptProperties.setProperty('restorePointers','canceled');
SpreadsheetApp.getActiveSpreadsheet().toast(' ','restore aborted');
app.close()
return app;
}
function continuetest(e){
runtest(e)
}
function runtest(e){
var dStart; var dEnd;
ScriptProperties.setProperty('startrestore',new Date().getTime().toString())
if(ScriptProperties.getProperty('restoreData')==null||Utilities.jsonStringify(ScriptProperties.getProperties()).indexOf('restoreData')==-1)
{ScriptProperties.setProperty('restoreData',Utilities.jsonStringify(e))
}
var app = UiApp.getActiveApplication();
var pointers = ScriptProperties.getProperty('restorePointers');
if(pointers=='0#0'){
dStart = 0;
dEnd = 500;
}else{
dStart = Number(pointers.split('#')[0]);
dEnd = Number(pointers.split('#')[1]);
}
// main loop --------------------------
for(var ee=dStart;ee<dEnd;++ee){ // main loop
var ccc = ScriptProperties.getProperty('restorePointers');
if(ccc=='canceled'){ app.close();return app};
Utilities.sleep(85); // simulate some activity
if((ee/10)==parseInt(ee/10)&&ee>0){
SpreadsheetApp.getActiveSpreadsheet().toast(ee+' steps completed')
if(new Date().getTime()-Number(ScriptProperties.getProperty('startrestore'))>12000){ ;// +- 12 sec timeout
ScriptProperties.setProperty('restorePointers',[ee,dEnd].join('#'));
app.getElementById('continue').setHTML('continue from '+ee).setVisible(true)
return app
}
}
}
// end of main loop-----------------
ScriptProperties.setProperty('restoreData','')
ScriptProperties.setProperty('restorePointers',0+'#'+0);
SpreadsheetApp.getActiveSpreadsheet().toast('normal process end');
app.close();
return app;
}
Here's what's keeping the 'continue' button from updating with each interval. Your Server Handler needs to return an app:
function continuetest(e){
return runtest(e) ///<<<
}
This bit, (ee/10)==parseInt(ee/10) is an awkward way to evaluate true every 10th item. Use modulus instead:
if((ee%10==0)&&ee>0){ ///<<< modulus
After each pause, the value of ee is repeated in the toast. This can be fixed by remembering what the last displayed value was, and skipping it.
if (ee == Number(ScriptProperties.getProperty('lastToast'))) continue; ///<<< don't repeat toast
ScriptProperties.setProperty('lastToast',ee); ///<<<
Full script
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [
{name: "test", functionName: "test"},
];
ss.addMenu("test", menuEntries);
}
function test(){
ScriptProperties.setProperty('restorePointers',[0,0].join('#'))
var app = UiApp.createApplication().setTitle("test");
app.setHeight(150).setWidth(250);
var doc = SpreadsheetApp.getActiveSpreadsheet();
var panel = app.createVerticalPanel();
var handlerCancel = app.createServerHandler('canceltest');
var handlerContinue = app.createServerHandler('continuetest');
var contCHandler = app.createClientHandler();
var cancel = app.createButton("cancel.", handlerCancel).setId('cancel').setVisible(false);
var cont = app.createButton('continue',handlerContinue).setId('continue').setVisible(false).addClickHandler(contCHandler);
var start = app.createButton('start').setId('start');
var handler = app.createServerClickHandler('runtest');
handler.addCallbackElement(panel);
contCHandler.forTargets(start).setEnabled(false).forEventSource().setVisible(false);
var cHandler = app.createClientHandler().forTargets(cancel).setVisible(true).forEventSource().setVisible(false);
start.addClickHandler(handler).addClickHandler(cHandler);
app.add(panel.add(start).add(cont).add(cancel))//.add(trig));
doc.show(app);
}
function canceltest(e){
var app = UiApp.getActiveApplication();
ScriptProperties.setProperty('restoreData','')
ScriptProperties.setProperty('restorePointers','canceled');
SpreadsheetApp.getActiveSpreadsheet().toast(' ','restore aborted');
app.close()
return app;
}
function continuetest(e){
return runtest(e) ///<<<
}
function runtest(e){
var dStart; var dEnd;
ScriptProperties.setProperty('startrestore',new Date().getTime().toString())
if(ScriptProperties.getProperty('restoreData')==null||Utilities.jsonStringify(ScriptProperties.getProperties()).indexOf('restoreData')==-1)
{ScriptProperties.setProperty('restoreData',Utilities.jsonStringify(e))
}
var app = UiApp.getActiveApplication();
var pointers = ScriptProperties.getProperty('restorePointers');
if(pointers=='0#0'){
dStart = 0;
dEnd = 500;
}else{
dStart = Number(pointers.split('#')[0]);
dEnd = Number(pointers.split('#')[1]);
}
// main loop --------------------------
for(var ee=dStart;ee<dEnd;++ee){ // main loop
var ccc = ScriptProperties.getProperty('restorePointers');
if(ccc=='canceled'){ app.close();return app};
Utilities.sleep(85); // simulate some activity
if((ee%10==0)&&ee>0){ ///<<< modulus
if (ee == Number(ScriptProperties.getProperty('lastToast'))) continue; ///<<< don't repeat toast
ScriptProperties.setProperty('lastToast',ee); ///<<<
SpreadsheetApp.getActiveSpreadsheet().toast(ee+' steps completed')
if(new Date().getTime()-Number(ScriptProperties.getProperty('startrestore'))>12000) { // +- 12 sec timeout
ScriptProperties.setProperty('restorePointers',[ee,dEnd].join('#'));
app.getElementById('continue').setHTML('continue from '+ee).setVisible(true)
return app
}
}
}
// end of main loop-----------------
ScriptProperties.setProperty('restoreData','')
ScriptProperties.setProperty('restorePointers',0+'#'+0);
SpreadsheetApp.getActiveSpreadsheet().toast('normal process end');
app.close();
return app;
}
Related
i have a spreadsheet with a list of songs that i've selected to ease the boredom of my pupils at school. so i've written this code to publish 3 songs from this list every day at 9:00 AM on my course on classroom and it worked fine for some days, then it started to report the error that you see in the title.
the code is the following
function createTrigger() {
// Trigger every day at 9
ScriptApp.newTrigger('pubblicavideo')
.timeBased()
.atHour(9)
.everyDays(1) // Frequency is required if you are using atHour() or nearMinute()
.create();
}
function onOpen() {
//aggiunge il bottone autotrigger con run e stop all'apertura del documento spreadsheet
var ui = SpreadsheetApp.getUi();
ui.createMenu("Auto Trigger")
.addItem("Run","runAuto")
.addItem("Stop","deleteTrigger")
.addToUi();
}
function runAuto() {
// resets the loop counter if it's not 0
refreshUserProps();
// clear out the sheet
clearData();
// create trigger to run program automatically
createTrigger();
}
function refreshUserProps() {
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('loopCounter', 0);
userProperties.setProperty('contarighe', 1);
}
function deleteTrigger() {
// Loop over all triggers and delete them
var allTriggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < allTriggers.length; i++) {
ScriptApp.deleteTrigger(allTriggers[i]);
}
}
function pubblica(k)
{
var corso = Classroom.Courses.get(61109944129);
var foglio = SpreadsheetApp.getActive();
var linkini = foglio.getRange("C2:C2014");
var titolini = foglio.getRange("B2:B2014");
var autorini = foglio.getRange("A2:A2014");
var cell = linkini.getCell(k, 1);
var cella = titolini.getCell(k, 1);
var cello = autorini.getCell(k, 1);
var link = cell.getValue();
var titolo = cella.getValue();
var autore = cello.getValue();
var courseWork = {
'title': titolo,
'description': autore,
'materials': [
{'link': { 'url': link }}
],
'workType': 'ASSIGNMENT',
'state': 'PUBLISHED',
}
Classroom.Courses.CourseWork.create(courseWork, 61109944129);
}
function clearData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Data');
// clear out the matches and output sheets
var lastRow = sheet.getLastRow();
if (lastRow > 1) {
sheet.getRange(2,1,lastRow-1,1).clearContent();
}
}
function pubblicavideo()
{
var pezzialgiorno = 3; //numero di pezzi da pubblicare ogni giorno
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Data');
var userProperties = PropertiesService.getUserProperties();
var loopCounter = Number(userProperties.getProperty('loopCounter'));
var contarighe = Number(userProperties.getProperty('contarighe'));
// put some limit on the number of loops
// could be based on a calculation or user input
// using a static number in this example
var limit = 671;
// if loop counter < limit number, run the repeatable action
if (loopCounter < limit) {
// see what the counter value is at the start of the loop
Logger.log(loopCounter);
// do stuff
for (var i=0; i<pezzialgiorno; i++)
{
pubblica(contarighe);
contarighe++;
}
// increment the properties service counter for the loop
loopCounter +=1;
userProperties.setProperty('loopCounter', loopCounter);
userProperties.setProperty('contarighe', contarighe);
// see what the counter value is at the end of the loop
Logger.log(loopCounter);
Logger.log(contarighe);
}
// if the loop counter is no longer smaller than the limit number
// run this finishing code instead of the repeatable action block
else {
// Log message to confirm loop is finished
sheet.getRange(sheet.getLastRow()+1,1).setValue("Finished");
Logger.log("Finished");
// delete trigger because we've reached the end of the loop
// this will end the program
deleteTrigger();
}
}
i tried to modify the code but it prevents me from saving it because of the same error. i've tried to look at the executions report and i found this
report of failed executions. you can see (i hope) that it worked until april the 3rd and then nothing worked anymore, not even the onOpen part, always the same error
so i can't change the code, i can't run it, i can't stop it, and it doesn't work. what should i do?
I am running code that takes images from my drive and puts them into google slides. Also I am trying to export data from big query into a table in the same google slides doc. I keep getting this error though, but the API is enabled?
The issue seems to be with this line:
var queryResults = BigQuery.Jobs.query(request, projectId);
Also for some reason the big query data doesn't come into google slides as a table
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Generate Level B', 'showSidebar')
.addToUi();
}
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('sidebar')
.setTitle('Generate Level B');
SpreadsheetApp.getUi().showSidebar(ui);
}
function showPrompt() {
var ui = SpreadsheetApp.getUi();
var result = ui.prompt(
'Generate custom company slide',
'Please enter the ticker symbol for the company:',
ui.ButtonSet.OK_CANCEL);
// Process the user's response.
var button = result.getSelectedButton();
var text = result.getResponseText();
if (button == ui.Button.OK) {
// User clicked "OK".
mergeSlide(text);
} else if (button == ui.Button.CANCEL) {
// User clicked "Cancel".
return;
} else if (button == ui.Button.CLOSE) {
// User clicked X in the title bar.
return;
}
}
function test() {
mergeSlide("DSYJ.J", "");}
function mergeSlide(tickerSymbol,companyName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var dataTicker = flatten(sheet.getRange(3, 1, lastRow-2, 1).getValues());
var dataName = flatten(sheet.getRange(3, 2, lastRow-2, 1).getValues());
var dataDesc = flatten(sheet.getRange(3, 3, lastRow-2, 1).getValues());
//Find index based on ticker/name
if(tickerSymbol != ""){
var index = dataTicker.indexOf(tickerSymbol);
var companyDesc = dataDesc[index];
var companyName = dataName[index];
}else if(companyName != ""){
var index = dataName.indexOf(companyName);
var companyDesc = dataDesc[index];
var tickerSymbol = dataTicker[index];
}else{
return;
}
var slideUrl = DriveApp.getFileById("xxxx").makeCopy(companyName).getUrl();
var slide = SlidesApp.openByUrl(slideUrl);
var slides = slide.getSlides();
//Slide1
var shapesSlide1 = slides[0].getShapes();
shapesSlide1[0].getText().setText(companyName);
//Slide2
var shapesSlide2 = slides[1].getShapes();
shapesSlide2[0].getText().setText(companyDesc);
//Slide3
// Replace this value with the project ID listed in the Google Cloud Platform project.
var projectId = 'vital-platform-791';
var sqlQuery = 'SELECT Price FROM [vital-platform-791.feeds.chrome_blue_button_valuegrid_lookup] LIMIT 5';
var request = {
query: sqlQuery
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
if (rows) {
// Get the headers.
var headers = queryResults.schema.fields.map(function(field) {
return field.name;
});
// Get the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
var table = slides[2].insertTable(rows.length+1, headers.length);
//Fill up the table header
for(var m = 0; m< headers.length; m++){
table.getCell(0,m).getText().setText(headers[m]).getTextStyle().setForegroundColor(255,0,86).setBold(true);
}
//Fill up rest of table
for(var k = 1; k< rows.length+1; k++){
for(var m = 0; m< headers.length; m++){
table.getCell(k,m).getText().setText(data[k-1][m]);
}
}
}
//Slide4
var shapeSlide4 = slides[3].getShapes();
var priceChangeImage = DriveApp.getFilesByName("Price Change_"+tickerSymbol+".png").next();
var newImage4 = shapeSlide4[0].replaceWithImage(priceChangeImage);
newImage4.setWidth(650);
newImage4.alignOnPage(SlidesApp.AlignmentPosition.HORIZONTAL_CENTER);
//Slide5
var shapeSlide5 = slides[4].getShapes();
var earningsRevisionsImage = DriveApp.getFilesByName("Earnings Revisions_"+tickerSymbol+".png").next();
var newImage5 = shapeSlide5[0].replaceWithImage(earningsRevisionsImage);
newImage5.setWidth(650);
newImage5.alignOnPage(SlidesApp.AlignmentPosition.HORIZONTAL_CENTER);
//Slide6
var shapeSlide6 = slides[5].getShapes();
var FgpeImage = DriveApp.getFilesByName("F-GPE_"+tickerSymbol+".png").next();
var newImage6 = shapeSlide6[0].replaceWithImage(FgpeImage);
newImage6.setWidth(650);
newImage6.alignOnPage(SlidesApp.AlignmentPosition.HORIZONTAL_CENTER);
newSlideNotify(slideUrl);
}
// Takes and array of arrays matrix and return an array of elements.
function flatten(arrayOfArrays){
return [].concat.apply([], arrayOfArrays);
}
function newSlideNotify(url) {
var htmlOutput = HtmlService
.createHtmlOutput('<p style="font-family:Arial;font-size:13px;">A Level B report has been created for the company that you have selected.<br><br>This new file has been placed in the same folder with the Slide Template.<br><br></p>Open Level B')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(500)
.setHeight(150);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Level B Generated!');
}
function getList() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var dataTicker = flatten(sheet.getRange(3, 1, lastRow-2, 1).getValues());
var dataName = flatten(sheet.getRange(3, 2, lastRow-2, 1).getValues());
return [dataTicker,dataName];
}
You need to enable the Advanced Service for BigQuery in your Google-Apps-script:
In this link about the BigQuery Service:
Note: This is an advanced service that must be enabled before use.
...which redirects you to this link where it explains how to enable advanced services:
In the script editor, select Resources > Advanced Google services....
Click the on/off switch next to the service you want to use (in your case BigQuery API).
Click OK.
The next steps in the link explain you how to enable the API in the GOOGLE CLOUD PLATFORM Console (which I assume you have already done as you said that the API is already enabled)
Does the error look like this?
Access Not Configured. BigQuery API has not been used in project
5622793721 before or it is disabled. Enable it
If so, the problem is that you need to go to your Dashboard and enable it.
Open your script file
Go to Resources > Advanced Google Services
Notice the message saying These services must also be enabled in the Google API Console.
Click the link where it says Google API Console
After searching for 'bigquery', do not select the one called Bigquery API. You are looking for the one called BigQuery Data Transfer API
Enable it
Run your code again to see if it works now
You may have to activate your email to the Analytics user management.
I'm trying to get a button to fire more than once(I.e. multiple clicks) but it seems to not be working. Any help would be greatly appreciated. Theoretically it should fire multiple times but it only fires once when I check it in the logs
function a
{
...
var addcolumnspanel = app.createHorizontalPanel().setId("addcolumnspanel");
var addbuttonhandler = app.createServerHandler("addcolumn");
var addbutton = app.createButton().setId("btnaddcolumn").setText("Add another column").addClickHandler(addbuttonhandler);
...
return app;
}
function addcolumn()
{
...//Do some stuff
return app;
}
Here is a more precise code example
//set global var
var counter = 1;
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Set up the Menu bar
function onOpen() {
// Logger.clear();
var menuEntries = [ {name: "demo", functionName: "myFunction"}];
ss.addMenu("Demo", menuEntries);
}
function myFunction() {
var myapp = UiApp.createApplication().setHeight(430).setWidth(800);;
var button = myapp.createButton("Clicky");
var myhandler = myapp.createServerHandler("secondfunction");
var myhandler = button.addClickHandler(myhandler)
myapp.add(button);
ss.show(myapp);
}
function secondfunction()
{
counter++;
Logger.log(counter);
}
OK. The problem is with the counter variable. You cannot use global variables that way in Apps Script. See this answer for more information. You can use ScriptProperties or CacheService as an alternative.
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Set up the Menu bar
function onOpen() {
// Logger.clear();
var menuEntries = [ {name: "demo", functionName: "myFunction"}];
ss.addMenu("Demo", menuEntries);
// Store your counter in CacheService as a string.
CacheService.getPrivateCache().put('counter','1',3600);
}
function myFunction() {
var myapp = UiApp.createApplication().setHeight(430).setWidth(800);;
var button = myapp.createButton("Clicky");
var myhandler = myapp.createServerHandler("secondfunction");
var myhandler = button.addClickHandler(myhandler)
myapp.add(button);
ss.show(myapp);
}
function secondfunction()
{
var cache = CacheService.getPrivateCache();
var counter = parseInt(cache.get('counter'));
counter ++;
cache.put('counter', counter.toString());
Logger.log(counter);
}
My code is below. It will accept data from the input text; then it will fetch the recent newest feed from stackoverflow(based in the input) in google spreadsheet.
I have(wanted) set an external gif image to be shown as a progress indicator while fetching of rss feed and its processing is going on.
Problem is: When i remove the commented part; that gif image will never be visible to the user and when that is remained as a comment; that gif image is being loaded by the app after the completion of the process and remained then after.
I want it to be visible only when the process(fetching of rss and processing of it) is going on. So is there any way to make it possible?
function stackoverflow(){
var app =UiApp.createApplication().setHeight(380).setWidth(800);
app.setTitle("Enter tag name");
var mydoc=SpreadsheetApp.getActiveSpreadsheet();
var txtBox = app.createTextBox().setFocus(true).setWidth("150").setId("ticker").setName("ticker");
var mainpanel = app.createHorizontalPanel().setId('mainpanel');
mainpanel.add(txtBox);
var subbtn = app.createButton("Get posts!").setId("tick").setWidth("80");
mainpanel.add(subbtn);
var myloadingimg=app.createImage("http://schedule.msu.edu/img/InProgress.gif").setHeight("26").setWidth("26").setId("loadingimg");
mainpanel.add(myloadingimg.setVisible(false));
app.add(mainpanel);
var panel = app.createVerticalPanel().setId('panel');
var submitHandler = app.createServerHandler("clicker").addCallbackElement(mainpanel);
subbtn.addClickHandler(submitHandler);
app.add(panel);
mydoc.show(app);
}
function clicker(e){
var app = UiApp.getActiveApplication();
var txtBox = app.getElementById("ticker");
app.getElementById("loadingimg").setVisible(true);
var panel=app.getElementById("panel");
app.remove(1);
var panel = app.createVerticalPanel().setId('panel');
var stackurl = "http://stackoverflow.com/feeds/tag?tagnames="+e.parameter.ticker+"&sort=newest";
var stackXML = UrlFetchApp.fetch(stackurl).getContentText();
var stackDOC = Xml.parse(stackXML, false);
var stackentry = stackDOC.getElement().getElements('entry');
for (var i = 0; i < stackentry.length; i++) {
var result = stackentry[i];
panel.add(app.createHTML("<br><b>Post Title: </b>"+ result.getElement('title').getText()+"<br>"));
panel.add(app.createAnchor('', '') .setText("Post URL").setHref(result.getElement('link').getAttribute('href').getValue()));
panel.add(app.createHTML("<br>"));
}
var scroll = app.createScrollPanel().setPixelSize(760, 280);
scroll.add(panel);
app.add(scroll);
//app.getElementById("loadingimg").setVisible(false);
return app;
}
function onOpen()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name:'stackoverflow',functionName:'stackoverflow'});
ss.addMenu("f2", menuEntries);
}
You can make use of clientHandlers which are meant for precisely such cases.
function stackoverflow(){
...
var clientHandler = app.createClientHandler().forTargets(myloadingimg).setVisible(true);
var submitHandler = app.createServerHandler("clicker").addCallbackElement(mainpanel);
subbtn.addClickHandler(submitHandler).addClickHandler(clientHandler);
...
}
function clicker(e){
var app = UiApp.getActiveApplication();
....
app.getElementById("loadingimg").setVisible(false);
return app;
}
I am getting "TypeError: Cannot read property "parameter" from undefined." when trying to log e.parameter properties. (I inserted the following lines in the contactMe() function)
Logger.log(e.parameter.textBox);
Logger.log(e.parameter);
The script otherwise works fine, any idea?
function doGet() {
var app = UiApp.createApplication();
var mainPanel = app.createVerticalPanel().setId('mainPanel');
app.add(mainPanel);
mainPanel.add(app.createLabel('Enter your email to sign up'));
var form = app.createHorizontalPanel();
mainPanel.add(form);
var email = app.createTextBox().setName('textBox').setId('textBox');
form.add(email);
var button = app.createButton('Sign up');
form.add(button);
var info = app.createLabel().setVisible(true).setId('info');
mainPanel.add(info);
//handler
var handler = app.createServerHandler('contactMe').addCallbackElement(mainPanel);
button.addClickHandler(handler);
return app;
}
function contactMe(e){
var app = UiApp.getActiveApplication();
Logger.log("testing");
Logger.log(e.parameter);
Logger.log(e.parameter.textBox);
app.getElementById('textBox').setValue('').setStyleAttribute("color", "black");
app.getElementById('info').setText('Thank you!').setStyleAttribute("color", "black");
var ss = SpreadsheetApp.openById('0AqKSxC6f0Cc7dF9aT1lUeXFEcnR2eUFYRGs4Y1NiVVE')
.getSheets()[0];
var range = ss.getRange(ss.getLastRow()+1, 1, 1, 2);
var values = [[new Date(),e.parameter.textBox]];
range.setValues(values);
return app;
}
I just tested your exact code (except the sheet stuff) and it works nicely... except that the logger doesn't show anything when called from a handler function but that's a known issue...
I used the label to check the e.parameter value like this :
app.getElementById('info').setText(e.parameter.textBox).setStyleAttribute("color", "black");
A bit out of the box but i think it should work:
function doGet() {
var app = UiApp.createApplication();
var mainPanel = app.createFormPanel;
app.add(mainPanel);
mainPanel.add(app.createLabel('Enter your email to sign up'));
var form = app.createHorizontalPanel();
mainPanel.add(form);
var email = app.createTextBox().setName('textBox').setId('textBox');
form.add(email);
var button = app.createSubmitButton('Sign up');
form.add(button);
var info = app.createLabel().setVisible(true).setId('info');
mainPanel.add(info);
return app;
}
function doPost(e){
var app = UiApp.getActiveApplication();
//Logger wont work in uiApps
//in Form panels the UI is cleared so you want to write a thank you note
app.add(app.createLabel("Thanks"));
var ss = SpreadsheetApp.openById('0AqKSxC6f0Cc7dF9aT1lUeXFEcnR2eUFYRGs4Y1NiVVE')
.getSheets()[0];
var range = ss.getRange(ss.getLastRow()+1, 1, 1, 2);
var values = [[new Date(),e.parameter.textBox]];
range.setValues(values);
return app;
With kind regards,
Thomas van Latum
I just copy pasted your complete code made a spreadsheet and ran it.
It works just perfectly dont forget your } at the end.....