HTML (Metro 4) 和 Google 工作表,异步加载数据
HTML (Metro 4) and Google Sheets, Loading Data Asynchronously
自 10 月以来,我一直在尝试将一组项目加载到 select 中。我可以在模板中使用同步编码来完成,但不能使用异步编码(Explanation). I have watched videos, read Whosebug after , read google documentation, metro documentation,只是想不通。这是一个带有 .gs 的 google 应用程序脚本项目文件后端和一个应该用于加载边栏的 .html 文件。
我有这个HTML
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- Metro 4 -->
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">
</head>
<body>
<!-- Title -->
<h2 style="text-align: center;">Add New Job</h2>
<!-- Job Name -->
<p style="text-align: center;"><span class='mif-chat-bubble-outline'></span> Job Name</p>
<input type="text" data-role="input" data-prepend="Name: ">
<!-- Creator Name -->
<p style="text-align: center;"><span class='mif-user-check'></span> Job Creator</p>
<select data-role="select" id="mySelectList">
<optgroup label="Employees">
<option value="" selected> Loading... </option>
</optgroup>
</select>
<nl></nl>
<p style="text-align: center;">
<button class="button success cycle " id="confirmButton"><span class="mif-checkmark"></span></button>
</p>
<!-- Metro 4 -->
<script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
<script>
$(function() {
$('#txt1').val('');
console.log("Running updateSelect");
google.script.run
.withSuccessHandler(updateSelect)
.getEmployeeNames();
});
function updateSelect(vA)//array of value that go into the select
{
var select = document.getElementById("mySelectList");
select.options.length = 0;
for (var i=0; i<vA.length;i++){
console.log("Creating items %s, %s", vA[i], vA[i]);
select.options[i] = new Option(vA[i],vA[i]);
console.log ("select.options[i] = %s, select.options = %s.", select.options[i], select.options);
}
}
console.log("My Code Ran");
</script>
</body>
</html>
在 运行 时提供此控制台反馈。
Console Feedback
我已经删除了所有 cookie 和缓存,禁用了所有插件等,但并没有解决问题。
为什么选项不会从“正在加载...”更改为我输入的实际新值?作为参考,我有以下代码确实有效,但它以低效的方式执行(在模板本身内部,而不是被调用)。
<!-- Creator Name -->
<? var employees = getEmployeeNames(); ?>
<p style="text-align: center;"><span class='mif-user-check'></span> Job Creator</p>
<select data-role="select" id="jobCreator">
<optgroup label="Employees">
<? for (var i = 0; i < employees.length; i++){ ?>
<option> <?= employees[i] ?></option>
<? } ?>
</optgroup>
</select>
这是 getEmployeeNames() 的后端脚本。我试过它返回一维或二维数组。虽然该函数给出了预期的输出,但 HTML select 仍然没有更新新选项。
function getEmployeeNames(){
var employeeSheet = SpreadsheetApp.getActive().getSheetByName('Dropdown Lists');
var names = employeeSheet.getRange(5, 4, employeeSheet.getLastRow(), 1).getValues();
names = removeBlankEntries(names);
Logger.log ('Employee Names "%s"', names);
return names;
}
function removeBlankEntries(arr){
var output = [];
arr.forEach(function(value){
if (value != "" & value != " "){
output.push(value[0]) // add [0] to make it 1d
};
});
return output;
}
这是一个示例 Logger.log 输出。
8:27:00 AM Info Employee Names "[PM, Employee 2, Employee 3, Employee 4]"
或者设置为二维数组。
8:28:00 AM Info Employee Names "[[PM], [Employee 2], [Employee 3], [Employee 4]]"
另外,下面是侧边栏在代码中的加载方式。
function loadNewJobSidebar(){
var htmlTemplate = HtmlService
.createTemplateFromFile("addJob");
var htmlOutput = htmlTemplate.evaluate()
.setTitle('Add New Job');
var ui = SpreadsheetApp.getUi();
ui.showSidebar(htmlOutput);
}
任何指导都会有所帮助。我觉得上面那个视频最好看,复制了三四次都没有成功。我已经编码十年了——尽管这只是我的副业——而且我在过去这么多个月里从来没有遇到过问题。
== 抱歉,这变成了一个怪物线程。以下是复制的具体步骤 ==
- 新建空白Google Sheet.
- 打开脚本编辑器并创建一个名为 addJob 的 HTML 文件(它会自动将 .html 添加到末尾)
- 在 HTML 文件中,准确复制此 post 中标题为“我有此 HTML”的第一个片段中的代码
- 在code.gs文件中,复制以下代码
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Manage Sheet')
.addSubMenu (ui.createMenu('Jobs')
.addItem('Add New Job', 'loadNewJobSidebar'))
.addToUi();
}
function getEmployeeNames(){
return ["Bob", "Jamie", "Ted"];
}
function loadNewJobSidebar(){
var htmlTemplate = HtmlService
.createTemplateFromFile("addJob");
var htmlOutput = htmlTemplate.evaluate()
.setTitle('Add New Job');
var ui = SpreadsheetApp.getUi();
ui.showSidebar(htmlOutput);
}
- 运行 脚本编辑器中的 onOpen() 函数。允许它访问 运行.
- 返回电子表格,在自定义菜单上,select“管理 Sheet -> 工作 -> 添加新工作”
- 边栏将加载并显示“正在加载”,但不会使用 getEmployee() 函数中的名称。
- 按 F12 并注意显示 select 选项的控制台日志语句应该被加载。
根据你更新的问题,我可以理解你当前的问题。对于您的脚本,如何修改函数 updateSelect
如下?
修改后的脚本:
function updateSelect(vA) {
var select = Metro.getPlugin("#mySelectList", 'select');
select.data(Object.fromEntries(vA.map(e => [e, e])));
}
- 在这个修改中,假设
vA
的值为一维数组。请注意这一点。
参考:
自 10 月以来,我一直在尝试将一组项目加载到 select 中。我可以在模板中使用同步编码来完成,但不能使用异步编码(Explanation). I have watched videos, read Whosebug
我有这个HTML
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- Metro 4 -->
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">
</head>
<body>
<!-- Title -->
<h2 style="text-align: center;">Add New Job</h2>
<!-- Job Name -->
<p style="text-align: center;"><span class='mif-chat-bubble-outline'></span> Job Name</p>
<input type="text" data-role="input" data-prepend="Name: ">
<!-- Creator Name -->
<p style="text-align: center;"><span class='mif-user-check'></span> Job Creator</p>
<select data-role="select" id="mySelectList">
<optgroup label="Employees">
<option value="" selected> Loading... </option>
</optgroup>
</select>
<nl></nl>
<p style="text-align: center;">
<button class="button success cycle " id="confirmButton"><span class="mif-checkmark"></span></button>
</p>
<!-- Metro 4 -->
<script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
<script>
$(function() {
$('#txt1').val('');
console.log("Running updateSelect");
google.script.run
.withSuccessHandler(updateSelect)
.getEmployeeNames();
});
function updateSelect(vA)//array of value that go into the select
{
var select = document.getElementById("mySelectList");
select.options.length = 0;
for (var i=0; i<vA.length;i++){
console.log("Creating items %s, %s", vA[i], vA[i]);
select.options[i] = new Option(vA[i],vA[i]);
console.log ("select.options[i] = %s, select.options = %s.", select.options[i], select.options);
}
}
console.log("My Code Ran");
</script>
</body>
</html>
在 运行 时提供此控制台反馈。
Console Feedback
我已经删除了所有 cookie 和缓存,禁用了所有插件等,但并没有解决问题。
为什么选项不会从“正在加载...”更改为我输入的实际新值?作为参考,我有以下代码确实有效,但它以低效的方式执行(在模板本身内部,而不是被调用)。
<!-- Creator Name -->
<? var employees = getEmployeeNames(); ?>
<p style="text-align: center;"><span class='mif-user-check'></span> Job Creator</p>
<select data-role="select" id="jobCreator">
<optgroup label="Employees">
<? for (var i = 0; i < employees.length; i++){ ?>
<option> <?= employees[i] ?></option>
<? } ?>
</optgroup>
</select>
这是 getEmployeeNames() 的后端脚本。我试过它返回一维或二维数组。虽然该函数给出了预期的输出,但 HTML select 仍然没有更新新选项。
function getEmployeeNames(){
var employeeSheet = SpreadsheetApp.getActive().getSheetByName('Dropdown Lists');
var names = employeeSheet.getRange(5, 4, employeeSheet.getLastRow(), 1).getValues();
names = removeBlankEntries(names);
Logger.log ('Employee Names "%s"', names);
return names;
}
function removeBlankEntries(arr){
var output = [];
arr.forEach(function(value){
if (value != "" & value != " "){
output.push(value[0]) // add [0] to make it 1d
};
});
return output;
}
这是一个示例 Logger.log 输出。
8:27:00 AM Info Employee Names "[PM, Employee 2, Employee 3, Employee 4]"
或者设置为二维数组。
8:28:00 AM Info Employee Names "[[PM], [Employee 2], [Employee 3], [Employee 4]]"
另外,下面是侧边栏在代码中的加载方式。
function loadNewJobSidebar(){
var htmlTemplate = HtmlService
.createTemplateFromFile("addJob");
var htmlOutput = htmlTemplate.evaluate()
.setTitle('Add New Job');
var ui = SpreadsheetApp.getUi();
ui.showSidebar(htmlOutput);
}
任何指导都会有所帮助。我觉得上面那个视频最好看,复制了三四次都没有成功。我已经编码十年了——尽管这只是我的副业——而且我在过去这么多个月里从来没有遇到过问题。
== 抱歉,这变成了一个怪物线程。以下是复制的具体步骤 ==
- 新建空白Google Sheet.
- 打开脚本编辑器并创建一个名为 addJob 的 HTML 文件(它会自动将 .html 添加到末尾)
- 在 HTML 文件中,准确复制此 post 中标题为“我有此 HTML”的第一个片段中的代码
- 在code.gs文件中,复制以下代码
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Manage Sheet')
.addSubMenu (ui.createMenu('Jobs')
.addItem('Add New Job', 'loadNewJobSidebar'))
.addToUi();
}
function getEmployeeNames(){
return ["Bob", "Jamie", "Ted"];
}
function loadNewJobSidebar(){
var htmlTemplate = HtmlService
.createTemplateFromFile("addJob");
var htmlOutput = htmlTemplate.evaluate()
.setTitle('Add New Job');
var ui = SpreadsheetApp.getUi();
ui.showSidebar(htmlOutput);
}
- 运行 脚本编辑器中的 onOpen() 函数。允许它访问 运行.
- 返回电子表格,在自定义菜单上,select“管理 Sheet -> 工作 -> 添加新工作”
- 边栏将加载并显示“正在加载”,但不会使用 getEmployee() 函数中的名称。
- 按 F12 并注意显示 select 选项的控制台日志语句应该被加载。
根据你更新的问题,我可以理解你当前的问题。对于您的脚本,如何修改函数 updateSelect
如下?
修改后的脚本:
function updateSelect(vA) {
var select = Metro.getPlugin("#mySelectList", 'select');
select.data(Object.fromEntries(vA.map(e => [e, e])));
}
- 在这个修改中,假设
vA
的值为一维数组。请注意这一点。