所有选项卡的 Google Sheets 索引侧边栏 - 添加搜索功能

问题描述 投票:0回答:3

经过一番搜索,我发现这段代码可以将 Google 表格中所有选项卡(工作簿)的侧边栏作为超链接获取。如果可能的话,我希望为此添加两个功能

  1. 搜索功能 - 侧边栏上的搜索框可以更轻松地查找选项卡
  2. 同一选项卡 - 在同一浏览器选项卡中打开单击的超链接选项卡,而不是在新窗口中打开。

这是到目前为止的代码:

    function onOpen() {
      SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
          .createMenu('Sidebar Menu')
          .addItem('Show sidebar', 'showSidebar')
          .addToUi();
    }
    
    function showSidebar() {
      var ui = HtmlService.createTemplateFromFile('sidebar.html')
          .evaluate()
          .setSandboxMode(HtmlService.SandboxMode.IFRAME)
          .setTitle('Index Sidebar');
      
      SpreadsheetApp.getUi().showSidebar(ui);
    }
        
    function getSheetNames() {
      
      // Get all the different sheet IDs
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheets = ss.getSheets();
      
      return sheetNamesIds(sheets);
    }
        
    // function to create array of sheet names and sheet ids
    function sheetNamesIds(sheets) {
      
      var indexOfSheets = [];
      
      // create array of sheet names and sheet gids
      sheets.forEach(function(sheet){
        indexOfSheets.push([sheet.getSheetName(),sheet.getSheetId()]);
       
      });
      
      //Logger.log(indexOfSheets);
      return indexOfSheets; 
    }

HTML

<!DOCTYPE html>
<h1>Index of all sheets in this workbook:</h1>
<input type="button" value="Close" onclick="google.script.host.close()" />

<ol>
<?!= getSheetNames().map(function(d) {
    return "<li><a href='https://docs.google.com/spreadsheets/d/1234/edit#gid=" + d[1] + "' target='_blank'>" + d[0] + "</a></li>";
    }).join(''); ?>
</ol>
javascript google-apps-script google-sheets
3个回答
3
投票

建议的解决方案

您应该能够用下面的代码替换您发布的代码并使其正常工作。首先将其复制并粘贴到两个文件中,然后从工作表运行,而不是从脚本编辑器运行。

enter image description here

HTML

<!DOCTYPE html>
<h1>Index of all sheets in this workbook:</h1>
<script>

function removeElement(elementId) {
    var element = document.getElementById(elementId);
    element.parentNode.removeChild(element);
}

function buildList(text) {
    google.script.run.withSuccessHandler(onSuccess).returnListItems(text)
}

function onSuccess(result) {
    var element = document.createElement("ol")
    element.innerHTML = result
    var sidebar = document.getElementById("sidebar")
    sidebar.appendChild(element)
}

function getTextAndSearch() {
    var text = document.getElementById("text-search").value
    removeElement("ol")
    buildList(text)
}


</script>
<sidebar id="sidebar">
    <input type="button" value="Close" onclick="google.script.host.close()" />
    <br>
    <input type="text" id="text-search" />
    <input type="button" value="Search" onclick="getTextAndSearch()" />

    <ol id="ol">
       <?!=
        returnListItems()
       ?>
    </ol>
</sidebar>

JS

function onOpen() {
  SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
  .createMenu('Sidebar Menu')
  .addItem('Show sidebar', 'showSidebar')
  .addToUi();
}

function showSidebar() {
  var ui = HtmlService.createTemplateFromFile('sidebar.html')
  .evaluate()
  .setSandboxMode(HtmlService.SandboxMode.IFRAME)
  .setTitle('Index Sidebar');
  
  SpreadsheetApp.getUi().showSidebar(ui);
}

function getSheetNames() {
  
  // Get all the different sheet IDs
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();
  
  return sheetNamesIds(sheets);
}

// function to create array of sheet names and sheet ids
function sheetNamesIds(sheets) {
  
  var indexOfSheets = [];
  
  // create array of sheet names and sheet gids
  sheets.forEach(function(sheet){
    indexOfSheets.push([sheet.getSheetName(),sheet.getSheetId()]);
    
  });
  
  //Logger.log(indexOfSheets);
  return indexOfSheets; 
}

// function to return a button with onclick attribute for each sheet that matches

