0
votes

Because I have a Google spreadsheet workbook with so many sheets that they are not all visible in the pulldown on the bottom left side of the spreadsheet workbook, I am attempting to modify the code at "How to get the list of all sheet in a dropdown list in a sidebar" from a standalone script to a bound script in order to be able to see a longer list. Also, I do not want my list in a dropdown. I want it simply as a bulleted list.

I am getting a malformed HTML error that I assume is being generated from within the scriplet. (See code below.) Any ideas what is going wrong with this code.

HTML

<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <select name="Sheets List" onchange="listSheets()")>
    <? var sheets=spreadsheet.getSheets(); ?>
    <? for(var i=0;i<sheets.length;i++) { ?>
      <option value=<?=sheets[i].getName()?>> <?= sheets[i].getName()?></option>
    <? } ?>
    </select>
  <script>
   function listSheets(){
     var name=document.getElementsByName("Sheets List")[0].value;
     google.script.run.goToSheet(name);
    };
  </script>
  </body>
  </html>

GS

function onOpen() {
   var ui = SpreadsheetApp.getUi();
   ui.createMenu('Custom')
      .addItem('Sheets List', 'sheetsList')   
      .addToUi();

function sheetsList(){
  var html = HtmlService.createHtmlOutputFromFile('sheets').evaluate
      .setTitle('Sheets in this Workbook')
      .setWidth(300);
  SpreadsheetApp.getUi()
  .showSidebar(html);
}
}

Error Message

Message details Malformed HTML content: > function listSheets(){ var name=document.getElementsByName("Sheets List")[0].value; google.script.run.goToSheet(name); }; .

3
Why is there a ) here: listSheets()" ) >TheMaster

3 Answers

2
votes

Sheet Link List in Sidebar

function allsheetslist() {
  var ss=SpreadsheetApp.getActive();
  var shts=ss.getSheets();
  var html='<table>';
  shts.forEach(function(sh,i){
    html+=Utilities.formatString('<tr><td><input type="button" value="%s" onClick="gotoSheet(%s);" /></td></tr>',sh.getName(),sh.getIndex());
  });
  html+='</table>';
  html+='<script>function gotoSheet(index){google.script.run.gotoSheetIndex(index);}</script>';
  var userInterface=HtmlService.createHtmlOutput(html)
  SpreadsheetApp.getUi().showSidebar(userInterface);
}

function gotoSheetIndex(index) {
  var ss=SpreadsheetApp.getActive();
  var shts=ss.getSheets();
  shts[index-1].activate();
}

You can get a lot more buttons on the side bar this way:

function allsheetslist() {
  var ss=SpreadsheetApp.getActive();
  var shts=ss.getSheets();
  var html='<style>input[type="button"]{margin:2px 5px 2px 0;border:none;background:white;}</style>';
  shts.forEach(function(sh,i){
    html+=Utilities.formatString('<input type="button" value="%s" onClick="gotoSheet(%s);" />',sh.getName(),sh.getIndex());
  });
  html+='<script>function gotoSheet(index){google.script.run.gotoSheetIndex(index);}</script>';
  var userInterface=HtmlService.createHtmlOutput(html).setTitle("Sheet Link List")
  SpreadsheetApp.getUi().showSidebar(userInterface);
}
2
votes

You have a few issues that are preventing the sidebar from showing:

  1. You should be using HtmlService.createTemplateFromFile(), not createHtmlOutputFromFile().
  2. To generate the HTML, you need to be sure to include the parentheses when calling .evaluate(). (Related to the first point, note that evaluate() is only available for HtmlTemplate objects.)
  3. sheetsList() should not be nested within your onOpen() function.
  4. You need to define spreadsheet in your HTML.

GS

function onOpen() {
  SpreadsheetApp.getUi().createMenu('Custom')
  .addItem('Sheets List', 'sheetsList')   
  .addToUi();
}

function sheetsList(){
  var html = HtmlService.createTemplateFromFile('sheets').evaluate()
    .setTitle('Sheets in this Workbook')
    .setWidth(300);
  SpreadsheetApp.getUi().showSidebar(html);
}

HTML In the HTML below, I removed the frontend JS code for listSheets() because it wasn't part of the question's scope and was calling a backend function that was also not included in the question.

<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <select name="Sheets List">
      <? var spreadsheet = SpreadsheetApp.getActive(); ?>
      <? var sheets=spreadsheet.getSheets(); ?>
      <? for(var i=0;i<sheets.length;i++) { ?>
      <option value=<?=sheets[i].getName()?>> <?= sheets[i].getName()?></option>
      <? } ?>
    </select>
  </body>
</html>
0
votes

Tried the @Cooper way. Its easier and more friendly for me. But the problem still pending is that the "OnClick" function is not called and nothing happens when the sheet name button is clicked on the side bar. I have even added a specific field to be displayed along with sheet name in the sidebar. That works fantastically. Now the only help needed is to activate the click. I have tried many ways still no success. The code used is as below:

function allsheetsList() {
  var ss = SpreadsheetApp.getActive();
  var shts = ss.getSheets();
  var html = '<table>';
  shts.forEach(function(sh, i) {
    html += Utilities.formatString('<tr><td><input type="button" value="%s" onClick="google.script.run.gotoSheet(\'%s\');" /></td>', sh.getName(), sh.getName());
    html += Utilities.formatString('<td><input type="button" value="%s" /></td></tr>', sh.getRange("C2").getValue());
  });
  html += '</table>';
  var userInterface = HtmlService.createHtmlOutput(html).setTitle("Sheet Link List");
  SpreadsheetApp.getUi().showSidebar(userInterface);
}

function gotoSheet(name) {
  var ss = SpreadsheetApp.getActive();
  ss.getSheetByName(name).activate();
}