Google Apps Script Find function caller id

2019-02-25 21:09发布

问题:

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?
}

回答1:

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) ...



回答2:

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.



回答3:

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];
}