1

I want to create an interactive web application using html service google apps script.

I am having trouble with adding an onclick event with a function into a button.

The functions are executed when the web loads for the first time, but not when it is clicked. If I click the button later, nothing happens.

Here is the link for my project

Code.gs :

function doGet() {
  var template = HtmlService.createTemplateFromFile('Index');

  return template.evaluate()
      .setTitle('Web App Window Title')
      .setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function getmenus() {
  var folder = DriveApp.getFolderById('0B5vEst6Tvg8nfmhRU1h4V044ODJlX2VxeHdKeFFicUx0UlMzMWhZcUxjTkRHSlZiR3FlT1k');
  var datax = []
  var result = [[]];
  var filess = folder.getFilesByType(MimeType.GOOGLE_SHEETS);
  while (filess.hasNext()) {
    datax.push(filess.next());
  }
  datax.sort(function sorting(x,y){
      var xp = x.getName().toLowerCase();
      var yp = y.getName().toLowerCase();
      return xp == yp ? 0 : xp < yp ? -1 : 1;
    });
  for (var a in datax) {
    var ss = SpreadsheetApp.openById(datax[a].getId());
    var info = ss.getSheetByName('Info');
    var url = info.getRange('B1').getValue();
    result[a] = [datax[a].getName(),datax[a].getId(),url];
  }
  return result;
}
function processmenu(result) {
  var ss = SpreadsheetApp.openById(result);
  var sheet = ss.getActiveSheet();
  var range = sheet.getDataRange();
  var values = range.getValues();
  return values;
}

JavaScript.html :

<script>

google.script.run.withSuccessHandler(loadmenu).getmenus();

function loadmenu(result) {
  var mainmenu = document.getElementById('menunav');
  mainmenu.innerHTML='';
  for (var a in result) {
    var form = document.createElement('form');
    var hidden = document.createElement('input');
    hidden.type='hidden';
    hidden.name='name';
    hidden.value=result[a][1];

    var button = document.createElement('input');
    button.type='button';
    button.name='menu';
    button.value=result[a][0];
    button.onclick=menuclick(result[a][1]);

    form.appendChild(hidden);
    form.appendChild(button);

    mainmenu.appendChild(form);
    var br = document.createElement("br");
    mainmenu.appendChild(br);

  }
}
function menuclick(result) {
google.script.run.withSuccessHandler(updateoptions).processmenu(result);
}
function updateoptions(values) {
  alert(values);
}

</script>

Please help me to solve the problem and maybe how to rewrite the code in a better way.

Thanks

3
  • Have you added the trigger to you your function? You will need to link the event to a trigger, in order for the event to execute a method. Commented Aug 20, 2015 at 21:28
  • Do you know how to add "onclick" trigger on this function ? I think it is already done in this line : button.onclick=menuclick(result[a][1]); Commented Aug 21, 2015 at 4:51
  • I updated your Apps Script code. Thank you for providing access to the file. That made finding the problem achievable. Commented Aug 22, 2015 at 3:33

2 Answers 2

1

This is a tricky one. Setting the onclick attribute using the DOM expects a function. And you can't use a text formula as the function, because it evaluates to a string instead of an object. So you need to create a new function with the new key word. Right now you have:

button.onclick=menuclick(result[a][1]);

Change to:

var newFunction = new Function("menuclick('" + result[a][1] + "')");
button.onclick=newFunction;

The value of the onclick attribute must be a function. In your case, you need to construct a function with a dynamic argument to be passed. You can construct the textual part of the formula with a string formula. But then the string needs to be used to create a function object.

In JavaScript you can concatenate string values with a plus sign.

"menuclick('" is a string.

result[a][1] is a string.

"')" is a string.

Note that you need to isolate the result[a][1] part between the two other strings. This is because result[a][1] needs to be evaluated, and a value retrieved from the object array.

I would also put the google.script.run call into a window.onload event:

window.onload = function() {
  console.log("window.onload ran!");
  google.script.run.withSuccessHandler(loadmenu).getmenus();
};

And also, use IFRAME sandbox mode:

.setSandboxMode(HtmlService.SandboxMode.IFRAME);
Sign up to request clarification or add additional context in comments.

1 Comment

Great thanks @Sandy for your changes to my code. Now I can see the problem that we need to define the function first. I am so sorry I don't have enough reputation point to mark this answer. Thx again for your help.
0

Just FYI for anyone else coming here from google, the selected answer above did not work for me.

var newFunction = new Function("functionName(" + param + ")");
element.onclick=newFunction;

I had to do this instead

element.setAttribute("onclick","functionName(" + param + ")");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.