function returnListItems(text) {
  
    var sheetNames = getSheetNames()
    
    // Checking if there is a search term
    if (text) {
      sheetNames = sheetNames.filter(n => n[0].includes(text))
    }
    
    var htmlString = sheetNames.map(function(d) {
        var string = `
        <li> 
          <input
           type="button"
           value="${d[0]}"
           onclick=\"google.script.run.setActiveByName('${d[0]}')\"/>
        </li>
        `
        return string }).join(' ')
    
    return htmlString
}

// Utility function to set Active sheet by name.
function setActiveByName(name) {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(name)
  SpreadsheetApp.setActiveSheet(ss)
}

您可能需要在脚本编辑器中创建一个虚拟函数:

function init(){}
并运行它只是为了授予脚本所需的权限,尽管当您从菜单运行脚本时应该会发生这种情况。

说明

使纸张成为焦点 -
setActiveSheet

这相对简单,所以我已将其包含在答案中,尽管从技术上讲是第二个问题。将来确保每个帖子只问一个问题,这样可以使网站上的内容更加整洁,并且将来的用户更容易搜索答案。谢谢你

这涉及到使用

setActiveSheet
,我为此创建了效用函数
setActiveByName

为了将此函数插入到每个链接中,我编写了函数

returnListItems
,该函数为每个按钮生成并返回 HTML,以便在单击时调用
setActiveByName
。将其编写为第二个函数并不是绝对必要的,但它使事情变得更清晰,特别是因为它会使主要问题变得容易得多。

搜索功能

刚开始时看似相对简单的事情很快就变得相当复杂。它涉及将一些代码分解为其组件功能,以使其更易于使用。然而,最大的挑战是正确设置服务器端代码(Apps 脚本编辑器)和客户端代码(包含在 HTML 中)。

加载侧边栏后,我发现对侧边栏 HTML 的任何进一步操作都需要在客户端完成,因此需要在 HTML 中完成功能。解决方案位于文档中的“客户端到服务器通信”文章中。

按下搜索按钮,然后客户端脚本获取搜索输入框中的文本,将其传递给

buildList
函数(也是客户端),该函数依次调用:

google.script.run.withSuccessHandler(onSuccess).returnListItems([SEARCH_TERM])

这是一个位于服务器端的异步函数。 “成功处理程序”是返回列表项时运行的回调函数。

onSuccess
只是更新侧边栏中的 HTML。我修改了
returnListItems
函数以能够接受搜索词,因此当它第一次运行时,它运行时不带任何参数,因此所有工作表都会返回。当由客户端函数调用时,它会以文本运行。如果工作表名称包含搜索词,则会列出它。

参考文献


1
投票

感谢 Ian 提供的上述解决方案。 效果很好! 经过一番尝试和错误后,我能够对其进行调整以确保不包含隐藏的工作表。 以下是其他感兴趣的人的更新代码:

function onOpen() {
  SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
  .createMenu('Sidebar Menu')
  .addItem('Show sidebar', 'showSidebar')
  .addToUi();
}

function showSidebar() {
  var ui = HtmlService.createTemplateFromFile('Sidebar.html')
  .evaluate()
  .setSandboxMode(HtmlService.SandboxMode.IFRAME)
  .setTitle('Index Sidebar');
  
  SpreadsheetApp.getUi().showSidebar(ui);
}


function getSheetNames() {
  
  // Get all the different sheet IDs
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets().filter(s => !s.isSheetHidden());
  
  return sheetNamesIds(sheets);
}


// function to create array of sheet names and sheet ids
function sheetNamesIds(sheets) {
  
  var indexOfSheets = [];

  // create array of sheet names and sheet gids
  sheets.forEach(function(sheet){
  
    indexOfSheets.push([sheet.getSheetName(),sheet.getSheetId()]);
        
  });

  
  //Logger.log(indexOfSheets);
  return indexOfSheets; 
}


// function to return a button with onclick attribute for each sheet that matches
function returnListItems(text) {
  
    var sheetNames = getSheetNames()
    
    // Checking if there is a search term
    if (text) {
      sheetNames = sheetNames.filter(n => n[0].includes(text))
    }
    
    var htmlString = sheetNames.map(function(d) {
        var string = `
        <li> 
          <input
           type="button"
           value="${d[0]}"
           onclick=\"google.script.run.setActiveByName('${d[0]}')\"/>
        </li>
        `
        return string }).join(' ')
    
    return htmlString
}



// Utility function to set Active sheet by name.
function setActiveByName(name) {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(name)
  SpreadsheetApp.setActiveSheet(ss)
}

© www.soinside.com 2019 - 2024. All rights reserved.