问题
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)andinput/form.htmlas 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, whenaddNewItem(this)is run, this function is searched from the GAS project. By this, an error occurs likeUncaught 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,addNewItemof client side is run, and then,RecipeBuilder.addNewItemof the library side is run.
Note:
In your Javascript of library side,
google.script.run.addNewItem(this);andgoogle.script.host.close();are run in order. Butgoogle.script.runworks with the asynchronous process. So if the process ofaddNewItem(this)is slow, the dialog might be closed beforeaddNewItem(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 dialogboxTo
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