将边栏中 html 表单的值传递给 google 脚本

Pass value from an html form in sidebar to google script

我在这方面遇到困难...我阅读了文档,但我无法做到。

我想在 Google 文档的边栏中创建一个小 html 表单。 此表单将从联系人中提取联系人组,以便用户可以选择一个并将 t 传递给我的脚本。

这是我所做的:

Page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" />
  </body>
</html>

menu.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Page')
      .evaluate();
}

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

}

function showSidebar() {

  var html = HtmlService.createHtmlOutputFromFile('Page')
      .setTitle('Chose the Contact Group')
      .setWidth(300);

  var groups = ContactsApp.getContactGroups();

  // add this to the html file Page.html
  html.append ('<form onsubmit="google.script.run.myFunction(formObject)">'+
               '<select>');

  for (var i = 0; i < groups.length; i++) {
    html.append('<option name="chosenGroup" value="' + groups[i].getName() + '">' + groups[i].getName() + '</option>');
  }

  html.append('</select><input type="submit">');

  //this is commented because I was testing it
  //html.append("<script>function handleFormSubmit(formObject) { google.script.run.myFunction(formObject); } </script>");

    DocumentApp.getUi() // Or DocumentApp or FormApp.
      .showSidebar(html);

}  

Code.gs

myFunction (formObject) {

Logger.log(formObject.chosenGroup);

}

当我点击提交按钮时,会打开一个新的空白页面,其中 url 如:

https://n-wuewuewuee98efgdsf98769s8d76f9s76df-0lu-script.googleusercontent.com/userCodeAppPanel?

这是因为 'form' 标签的 'action' 属性。当您提交表单时,浏览器将重定向到 'action' 属性中指定的路由。通常,此 URL 模式映射到服务器上接收表单发布的数据的代码。

您的代码中还有其他问题需要首先解决:

1) 仅当您将脚本部署为 Web 应用程序时才需要 doGet() 函数。当您在浏览器中打开该应用程序的 URL 时,doGet() 中的代码将执行,即向该应用程序发送 'GET' 请求。您的脚本是文档绑定的,因此不需要 doGet()

2) 业务逻辑的不同方面。 showSideBar() 必须准确地完成它应该做的事情,即显示边栏。 getContactGroups() 必须 return 联系人组数组等

3) 请记住,您可以将变量传递给 HTML 页面并使用模板 HTML 动态创建 UI。无需逐行追加! https://developers.google.com/apps-script/guides/html/templates

4) 最后,重定向到另一个页面可以使用jQuery轻松解决。

参见下面的示例代码。我的脚本是电子表格绑定的,因此您只需将 SpreadsheetApp 替换为 DocumentApp。

服务器代码(main.gs)

function onOpen(){

var ui = SpreadsheetApp.getUi();

ui.createMenu('Menu')
  .addItem('Show sidebar', 'showSidebar')
  .addToUi();


}


function showSidebar() {

var ui = SpreadsheetApp.getUi();
var template = HtmlService.createTemplateFromFile('sidebar');

template.contactGroups = getContactGroups(); //adding contactGroups as a property of the template object. 

ui.showSidebar(template.evaluate()); //Calling evaluate() executes the inline JS code in sidebar.html, populating the dropdown list


}

function getContactGroups(){

try {

var contactGroups = ContactsApp.getContactGroups();

} catch(error) {

Logger.log(error);

}

return contactGroups;

}

function processFormResponse(formObject){


Logger.log(formObject.chosenGroup);



}

这里是 sidebar.html。请注意 html 文件中内联代码的特殊语法。调用 e.preventDefault() 负责重定向到另一个页面。由于我们将 contactGroups 作为 属性 添加到模板对象,因此调用 evaluate() 时该变量将可用。下面的内联代码将使用组名称动态填充下拉列表。

<!DOCTYPE html>
    <html>
      <head>
        <base target="_top">
      </head>
      <body>
        Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" />

        <form>
        <select name="chosenGroup">

        <? for (var i=0; i < contactGroups.length; i++) { ?>

        <option value="<?= contactGroups[i].getName()?>"><?= contactGroups[i].getName()?></option>


        <?}?>
        </select>
        <input type="submit" value="Submit">
        </form>



       <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
       <script>

        $(document).ready(function(){

              $('form').submit(function(e){

                e.preventDefault();

                google.script.run.processFormResponse(this);


              });


        });

       </script>


      </body>
    </html>

更新

jQuery没什么特别的。它是一个 JS 库,旨在使 DOM 树的导航更容易一些,但它构建在浏览器中相同的 DOM API 之上。长话短说,您不需要 jQuery 即可获得此结果。 1) 为您的 'form' 标签分配一个唯一 ID,例如

<form id="form">

2) 创建一个函数,将事件侦听器添加到侦听 'submit' 事件的表单。第二个参数是事件处理函数。使用 'click' 而不是 'submit' 将强制您通过 id 引用文本字段并获取用户输入来手动创建表单对象。

   <script>
      function addEventListeners() {

       document.getElementById('form').addEventListener('submit', function(e){

       e.preventDefault();
       google.script.run.processFormResponse(this);


       });



       }
      </script>

最后,在加载时调用此函数。

<body onLoad="addEventListeners()">

我之前示例中的 jQuery 代码做了完全相同的事情,但可读性更高且更易于维护。