将边栏中 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 代码做了完全相同的事情,但可读性更高且更易于维护。
我在这方面遇到困难...我阅读了文档,但我无法做到。
我想在 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 代码做了完全相同的事情,但可读性更高且更易于维护。