javascript-按钮单击并返回值时出现重复的多级下拉菜单

时间:2018-07-28 20:59:16

标签: javascript html

这是设置。在初始页面上,我有两个彼此相邻的下拉菜单。第二个下拉列表中的值取决于第一个下拉列表中的值。效果很好。

我有一个添加按钮,用于复制下拉菜单行,即在前一个下拉菜单下方添加2个相邻的下拉菜单。

添加下拉菜单效果很好。但是,如果我在初始下拉菜单中选择了一个值,并且在第二个下拉菜单中加载了相应的值(取决于第一个下拉菜单中的值),则该值会在新添加的下拉列表中重复。

此外,新添加的下拉列表没有响应,即,左侧下拉列表的更改不会更改右侧下拉列表中的值。 (仅在最初添加的下拉菜单中提供响应)

也许我没有使用最佳的javascript做法,请原谅我,因为我对此很陌生。

欢迎任何反馈。谢谢。

这是代码:

<div class="container">
        <table id="myTable">
                <tr id="initialRow" class="select_row">



<td>
        <select  id= "select1" class = "select1">
                <option>Select an option</option>
                <option>yes</option>
                <option>no</option>
              </select>

                <select  id = 'select2' class = "select2">
                </select>

</td>

</tr>
</table>
<button class = "button" type="button" onClick ="addRow()">Add</button>
<button class = "button" type="button" onClick ="getValues()">Print values</button>
</div>

<script>
    const table = document.querySelector('#myTable');
    const rowToDuplicate = document.querySelector('#initialRow');
    function addRow() { 
      var duplicate = rowToDuplicate.cloneNode(true);
   duplicate.removeAttribute('id');      table.appendChild(duplicate);
    }

    function getValues() {
      const rows = document.querySelectorAll('.select_row');
     rows.forEach((row, i) => {
       console.log(`row ${i}: select1 `, row.querySelector('.select1').value);   console.log(`row ${i}: select2 `,row.querySelector('.select2').value);
     })

    }
</script>


<script>
        (function() {

            //setup an object fully of arrays
            //alternativly it could be something like
            //{"yes":[{value:sweet, text:Sweet}.....]}
            //so you could set the label of the option tag something different than the name
            var bOptions = {
              "yes": ["sweet", "wohoo", "yay"],
              "no": ["you suck!", "common son"]
            };

            var A = document.getElementById('select1');
            var B = document.getElementById('select2');

            //on change is a good event for this because you are guarenteed the value is different
            A.onchange = function() {
              //clear out B
              B.length = 0;
              //get the selected value from A
              var _val = this.options[this.selectedIndex].value;
              //loop through bOption at the selected value
              for (var i in bOptions[_val]) {
                //create option tag
                var op = document.createElement('option');
                //set its value
                op.value = bOptions[_val][i];
                //set the display label
                op.text = bOptions[_val][i];
                //append it to B
                B.appendChild(op);
              }
            };
            //fire this to update B on load
            A.onchange();

          })();
      </script>

1 个答案:

答案 0 :(得分:1)

几件事:

  1. script标记中的代码运行一次。这意味着您只需初始化一次选择。您动态添加的那些选择不会被初始化,并且不会对onchange事件做出反应。
  2. 您的克隆还不够。您需要克隆clean行,然后继续对其进行克隆。
  3. 您过于依赖ids。一旦开始处理新的动态行,这些ID就会很麻烦。

我做了一个快速修复,应该可以帮助您。让我知道是否有帮助。

<div class="container">
  <table id="myTable">
    <tr id="initialRow" class="select_row">
      <td>
        <select class="select1">
          <option>Select an option</option>
          <option>yes</option>
          <option>no</option>
        </select>
        <select class="select2"></select>
      </td>
    </tr>
  </table>
  <button class="button" type="button" onClick="addRow()">Add</button>
  <button class="button" type="button" onClick="getValues()">Print values</button>
</div>

<script>
  const table = document.getElementById('myTable');
	const initialRow = document.getElementById('initialRow');
  const rowToDuplicate = initialRow.cloneNode(true);

  function addRow() {
     let duplicate = rowToDuplicate.cloneNode(true);	
     let select1 = duplicate.lastElementChild.firstElementChild
     let select2 = duplicate.lastElementChild.lastElementChild		

     select1.setAttribute('id', 'select1-' + table.children.length)
     select2.setAttribute('id', 'select2-' + table.children.length)

     table.appendChild(duplicate);
     initSelects(select1, select2);
  }

  function getValues() {
    const rows = document.querySelectorAll('.select_row');
    rows.forEach((row, i) => {
      console.log(`row ${i}: select1 `, row.querySelector('.select1').value);
      console.log(`row ${i}: select2 `, row.querySelector('.select2').value);
    })
  }
	
	function initSelects(a, b) {
		var bOptions = {
      "yes": ["sweet", "wohoo", "yay"],
      "no": ["you suck!", "common son"]
    };

		a.onchange = function () {
			//clear out B
			b.length = 0;
			//get the selected value from A
			var _val = this.options[this.selectedIndex].value;
			//loop through bOption at the selected value
			for (var i in bOptions[_val]) {
				//create option tag
				var op = document.createElement('option');
				//set its value
				op.value = bOptions[_val][i];
				//set the display label
				op.text = bOptions[_val][i];
				//append it to B
				b.appendChild(op);
				}
		}
	}
	
	initSelects(
		initialRow.lastElementChild.firstElementChild, 
		initialRow.lastElementChild.lastElementChild
	);
</script>