How to run HTML from google library?

試著忘記壹切 提交于 2020-05-17 06:26:33

问题


I have a Google Library with HTML form, process form script addNewItemand script to run the form in popup window addItem.

function addItem()
{
  var html = HtmlService.createHtmlOutputFromFile('input/form.html');
  SpreadsheetApp.getUi() 
      .showModalDialog(html, 'Add New Recipe');
  
}

function addNewItem(form_data)
{
  var url = "SPREADSHEET_URL_TO_DATA_COLLECTION";
  var ss = SpreadsheetApp.openByUrl(url);
  var sheet = ss.getSheetByName('List');  
  var asiaTime = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd");
  
  var dishName = form_data.dish_name;
  var cuisineName = form_data.cuisine_name;
  var placeName = form_data.place_name;
  var categoryName = form_data.category_name;
  var num = sheet.getRange(sheet.getLastRow(), 1).getValue() + 1 || sheet.getLastRow();
    
  sheet.appendRow([num, dishName, cuisineName, placeName, categoryName, asiaTime]);
}
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
  </head>
  <body>
    <form id="myform">
    <div class="block form-group">
    <label for="dish_name">Dish name</label>
    <input type='text' name='dish_name' id="dish_name" required="required"/>
    </div>
   
    <div class="block form-group">
    <label for="place_name">Place</label>
        <select id="place_name" name="place_name" type="text" required>
       
             <option value="LL4H">LL4H</option>
             <option value="LL4T">LL4T</option>              
        </select>
    </div>
    
    <div class="block form-group">
    <label for="cuisine_name">Cuisine</label>
        <select id="cuisine_name" name="cuisine_name" type="text" required>
       
             <option value="Asian">Asian</option>
             <option value="Western">Western</option>              
        </select>
    </div>
    
    <div class="block form-group">
    <label for="category_name">Category</label>
        <input id="category_name" name="category_name" type="text" list="quote-choices" required>
        <datalist id="quote-choices">
             <option value="Starter">Starter</option>
             <option value="Main course">Main course</option> 
             <option value="Veggi side">Veggi side</option>
             <option value="Carbs side">Carbs side</option>
             <option value="Dessert">Dessert</option>
             <option value="Dough">Dough</option>
             <option value="Sauce">Sauce</option>
             <option value="Drink">Drink</option>
             <option value="Other">Other</option>
        </datalist>
    </div>
    <div class="block">
    <button type="submit" class="action">Submit</button>
    </div>
    </form>
    <script>
      document.querySelector("#myform").addEventListener("submit", 
      function(e)
      {
      e.preventDefault();    //stop form from submitting
      console.log(this)
      google.script.run.withSuccessHandler(()=> google.script.host.close()).addNewItem(this);
      }
      );
    </script>
  </body>
</html>

I connected this Library with the Google Spreadsheet and declared new function to run library script to open the form.

function createRecipe() {
  RecipeBuilder.addItem();
}

function addNewItem(form_data) {
  RecipeBuilder.addNewItem(form_data);
}

Form appears in popup window well.

I click Submit to submit my data from the form, but serverside process does not start.

How to run this form correct? Where I'm wrong? How to fix it?


UPDATED

It's still does not work with library but works well if I put it in bound-container script of some spreadsheet. Unfortunately, I can't use it in bound-container because full code of addNewItem(form_data) function must replicate current spreadsheet. Finally it will be 1000+ Google Spreadsheets with same numbers of bound-containers. It will be super complicated to update it



回答1:


I believe your goal and situation as follows.

  • You want to use addItem(), addNewItem(form_data) and input/form.html as a GAS library.
  • When you call this library from the client side, when the submit button is clicked, the data is not sent.
    • You want to remove this issue.
  • The library name is RecipeBuilder.

For this, how about this modification?

Modification points:

  • I think that the reason of your issue is google.script.run.addNewItem(this);. In this case, when addNewItem(this) is run, this function is searched from the GAS project. By this, an error occurs like Uncaught TypeError: google.script.run.addNewItem is not a function. I think that this is the reason of your issue.

In order to remove this issue, how about the following modification? In this modification, one more function is added to the client side.

Modified script:

function createRecipe() {
  RecipeBuilder.addItem();
}

// Added
function addNewItem(form_data) {
  RecipeBuilder.addNewItem(form_data);
}
  • By this, when google.script.run.addNewItem(this); is run at the library side, addNewItem of client side is run, and then, RecipeBuilder.addNewItem of the library side is run.

Note:

  • In your Javascript of library side, google.script.run.addNewItem(this); and google.script.host.close(); are run in order. But google.script.run works with the asynchronous process. So if the process of addNewItem(this) is slow, the dialog might be closed before addNewItem(this) is run. So I think that the following modification might be also used.

    • From

      google.script.run.addNewItem(this);
      google.script.host.close();//close this dialogbox
      
    • To

      google.script.run.withSuccessHandler(()=> google.script.host.close()).addNewItem(this);
      

Reference:

  • Class google.script.run



回答2:


I recommend you put your scripts into:

document.addEventListener('DOMContentLoaded', event => {
    // your code here
});


来源:https://stackoverflow.com/questions/61566169/how-to-run-html-from-google-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!