将值从侧边栏中的html表单传递到google脚本

时间:2017-06-12 15:08:43

标签: google-apps-script google-docs

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

我想在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);

}

当我点击提交按钮时,会打开一个新的空白页面,其中包含以下网址:

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

1 个答案:

答案 0 :(得分:3)

That happens because of the 'action' attribute of the 'form' tag. When you submit a form, the browser is redirected to the route specified in the 'action' attribute. Usually, this URL pattern is mapped to the code on the server that receives data posted by the form.

There are other issues in your code that should be addressed first:

1) The doGet() function is needed only when you deploy the script as a web app. The code in doGet() executes when you open that app's URL in a browser, i.e. send a 'GET' request to the app. Your script is document-bound, so no need for doGet()

2) Separate aspects of your business logic. showSideBar() must do exactly what it's supposed to do, namely, show the sidebar. getContactGroups() must return the array of contact groups, etc.

3) Remember, you can pass variables to HTML pages and create UI dynamically using templated HTML. No need for appending line by line! https://developers.google.com/apps-script/guides/html/templates

4) Finally, the redirect to another page can be easily solved by using jQuery.

See sample code below. My script was spreadsheet-bound, so all you have to do is replace SpreadsheetApp with DocumentApp.

Server code (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);



}

And here's sidebar.html. Note the special syntax for inline code within html files. Calling e.preventDefault() takes care of the redirect to another page. Since we are adding contactGroups as a property to the template object, this variable will be available when evaluate() is called. The inline code below will dynamically populate the dropdown list with group names.

<!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>

UPDATE

There's nothing special about jQuery. It's a JS library designed to make navigating the DOM tree a bit easier, but it's built on top of the same DOM API in your browser. Long story short, you don't need jQuery to achieve this result. 1) Assign a unique id to your 'form' tag, e.g.

<form id="form">

2) Create a function that adds an event listener to the form that listens to the 'submit' event. The 2nd argument is the event handler function. Using 'click' instead of 'submit' will force you to create the form object manually by referencing text fields by id and getting user input.

   <script>
      function addEventListeners() {

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

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


       });



       }
      </script>

Finally, call this function on load.

<body onLoad="addEventListeners()">

The jQuery code in my previous example did exactly the same thing, but was much more readable and easy to maintain.