如何将值从Google脚本

时间:2017-06-30 17:55:25

标签: javascript html google-apps-script

我有一张google工作表,维护一个项目列表,并在其后面运行一些脚本。我已经能够添加功能以单击“添加项目”按钮,该按钮将打开一个用于输入信息的HTML窗口,在提交时,可以向工作表添加新记录。

现在,如果状态更改为“已取消”,我正在处理删除记录的过程。我想要做的是显示一个html窗口,列出项目的某些细节,并让用户有机会在不取消项目的情况下返回,或者输入一些关于它被取消的原因的说明,然后继续

我被困在哪里用html窗口填充项目的详细信息。我找到了一种方法,但我知道这不是最好的方法。

Google Script:

function onEdit(e) {
  if(e.range.getColumn() == 9 && e.value == "Cancelled" && e.source.getActiveSheet().getName() == "Summary") {
    var cancelSheet = ss.getSheetByName(e.source.getActiveSheet().getName());
    var cancelRange = cancelSheet.getRange(e.range.getRow(), 1, 1, cancelSheet.getLastColumn());
    var cancelRow = cancelRange.getValues();

    openCancelDialog(cancelRow);
  }
}

function openCancelDialog(x) {
  var html = HtmlService
  //.createHtmlOutputFromFile('Cancel')
  .createHtmlOutput(
    '<table><tr><td colspan = \"2\"><b>You are cancelling the following project:</b></td></tr>' +
    '<tr><td>Project Name: </td><td>' + x[0][4] + '</td></tr>' + 
    '<tr><td>Project Number: </td><td>' + x[0][0] + '</td></tr>' + 
    '<tr><td>Project Category: </td><td>' + x[0][1] + '</td></tr>' + 
    '<tr><td>Business Owner: </td><td>' + x[0][17] + '</td></tr>' + 
    '<tr><td>Project Manager: </td><td>' + x[0][18] + '</td></tr>' + 
    '</table>'
  )
  .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  SpreadsheetApp.getUi()
       .showModalDialog(html, 'Cancel a Project');
}

这种方式是直接在gs中编写html。我想要做的是创建一个单独的html页面。这可以通过这种方法完成(并且我是如何在gs中的其他地方创建“添加项目”对话框):

function openCancelDialog(x) {
  var html = HtmlService.createHtmlOutputFromFile('Cancel').setSandboxMode(HtmlService.SandboxMode.IFRAME);
  SpreadsheetApp.getUi()
       .showModalDialog(html, 'Cancel a Project');
}

这将是Cancel.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
    </script>

    <script>
      <!-- Scripting to get my values? -->
    </script>

  </head>
  <body>
    <!-- Layout the window
         Add a Comments section
         Add a button to go back without cancel
         Add a button to submit the cancel and update -->
  </body>
</html>

但我还没想到的是如何将数组从openCancelDialog函数传递给html,所以它可以显示在页面上..

我怀疑我需要在Cancel.html文件中添加脚本以获取这些值。但有没有办法在创建它时将该数组发送到html?

3 个答案:

答案 0 :(得分:1)

这是另一种方法。我喜欢这样做,因为我有比模板更多的控制权。

这是我在处理电子表格中包含的电子邮件示例脚本时所执行的脚本。此脚本稍微复杂一点,因为它只是为用户提供了从电子邮件设置页面删除已发送电子邮件并将其存档到另一页面的选项。它通过动态创建html并将其作为字符串收集然后将其添加到另一个html页面来实现。我在脚本末尾启动html作为一个对话框,允许用户通过选中复选框并单击名为Archive Selected的按钮来选择要存档的电子邮件。我发现将javascript函数放在一个标准的html文件中然后先通过HtmlService运行并稍后附加字符串会更容易。

这是脚本:

function archiveSelectedEmails()
{
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sht=ss.getSheetByName('EmailSetup');
  var rng=sht.getDataRange();
  var rngA=rng.getValues();
  var s='<html><head><script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script></head><body>';
  var s='';
  for(var i=2;i<rngA.length;i++)
  {
    var dataA={};
    for(var j=0;j<rngA[1].length;j++)
    {
      dataA[rngA[1][j]]=rngA[i][j];
    }
    var row=Number(i+1);
    s+='<div id="row' + row + '"><input type="checkbox" name="email" value="' + Number(i+1) + '" />' + ' <strong>Row:</strong> ' + Number(i+1) + ' <strong>Name:</strong> ' + dataA.Name + ' <strong>Email:</strong> ' + dataA.Email + ' <strong>Subject:</strong> ' + dataA.Subject + ' <strong>DateSent:</strong> ' + Utilities.formatDate(new Date(dataA.DateSent), 'GMT-6', "M/dd/yyyy HH:mm:ss") + '</div>';
  }
  s+='<br /><input type="button" value="Exit" onClick="google.script.host.close();" /><input type="button" value="Archive Checked" onClick="getCheckedBoxes(\'email\');" />';

  var html=HtmlService.createHtmlOutputFromFile('htmlToBody').setWidth(800).setHeight(250);
  html.append(s);
  SpreadsheetApp.getUi().showModelessDialog(html, 'Select Emails to Archive');
}

这是html文件&#39; htmlToBody&#39;:

<!DOCTYPE html>
<html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
function getCheckedBoxes(chkboxName) {
  var checkboxes = document.getElementsByName(chkboxName);
  var rowsToArchive = [];
  for (var i=0; i<checkboxes.length; i++) 
  {
     if (checkboxes[i].checked) 
     {
        rowsToArchive.push(Number(checkboxes[i].value));
     }
  }
  google.script.run
    .withSuccessHandler(setResponse)
    .archiveSelectedRows(rowsToArchive);
}

function setResponse(a)
{
  var s='<br />Rows: ';
  for(var i=0;i<a.length;i++)
  {
    if(i>0)
    {
      s+=', ';
    }
    s+=a[i];
    var id='#row' + a[i]
    $(id).css('display','none');
  }
  s+='<br />Total: ' + a.length;
  google.script.run.displayMessage(s,'Archived Rows')
}
console.log('script here');
</script>
   </head>  
  <body>

我接受了你的项目想法并稍稍运行了。

这些是google脚本。你会注意到我开始使用你的功能名称。

    function openCancelDialog1()
{
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sht=ss.getSheetByName('Projects');
  var rng=sht.getDataRange();
  var rngA=rng.getValues();
  var s='';
  for(var i=1;i<rngA.length;i++)
  {
    var dataA={};
    for(var j=0;j<rngA[0].length;j++)
    {
      dataA[rngA[0][j]]=rngA[i][j];
    }
    var row=Number(i+1);
    s+='<div id="row' + row + '"><input type="checkbox" name="project" value="' + row + '" />' + ' <strong>Row:</strong> ' + Number(i+1) + ' <strong>Name:</strong> ' + dataA.Name + ' <strong>Project:</strong> ' + dataA.Description + '</div>';
  }
  s+='<br /><input type="button" value="Exit" onClick="google.script.host.close();" /><input type="button" value="Cancel and Archive Checked" onClick="getCheckedBoxes(\'project\');" />';
  var html=HtmlService.createHtmlOutputFromFile('htmlToBody').setWidth(800).setHeight(250);
  html.append(s);
  SpreadsheetApp.getUi().showModelessDialog(html, 'Select Project to Cancel');
}

function archiveSelectedRows(rows)
{
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sht=ss.getSheetByName('Projects');
  var dest=ss.getSheetByName('ArchivedProjects');
  var rng=sht.getDataRange();
  var rngA=rng.getValues();
  var deleted=[];
  for(var i=rngA.length-1;i>1;i--)
  {
    if(rows.indexOf(i+1)>-1)
    {
      deleted.push(Number(i+1));
      rngA[i][4]=Utilities.formatDate(new Date(), 'GMT-7', 'M/d/yyyy')
      dest.appendRow(rngA[i]);
      sht.deleteRow(i+1);
    }
  }
  var msg='Row Numbers Deleted = ' + deleted;
  var title='Rows Deleted';
  var timeout=10;
  return deleted;
}

function displayMessage(msg,title)
{
  msg+='<br /><input type="button" value="Exit" onClick="google.script.host.close()"; />';
  var html=HtmlService.createHtmlOutput(msg).setWidth(400).setHeight(300);
  SpreadsheetApp.getUi().showModelessDialog(html, title);
}

这是htmlTobody文件。对于这种情况,它已被修改了一点。

    <!DOCTYPE html>
<html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
function getCheckedBoxes(chkboxName) {
  var checkboxes = document.getElementsByName(chkboxName);
  var rowsToArchive = [];
  for (var i=0; i<checkboxes.length; i++) 
  {
     if (checkboxes[i].checked) 
     {
        rowsToArchive.push(Number(checkboxes[i].value));
     }
  }
  google.script.run
    .withSuccessHandler(setResponse)
    .archiveSelectedRows(rowsToArchive);
}

function setResponse(a)
{
  var s='<br />Row Numberss: ';
  for(var i=0;i<a.length;i++)
  {
    if(i>0)
    {
      s+=', ';
    }
    s+=a[i];
    var id='#row' + a[i]
    $(id).css('display','none');
  }
  s+='<br />Total: ' + a.length;
  google.script.run.displayMessage(s,'Canceled Rows')
}
console.log('script here');
</script>
   </head>  
  <body>

这就是我的&#39; Projects&#39;标签看起来像。我有一个Projects选项卡和一个ArchivedProjects选项卡。当我将项目归档时,它们会被复制到ArchivedProjects表中。

enter image description here

答案 1 :(得分:0)

使用HtmlService.createTemplateFromFile

function openCancelDialog(row)
{
  var ui = SpreadsheetApp.getUi();

  // get template
  var template = HtmlService.createTemplateFromFile('Cancel');

  // pass data to template
  template.data = {
    row: JSON.stringify(row)
  };

  // get output html
  var html = template.evaluate();

  // show modal window
  ui.showModalDialog(html, 'Cancel a Project');
}

Cancel.html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <script>
    var row = <?!=data.row?>;
    //document.write(row);
    </script>
  </body>
</html>

详细的模板文档:https://developers.google.com/apps-script/guides/html/templates

答案 2 :(得分:0)

科斯的回答给了我一些关于如何解决这个问题的想法。这一点,以及一些额外的阅读,特别是https://www.w3schools.com/js/js_json_intro.asp和后续章节,帮助我解决了这个问题。

新js代码:

function onEdit(e) {
  if(e.range.getColumn() == 9 && e.value == "Cancelled" && e.source.getActiveSheet().getName() == "Summary") {
    var cancelSheet = ss.getSheetByName(e.source.getActiveSheet().getName());
    var cancelRange = cancelSheet.getRange(e.range.getRow(), 1, 1, cancelSheet.getLastColumn());
    var cancelRow = cancelRange.getValues();

    //openCancelDialog(cancelRow);

    var aSheet = e.source.getActiveSheet().getName();
    var column = e.range.getColumn();
    var row = e.range.getRow();
    Logger.log("Col: " + column + "  Row: " + row + "  Sheet: " + aSheet);
    Logger.log(cancelRow);
  }
  Logger.log(e);
}

function openCancelDialog(row) {
  var ui = SpreadsheetApp.getUi();

  // get template
  var template = HtmlService.createTemplateFromFile('Cancel');

  var myJSON = JSON.stringify(row);

  // pass data to template
  template.data = myJSON;

  // get output html
  var html = template.evaluate();

  // show modal window
  ui.showModalDialog(html, 'Cancel a Project');
}

新HTML:

<!DOCTYPE html>
<html>
  <body>  
    <table>
      <tr><td>Number: </td><td id="number"></td></tr>
      <tr><td>Name: </td><td id="name"></td></tr>
      <tr><td>Category: </td><td id="category"></td></tr>
      <tr><td>Business Owner: </td><td id="owner"></td></tr>
      <tr><td>Project : </td><td id="manager"></td></tr>
    </table>

    <script>
      var objII = JSON.parse(<?=data?>);

      document.getElementById("number").innerHTML = objII[0][0];
      document.getElementById("name").innerHTML = objII[0][4];
      document.getElementById("category").innerHTML = objII[0][1];
      document.getElementById("owner").innerHTML = objII[0][17];
      document.getElementById("manager").innerHTML = objII[0][18];
    </script>

  </body>
</html>

我怀疑可能有更优雅的方法来做到这一点,甚至可能更多&#34;纠正&#34;方法。但这似乎适用于我需要它做的事情,所以我想我发布它以防其他人在看。

谢谢