如何在HTML中传递参数调用Google Apps Script的getItems函数?
问题描述
我在Google Docs中使用Google Apps Script,通过test3函数调用MultiSelect HTML侧边栏。已成功从传递的data中解析出role参数并能正常显示,但无法将该role参数传递给服务端的getItems(role)函数,尝试了role、$role等多种写法均失败,求解决方法。
Google Apps Script代码
function test3() { var role = "EventProducer"; var row = 2; var col = 3; var html = HtmlService.createHtmlOutputFromFile('MultiSelect') .setTitle('Select the Team Members for this Event') .setWidth(300); var data = { role: role, row: row, col: col }; var idData = "SelectMember_htmlservice"; var strAppend = "<div id='" + idData + "' style='display:none;'>" + Utilities.base64Encode(JSON.stringify(data)) + "</div>"; html.append(strAppend); DocumentApp.getUi().showSidebar(html); } function getItems(role) { var items = getDropdownOptions(role); return items; } function writeToPEO(selectedItems) { var sheet = DocumentApp.getActiveSpreadsheet().getActiveSheet(); var cell = sheet.getActiveCell(); cell.setValue(selectedItems.join(", ")); // Join array items with comma and space }
原始HTML代码
<!DOCTYPE html> <script> function getDataFromHtml(idData) { if (!idData) idData = "SelectMember_htmlservice"; var dataEncoded = document.getElementById(idData).innerHTML; var data = JSON.parse(atob(dataEncoded)); //alert("1=>"+data.role+" "+data.row+" "+data.col); return data; } function initialize() { var data = getDataFromHtml(); //alert("2=>"+data.role+" "+data.row+" "+data.col); document.getElementById('role').innerText = data.role; document.getElementById('row').innerText = data.row; document.getElementById('col').innerText = data.col; //alert("In initialize: "+'role'+"::"+'row'+'::'+'col'); } window.onload = initialize; </script> <html> <head> <base target="_top"> </head> <body> <H2 id="role"></H2> <H2 id="row"></H2> <H2 id="col"></H2> <div id="checkboxes"></div> <br> <button onclick="submit()">Submit}</button> <script> // Load items from the server-side function getItems google.script.run.withSuccessHandler(function(items) { var container = document.getElementById('checkboxes'); items.forEach(function(item) { var checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.id = item; checkbox.value = item; var label = document.createElement('label'); label.htmlFor = item; label.appendChild(document.createTextNode(item)); container.appendChild(checkbox); container.appendChild(label); container.appendChild(document.createElement('br')); }); }).getItems().'role';//<== This is where I want to pass the value contained in 'role' function submit() { var selectedItems = []; var checkboxes = document.getElementById('checkboxes').querySelectorAll('input[type=checkbox]:checked'); checkboxes.forEach(function(checkbox) { selectedItems.push(checkbox.value); }); // Write the selected items back to the document //google.script.run.writeToSheet(selectedItems); // Optionally close the sidebar google.script.host.close(); } </script> </body> </html>
解决方法
问题核心有两个:
- 调用
getItems的语法错误:.getItems().'role'完全不符合JavaScript语法 - 加载复选框的脚本执行时机不对:页面加载时直接执行该脚本,此时
initialize还没完成数据解析,拿不到role值
修改后的HTML代码
<!DOCTYPE html> <script> function getDataFromHtml(idData) { if (!idData) idData = "SelectMember_htmlservice"; var dataEncoded = document.getElementById(idData).innerHTML; var data = JSON.parse(atob(dataEncoded)); return data; } function initialize() { var data = getDataFromHtml(); // 显示传递过来的参数 document.getElementById('role').innerText = data.role; document.getElementById('row').innerText = data.row; document.getElementById('col').innerText = data.col; // 拿到role后再调用服务端函数 google.script.run.withSuccessHandler(function(items) { var container = document.getElementById('checkboxes'); items.forEach(function(item) { var checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.id = item; checkbox.value = item; var label = document.createElement('label'); label.htmlFor = item; label.appendChild(document.createTextNode(item)); container.appendChild(checkbox); container.appendChild(label); container.appendChild(document.createElement('br')); }); }).getItems(data.role); // 直接传入解析后的role参数 } window.onload = initialize; </script> <html> <head> <base target="_top"> </head> <body> <H2 id="role"></H2> <H2 id="row"></H2> <H2 id="col"></H2> <div id="checkboxes"></div> <br> <button onclick="submit()">Submit</button> <!-- 去掉多余的} --> <script> function submit() { var selectedItems = []; var checkboxes = document.getElementById('checkboxes').querySelectorAll('input[type=checkbox]:checked'); checkboxes.forEach(function(checkbox) { selectedItems.push(checkbox.value); }); // 调用服务端写入函数 google.script.run.writeToPEO(selectedItems); // 关闭侧边栏 google.script.host.close(); } </script> </body> </html>
关键修改点
- 将
google.script.run.getItems()的调用移到initialize函数内部,确保在获取到data.role之后再执行 - 直接用
.getItems(data.role)的方式传递参数,这是google.script.run调用带参服务端函数的标准写法 - 修复了Submit按钮文本里多余的
} - 取消了原来独立的加载复选框脚本,避免执行时机问题
内容的提问来源于stack exchange,提问作者Ira Kirschner
相关产品推荐
相关产品推荐

