javascript - 需要帮助使用 Google Apps 脚本更新 HTML Web Apps 中的下拉菜单

标签 javascript html google-apps-script google-sheets

这是我第一次在这里发帖,所以如果我需要编辑任何内容,请告诉我。

我正在开发一个程序,该程序运行在 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 社区。

我相信问题不在 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/

相关文章:

google-apps-script - 使用 UrlFetchApp 从 https ://discord. com 寻址端点时出现错误 (403)

javascript - 从包含特定字符的字符串中获取单词。 (例如#或@,例如后期规划师)

javascript - 如何在Javascript中声明这种结构

javascript - 无法从angularjs ionic框架中的另一个 Controller 调用方法

javascript - Firefox onchange 不调用函数

javascript - 如何查看新人来自哪个邀请链接?

JavaScript html 画廊

html - 表中的图像不对齐,即使有 cellpadding ="0"

html - 如何更改搜索按钮文本颜色?

google-apps-script - 谷歌应用脚​​本: update cell to file name