这是我第一次在这里发帖,所以如果我需要编辑任何内容,请告诉我。
我正在开发一个程序,该程序运行在 Google 表格中导入的数据,在 HTML Web 应用程序中显示一“行”数据,然后用户可以将帐号(在下拉列表中找到)分配给显示的项目,然后移至数据中的下一行。数据中的每一项都有一个ID号,根据这个ID号和数据的描述,用户在列表中选择合适的帐号来分配给数据。
问题是这些帐号有数百个,让用户滚动/搜索这些帐号以找到正确的帐户将非常乏味。
好消息是,只有某些帐户可以分配 ID 号。我可以有效地对下拉列表进行排序,以仅显示可以分配给当前 ID 的帐户,从而使用户的工作变得更加轻松快捷。
但是,我不知道在 html 页面上加载项目后如何更新下拉列表。我能够获取当前的 ID 号并对帐户进行排序,但我无法更新下拉列表。
我已经粘贴了 code.gs 和 html/javascript 代码。 我没有将所有代码包含在 code.gs 文件中,因为其中一些代码与我的问题无关。
我正在使用 Materialise CSS。
代码.gs:
var url = "hidden";
var ss = SpreadsheetApp.openByUrl(url);
var masterWS = ss.getSheetByName("Master List");
var items = [];
var Route = {};
Route.path = function (route, callback){
Route[route] = callback;
}
function doGet(e) {
Route.path("summary", summaryPage);
Route.path("edit", editPage);
if(Route[e.parameters.v]){
return Route[e.parameters.v]();
} else {
return editPage();
}
}
function summaryPage(){
var tmp = HtmlService.createTemplateFromFile("summary");
var sumList = showSummary();
tmp.summaryList = sumList;
return tmp.evaluate();
}
function include(fileName){
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
function editPage(){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("GLAccounts");
// Create drop down and populate with all account options
var SSassetList = ws.getRange(2,1, getLastRowSpecial("A", "GLAccounts"),1).getValues();
var htmlAssetList = SSassetList.map(function (r){return '<option>' + r[0] + '</option>';}).join('');
var tmp = HtmlService.createTemplateFromFile("page");
tmp.assetList = htmlAssetList;
return tmp.evaluate();
}
function calculateTotalEntries(){
//Logger.log("Done: " + done);
var lastRow = masterWS.getLastRow();
var totalEntries = 0;
var i = lastRow;
while (masterWS.getRange(i, 1).getValue() != "Transaction Date"){
i--;
totalEntries++;
}
masterWS.getRange("R1").setValue(totalEntries);
masterWS.getRange("R2").setValue(lastRow);
}
function userClicked(userInfo){
var r = masterWS.getRange("P1").getValue();
var GLAccount = userInfo.act;
var lastRow = masterWS.getRange("R2").getValue();
var totalEntries = masterWS.getRange("R1").getValue();
if(!(masterWS.getRange("P3").getValue())){
//Logger.log("Done parsing. Items length: " + items.length);
if(r <= totalEntries - 1 ){
masterWS.getRange("P4").setValue(lastRow - totalEntries + 1 + r);
if(masterWS.getRange("P1").getValue() != 0){
masterWS.getRange(lastRow - totalEntries + r, 8).setValue(GLAccount);
}
r = r + 1;
masterWS.getRange("P1").setValue(r);
} else {
//Logger.log("Last one");
masterWS.getRange("P3").setValue(true);
masterWS.getRange(lastRow, 8).setValue(GLAccount);
//return Error;
resetCounters();
calculateChange();
}
}
}
function showItem(){
var row = masterWS.getRange("P4").getValue();
return "Item: " + masterWS.getRange(row,5).getValue() + "; Date: " + slice(masterWS.getRange(row,1).getValue(), 13) + "; ID: "+ masterWS.getRange(row,6).getValue();
}
function getData(){
var row = masterWS.getRange("P4").getValue();
var id = "";
id = masterWS.getRange(row,6).getValue().toString();
var availAccounts = [];
var IDSheet = ss.getSheetByName("MerchantCodes");
var lastIDRow = IDSheet.getLastRow();
var lastIDCol = 0;
var currentRow = 0;
for(var i = 6; i < lastIDRow; i++){
if(IDSheet.getRange(i, 1).getValue().toString() == id){
currentRow = i;
break;
}
}
//Logger.log("ID: " + id + " @ row " + i);
for( var j = 1; j < 10; j++){
if(IDSheet.getRange(currentRow,j).getValue() != ""){
lastIDCol = j;
}
}
//Logger.log("Last Column for row " + i + ": " + lastIDCol);
for(var r = lastIDCol - (lastIDCol - 3) + 1; r < lastIDCol+1; r++){
//Logger.log("Account: " + IDSheet.getRange(currentRow,r).getValue());
availAccounts.push(IDSheet.getRange(currentRow,r).getValue());
}
return availAccounts;
}
function resetCounters(){
masterWS.getRange("P1").setValue(0);
masterWS.getRange("P3").setValue(false);
masterWS.getRange("P4").setValue("");
masterWS.getRange("P5").setValue("");
masterWS.getRange("P6").setValue("");
}
function getLastRowSpecial(col, sheetName){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName(sheetName);
var data = ws.getRange(col + "2:" + col).getValues();
var lastRowData = data.filter(String).length;
return lastRowData;
}
}
HTML:
Web 应用程序中显示的项目(根据数据而变化)位于标签中。 下拉列表是使用标签填充的。这些标签中的数据来自 code.gs 文件中的 doGet() 和 editPage() 函数。
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<?!= include("page-css"); ?>
</head>
<body>
<div class = "container"> <!-- Open container -->
<div> <!-- Open row -->
<label>Item</label>
<p><span id="current"></span></p>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<button id="btn2" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Start</button>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<div class="input-field col s6">
<select id="glAcc">
<option disabled selected>Choose your GL Account</option>
<?!= assetList; ?>
</select>
<label>GL Account</label>
</div>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<button id="updDrop" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Update Dropdown
<i class="material-icons right">send</i>
</button>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<button id="btn" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<a href="<?= ScriptApp.getService().getUrl(); ?>?v=summary" id="summary" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Go to Summary Page
<i class="material-icons right">arrow_forward</i>
</a>
</div> <!-- Close row -->
</div> <!-- Close container -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<?!= include("page-js"); ?>
</body>
</html>
HTML JS 代码:
<script>
document.addEventListener('DOMContentLoaded', function(){
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
document.addEventListener('DOMContentLoaded', reset);
document.getElementById("btn").addEventListener("click",doStuff);
document.getElementById("btn2").addEventListener("click",doStuff);
document.getElementById("sumBtn").addEventListener("click", summary);
document.getElementById("updDrop").addEventListener("click", updateDropdown);
function doStuff(){
var userInfo = {};
userInfo.act = document.getElementById("glAcc").value;
google.script.run.withSuccessHandler(findItem).userClicked(userInfo);
//findItem();
//google.script.run.getLength();
// Reset dropdown
var myApp = document.getElementById("glAcc");
myApp.selectedIndex = 0;
M.FormSelect.init(myApp);
}
function reset(){
google.script.run.resetCounters();
google.script.run.calculateTotalEntries();
document.getElementById("current").textContent = "Click the Start Button";
}
function updateDropdown(){
google.script.run.withSuccessHandler(updateSelect).getData();
}
function updateSelect(vA){
var select = document.getElementById("glAcc");
select.options.length = 0;
vA.unshift("");
for(var i = 1; i < vA.length; i++){
select.options[i] = new Option(vA[i], vA[i]);
}
}
function findItem(){
google.script.run.withSuccessHandler(changeItem).showItem();
}
function changeItem(item){
document.getElementById("current").textContent = item;
//document.getElementById("options"). = "<option>1</option><option>2</option>";
}
function summary(){
google.script.run.withSuccessHandler(findSummary).calculateChange();
}
function findSummary(){
google.script.run.withSuccessHandler(changeSummary).showSummary();
}
function changeSummary(summary){
document.getElementById("sumText").textContent = summary;
}
</script>
总的来说,我希望下拉选项随着显示的项目的更新而更新。如果无法同时更新,我可以添加一个按钮,单击后将更新下拉列表。
我不想与所有人分享整个代码/电子表格,但如果您想访问,请给我留言,我可以分享给您。
谢谢。
最佳答案
欢迎来到 SO 社区。p>
我相信问题不在 Apps 脚本中。
当您使用 Materialise Select 时,您需要重新初始化它。
这是我在代码库中找到的函数,它应该对您有帮助:
function fillMaterializeSelect(elSelect, data) {
elSelect.options.length = 0;
for (let i = 0; i < data.length; i++) {
const dataElement = data[i];
const option = document.createElement("option");
option.value = dataElement.value;
option.text = dataElement.text;
elSelect.add(option);
}
M.FormSelect.init(elSelect);
}
关于javascript - 需要帮助使用 Google Apps 脚本更新 HTML Web Apps 中的下拉菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65757035/