无法使用 Google Apps 脚本在 Google 表格的菜单上加载 HTML 对话框文件
Unable to load HTML file of a Dialog on menu of Google Sheets with Google Apps Script
我无法将名为 addSupermarket.html
的 HTML 文件加载到弹出的对话框中。这个想法是 main.html 包含弹出对话框的 HTML 有标签。并且选项卡不会切换,也不会为选项卡加载相应的 html 文件。
此文件名为 loadForm.gs
并加载菜单。
function loadMainForm() {
const htmlServ = HtmlService.createTemplateFromFile("main");
const html = htmlServ.evaluate();
const ui = SpreadsheetApp.getUi();
html.setWidth(850).setHeight(600);
ui.showModalDialog(html, "Add Supermarket");
}
function createMenu() {
SpreadsheetApp.getUi().createMenu("Utilities")
.addItem("Add new Supermarket", "loadMainForm")
.addToUi();
}
function onOpen() {
createMenu();
}
这就是 main.html
的样子。这是对话框的实际 HTML,但我想将选项卡 addSupermarkets.html
的 HTML 加载到名为 Add Supermarket 的选项卡中。
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Hello, world!</title>
<style>
.nav-link {
cursor:pointer;
}
</style>
</head>
<body>
<ul class="nav nav-tabs">
<li class="nav-item">
<div class="nav-link active" id="search-link">Search</a>
</li>
<li class="nav-item">
<div class="nav-link" id="add-supermarket-link">Add Supermarket</a>
</li>
</ul>
<div class="container">
<div id="app"></div>
</div>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<script>
function loadAddSupermarketView() {
google.script.run.withSuccessHandler(function(html) {
document.getElementById("app").innerHTML = html;
}).loadAddSupermarketView();
}
document.getElementById("add-supermarket-link").addEventListener("click", loadAddSupermarketView);
</script>
</body>
</html>
addsupermarket.html
现在看起来像这样,只是有一个 H1 文本作为占位符。
<h1Add Supermarket</h1>
这是loadAddSupermarket.gs
function loadPartialHTML_(partial) {
const htmlServ = HtmlService.createTemplateFromFile(partial);
return htmlServ.evaluate.getContent();
}
function loadAddSupermarketView() {
return loadPartialHTML_("addSupermarket");
}
这是显示的对话框。
我哪里做错了?为什么我不能将 HTML 加载到文件中?
我尝试复制您的代码并发现了一些问题:
loadForm.html
和 loadAddSupermarket.html
的文件扩展名不正确,文件包含 Apps 脚本方法,您应该改用 .gs
文件扩展名
- 您的 HTML 文件中有不必要的导入。
nav-bar
操作不需要 Popper.js,它需要 JQuery 并且 JQuery 未导入您的 HTML,这导致其他选项卡无法点击。
- 在您的
loadAddSupermarket.gs
文件中,addSupermarket 与文件列表中的任何文件都不匹配。 Apps 脚本在文件名方面区分大小写。将 addsupermarket.html
重命名为 addSupermarket.html
- 在
loadPartialHTML_(partial)
函数的htmlServ.evaluate.getContent();
中。这将产生错误,因为脚本在 HtmlTemplate 中找不到 evaluate
属性。我想你错过了在它旁边添加 ()
。
<li>
下的项目以 <div>
开头但以 </a>
结尾。你应该改用。
在这里,我重构了您的代码,并且能够为“添加超市”选项卡获得正确的输出。
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<ul class="nav nav-tabs">
<li class="nav-link active"><a data-toggle="tab" href="#search" id="search-link">Search</a></li>
<li class="nav-link"><a data-toggle="tab" href="#addsupermarket" id="add-supermarket-link">Add Supermarket</a></li>
</ul>
<div class="tab-content">
<div id="search" class="tab-pane fade in active"></div>
<div id="addsupermarket" class="tab-pane fade"></div>
</div>
<script>
function loadAddSupermarketView() {
google.script.run.withSuccessHandler(function(html) {
document.getElementById("addsupermarket").innerHTML = html;
}).loadAddSupermarketView();
}
document.getElementById("add-supermarket-link").addEventListener("click", loadAddSupermarketView);
</script>
</body>
</html>
addSupermarket.html
<h1>Add Supermarket</h1>
loadform.gs
function loadMainForm() {
const htmlServ = HtmlService.createTemplateFromFile("main");
const html = htmlServ.evaluate();
const ui = SpreadsheetApp.getUi();
html.setWidth(850).setHeight(600);
ui.showModalDialog(html, "Add Supermarket");
}
function createMenu() {
SpreadsheetApp.getUi().createMenu("Utilities")
.addItem("Add new Supermarket", "loadMainForm")
.addToUi();
}
function onOpen() {
createMenu();
}
loadAddSupermarket.gs
function loadPartialHTML_(partial) {
const htmlServ = HtmlService.createTemplateFromFile(partial);
return htmlServ.evaluate().getContent();
}
function loadAddSupermarketView() {
return loadPartialHTML_("addSupermarket");
}
输出:
参考文献:
我无法将名为 addSupermarket.html
的 HTML 文件加载到弹出的对话框中。这个想法是 main.html 包含弹出对话框的 HTML 有标签。并且选项卡不会切换,也不会为选项卡加载相应的 html 文件。
此文件名为 loadForm.gs
并加载菜单。
function loadMainForm() {
const htmlServ = HtmlService.createTemplateFromFile("main");
const html = htmlServ.evaluate();
const ui = SpreadsheetApp.getUi();
html.setWidth(850).setHeight(600);
ui.showModalDialog(html, "Add Supermarket");
}
function createMenu() {
SpreadsheetApp.getUi().createMenu("Utilities")
.addItem("Add new Supermarket", "loadMainForm")
.addToUi();
}
function onOpen() {
createMenu();
}
这就是 main.html
的样子。这是对话框的实际 HTML,但我想将选项卡 addSupermarkets.html
的 HTML 加载到名为 Add Supermarket 的选项卡中。
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Hello, world!</title>
<style>
.nav-link {
cursor:pointer;
}
</style>
</head>
<body>
<ul class="nav nav-tabs">
<li class="nav-item">
<div class="nav-link active" id="search-link">Search</a>
</li>
<li class="nav-item">
<div class="nav-link" id="add-supermarket-link">Add Supermarket</a>
</li>
</ul>
<div class="container">
<div id="app"></div>
</div>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<script>
function loadAddSupermarketView() {
google.script.run.withSuccessHandler(function(html) {
document.getElementById("app").innerHTML = html;
}).loadAddSupermarketView();
}
document.getElementById("add-supermarket-link").addEventListener("click", loadAddSupermarketView);
</script>
</body>
</html>
addsupermarket.html
现在看起来像这样,只是有一个 H1 文本作为占位符。
<h1Add Supermarket</h1>
这是loadAddSupermarket.gs
function loadPartialHTML_(partial) {
const htmlServ = HtmlService.createTemplateFromFile(partial);
return htmlServ.evaluate.getContent();
}
function loadAddSupermarketView() {
return loadPartialHTML_("addSupermarket");
}
这是显示的对话框。
我哪里做错了?为什么我不能将 HTML 加载到文件中?
我尝试复制您的代码并发现了一些问题:
loadForm.html
和loadAddSupermarket.html
的文件扩展名不正确,文件包含 Apps 脚本方法,您应该改用.gs
文件扩展名- 您的 HTML 文件中有不必要的导入。
nav-bar
操作不需要 Popper.js,它需要 JQuery 并且 JQuery 未导入您的 HTML,这导致其他选项卡无法点击。 - 在您的
loadAddSupermarket.gs
文件中,addSupermarket 与文件列表中的任何文件都不匹配。 Apps 脚本在文件名方面区分大小写。将addsupermarket.html
重命名为addSupermarket.html
- 在
loadPartialHTML_(partial)
函数的htmlServ.evaluate.getContent();
中。这将产生错误,因为脚本在 HtmlTemplate 中找不到evaluate
属性。我想你错过了在它旁边添加()
。 <li>
下的项目以<div>
开头但以</a>
结尾。你应该改用。
在这里,我重构了您的代码,并且能够为“添加超市”选项卡获得正确的输出。
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<ul class="nav nav-tabs">
<li class="nav-link active"><a data-toggle="tab" href="#search" id="search-link">Search</a></li>
<li class="nav-link"><a data-toggle="tab" href="#addsupermarket" id="add-supermarket-link">Add Supermarket</a></li>
</ul>
<div class="tab-content">
<div id="search" class="tab-pane fade in active"></div>
<div id="addsupermarket" class="tab-pane fade"></div>
</div>
<script>
function loadAddSupermarketView() {
google.script.run.withSuccessHandler(function(html) {
document.getElementById("addsupermarket").innerHTML = html;
}).loadAddSupermarketView();
}
document.getElementById("add-supermarket-link").addEventListener("click", loadAddSupermarketView);
</script>
</body>
</html>
addSupermarket.html
<h1>Add Supermarket</h1>
loadform.gs
function loadMainForm() {
const htmlServ = HtmlService.createTemplateFromFile("main");
const html = htmlServ.evaluate();
const ui = SpreadsheetApp.getUi();
html.setWidth(850).setHeight(600);
ui.showModalDialog(html, "Add Supermarket");
}
function createMenu() {
SpreadsheetApp.getUi().createMenu("Utilities")
.addItem("Add new Supermarket", "loadMainForm")
.addToUi();
}
function onOpen() {
createMenu();
}
loadAddSupermarket.gs
function loadPartialHTML_(partial) {
const htmlServ = HtmlService.createTemplateFromFile(partial);
return htmlServ.evaluate().getContent();
}
function loadAddSupermarketView() {
return loadPartialHTML_("addSupermarket");
}
输出: