I have a Google Apps Script that dynamically generates buttons and assigns for each a ClickHandler which in turn calls a function.
My problem is that because every button calls the same function I can't find a way to indentify which of them actually made the call. Here is a code sample:
var handler = app.createServerHandler("buttonAction");
for (i=1,...) {
app.createButton(...).setId(i).addClickHandler(handler);
}
function buttonAction() {
//How do I know what button made the call?
}
Another option is to use the e.parameter.source value to determine the ID of the element that triggered the serverHandler to be called.
Here's an example:
function doGet(e) {
var app = UiApp.createApplication();
var handler = app.createServerHandler("buttonAction");
for (var i = 0; i < 4; i++) {
app.add(app.createButton('button'+i).setId(i).addClickHandler(handler));
}
return app;
}
function buttonAction(e) {
var app = UiApp.getActiveApplication();
Logger.log(e.parameter.source);
}
e.parameter.source will contain the ID of the element, which you could then use to call app.getElementById(e.parameter.source) ...
You could create multiple handlers, each for one button:
for (i=1,...) {
var handler = app.createServerHandler("buttonAction" + i);
app.createButton(...).setId(i).addClickHandler(handler);
}
function buttonAction1() {
// code to handle button 1
}
function buttonAction2() {
// code to handle button 2
}
function buttonAction...
I wouldn't recommend of having these sort of "anonymous" action handlers though, as you might be having troubles later in remembering which actionX does what.
(e.g. have a different approach, w/o a loop, or prepare a dictionary-like/array object of meaningful handler names before that loop.)
OTOH, you could use event object argument provided to your callback function:
function buttonAction(event) {
// use event object here to identify where this event came from
}
The thing is the above event
object properties depends on where your callback is being called from. For instance, if it were a submit button where you had a Form, then you could access parameters submitted by that from like so: event.parameter.myParamName
. See code sample here.
So, if you have a variable number of buttons, you could use a hidden element + the button:
for (i=1,...) {
var hiddenAction = app.createHidden("action", "action"+i);
var handler = app.createServerHandler("buttonAction");
handler.addCallbackElement(hiddenAction);
var btn = app.createButton("Button text", handler);
// you'll need to add both btn and hidden field
// to the UI
app.add(hiddenAction);
app.add(btn);
}
Then, your buttonAction
might look like this:
function buttonAction(e) {
var action = e.parameter.action;
// do something based on action value here
// which will be one of "action1", "action2", ...
}
The above is a copy & paste from Hidden class sample.
The above might not work out of the box, but you get the idea: create a hidden element that holds the info you need in your callback, and attach that hidden to your server handler. You could even create multiple hidden elements or a Form panel.
I have the same issue. It works using Tag.
EG
SETUP
var button = addButton(app
,panel
,"buttonActiveTrelloProjects_" + i.toString()
,appVars.buttonWidth() + "px"
,appVars.level2ButtonHeight().toString() + "px"
,false
,false
,"Trello"
,"buttonActiveTrelloProjectsHandler"
,(appVars.buttonLhsGap() * buttonCntr) + (appVars.buttonWidth() * (buttonCntr - 1 ) + 9)
,(appVars.level2ButtonTopGap() * 34)
,3
,"button");
button.setTag(projectName );
USE
function buttonActiveProjectsChartHandler_1(button){
...
buttonTag = getButtonTag(button);
chartType = buttonTag.split(";")[1];
activeProject = buttonTag.split(";")[0];
...
}
function getButtonTag(button){
var jsonButton = JSON.stringify(button);
var source = button.parameter.source;
var tagPtr = source + "_tag";
return button.parameter[tagPtr];
}