簡體   English   中英

Javascript & HTML - 傳遞下拉索引值作為對象屬性返回未定義

[英]Javascript & HTML - Passing dropdown index value as object property returns undefined

我是這種語言的新手,但遇到了障礙。 我已經針對這個特定問題搜索了幾個小時,但似乎無法弄清楚為什么我的情況如此難以解決。 我確定我只需要一雙知道自己在看什么的眼睛。

我正在嘗試將下拉選擇的索引傳遞到我的 Code.gs 函數中,以便我可以在其他地方使用它來選擇電子表格中的某一行數據。 我設置了對象 driverPicked 並為其指定了選定的屬性,然后尋找選定的索引屬性。 由於我對此非常陌生,因此我很難理解像這樣嵌套屬性的后果,並且可以使用線索來解決如何解決“TypeError:無法讀取未定義的屬性‘selected’(第 39 行,文件“代碼”)”錯誤我已經有幾個小時了。

有很多類似的答案,但我無法確切地弄清楚它們如何適用於我 - 所以請原諒我!

var url = "REDACTED";

function doGet(e){

//var x = document.getElementById("driver").selectedIndex;  

var driverIndex = userClicked();
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Results_2019");
var listDrivers = ws.getRange(4,1,ws.getRange("A3").getDataRegion().getLastRow(),1).getValues();
var infoHeading = ws.getRange(3, 1, 1, 8).getValues();
var driverInfo = ws.getRange(driverIndex, 1, 1 ,8).getValues();


var tmp = HtmlService.createTemplateFromFile("page"); 
tmp.title = "GLTC Driver List";
//tmp.listDrivers = listDrivers.map(function(r){r[0];});
tmp.listDrivers = [].concat.apply([], listDrivers);
tmp.infoHeading = [].concat.apply([], infoHeading);
tmp.driverInfo = [].concat.apply([], driverInfo);
tmp.driverIndex = driverIndex;


return tmp.evaluate();

}


function include(filename){
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}


function userClicked(driverPicked) {
  console.log(driverPicked); 
  var driverName = driverPicked.value;
  return driverName;
}


<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <!--Let browser know website is optimized for mobile-->
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <!--Import Google Icon Font-->
     <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <!-- Compiled and minified CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <?!= include("page-css"); ?>
  </head>
  <body>

    <h1><?= title; ?></h1>

    <div class="input-field">
  <select id="driver">
    <option disabled selected>Choose Driver</option>
    <? for(var i=0;i<listDrivers.length;i++){ ?>
      <option class="selected">
        <?= listDrivers[i]; ?>
      </option>
      <? } ?>
  </select>
</div>

  <h5><?= infoHeading; ?></h5>

  <h5><?= driverInfo; ?></h5>

  <h5><?= driverIndex; ?></h5>

<script>  

document.getElementById("driver").addEventListener("change", doStuff); // add onchange listener to the select element instead of options

function doStuff(event) {
  var driverPicked = {};

  driverPicked.driver = event.target.value;
  driverPicked.selected = event.target.options.selectedIndex;
  userClicked(driverPicked);
}


  </script>

    <!-- Compiled and minified JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    <?!= include("page-js"); ?>

  </body>
</html>

代碼的幾個問題:

  1. DOM 元素的 id 必須是唯一的,因此在呈現選項時,您需要為 id 添加索引或使用類名。
  2. select元素使用change事件而不是click
  3. 您可以在doStuff函數中訪問事件對象作為參數,而不是手動查詢 DOM 元素。 我不確定為什么需要獲取索引,但是為了獲取驅動程序的名稱,您可以這樣做:
<div class="input-field">
  <select id="driver">
    <option disabled selected>Choose Driver</option>
    <? for(var i=0;i<listDrivers.length;i++){ ?>
      <option class="selected"> // use class instead of id here
        <?= listDrivers[i]; ?>
      </option>
      <? } ?>
  </select>
</div>
document.getElementById("driver").addEventListener("change", doStuff); // add onchange listener to the select element instead of options

function doStuff(event) {
  var driverPicked = {};

  driverPicked.driver = event.target.value;
  driverPicked.selected = event.target.options.selectedIndex;

  google.script.run.userClicked(driverPicked);
}

function userClicked(driverPicked) {

  var driverName = driverPicked.value;
  return driverName;
}

這是一個帶有一些模擬select選項的可運行示例:

 document.getElementById("driver").addEventListener("change", doStuff); // add onchange listener to the select element instead of options function doStuff(event) { var driverPicked = {}; driverPicked.driver = event.target.value; driverPicked.selected = event.target.options.selectedIndex; userClicked(driverPicked); } function userClicked(driverPicked) { console.log(driverPicked); var driverName = driverPicked.value; return driverName; }
 <div class="input-field"> <select id="driver"> <option disabled selected>Choose Driver</option> <option class="selected"> Driver 1</option> <option class="selected"> Driver 2</option> </select> </div>

這里做了一些簡化。 主要的是,我不是通過google.script.run調用該函數,而是直接調用它。

更新

我忘了包括在最初的回應中。 元素id應該是唯一的。 如果您遍歷所有元素並且不更改它們的 id 值,那么您正在制作不正確的 HTML,並且函數getElementById(...)將返回一個元素數組而不是僅返回一個元素數組(因此,其余代碼將不起作用正如預期的那樣)

見下面的演示

 document.getElementById("driver").addEventListener("change", doStuff); function doStuff() { var driverPicked = {}; selectBox = document.getElementById("driver"); driverPicked = selectBox.options[selectBox.selectedIndex]; console.log('User changed value to: '); console.log(driverPicked); // will this work on other browsers? // google.script.run.userClicked(driverPicked); // I am using this instead for demo purposes userClicked(driverPicked); } function userClicked(driverPicked) { var driverName = driverPicked.value; var driverText = driverPicked.text; console.log('name/value: ' + driverName + ' text: ' + driverText); return driverName; }
 <div class="input-field"> <select id="driver"> <option disabled>Choose Driver</option> <option value="1">One</option> <option value="2">Two</option> <option value="3">Three</option> <option value="4">Four</option> </select> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM