【问题标题】:duplicate drop-downs on button click单击按钮时重复的下拉菜单
【发布时间】:2018-07-29 22:27:55
【问题描述】:

目前我有这个设置。 我的页面加载了 2 个相邻对齐的下拉菜单和一个添加按钮。 ADD 按钮使用函数 addRow() 在下一行添加一个下拉列表。 该函数可能是最糟糕的实现。

a) 我希望添加按钮将 2 个类似的下拉菜单添加到下一行,这些下拉菜单与最初在页面中相邻对齐。 (现在代码只在下一行添加了 1 个下拉菜单)

b) 有什么方法可以将添加按钮放在我拥有的下拉菜单下方,而不是放在第一行下拉菜单旁边?

下面是代码

<div class="container">
        <table>
                <tr>



<td>
<select id="soflow">
  <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
  <option>Select an Option</option>
  <option>Option 1</option>
  <option>Option 2</option>
</select>

<select id="soflow">
    <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
    <option>Select an Option</option>
    <option>Option 1</option>
    <option>Option 2</option>
  </select>

 <button class = "button" type="button" onClick ="addRow(this)">Add</button></td>

</tr>
</table>

</div>

<script>
    function addRow(btn) {         
        var parentRow = btn.parentNode.parentNode;
        var table = parentRow.parentNode;
        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);
        var cell1 = row.insertCell(0);
        //var element2 = document.createElement("input");
        var element2 = document.createElement("select");
        element2.setAttribute("id", "soflow")
        //element2.type = "select";
        var option1 = document.createElement("option");
        option1.innerHTML = "Option1";
        option1.value = "1";
        element2.add(option1, null);
        var option2 = document.createElement("option");
        option2.innerHTML = "Option2";
        option2.value = "2";
        element2.add(option2, null);
        cell1.appendChild(element2);
    }
</script>

感谢您的帮助。

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    id 提供给要克隆的 &lt;tr&gt;table。然后使用cloneNode() 克隆该行并将其附加到表中。

    <div class="container">
            <table id="myTable">
                    <tr id="initialRow" class="select_row">
    
    
    
    <td>
    <select id="soflow" class="select1">
      <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
      <option>Select an Option</option>
      <option>Option 1</option>
      <option>Option 2</option>
    </select>
    
    <select id="soflow"  class="select2">
        <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
        <option>Select an Option</option>
        <option>Option 1</option>
        <option>Option 2</option>
      </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>

    【讨论】:

    • 完美。我可以跟踪以某种方式创建的所有下拉列表吗?因为我需要在我添加的所有下拉列表中选择值。
    • 除了删除id 属性外,您还可以使用标准模式来命名它并使其随机命名,这样一个就不会与另一个冲突。喜欢duplicate.id = "row_" + Math.random()
    • 如果它回答了您的问题,请将其标记为正确答案。
    【解决方案2】:

    您有两个同名的 ID。将 ID 属性更改为两个选择元素(例如 &lt;select id="soflow1"&gt; &amp;&amp; &lt;select id="soflow2"&gt;)具有不同的名称,并在您的 Javascript 中将每个元素称为 soflow1soflow2。您的 JavaScript 引用了两个 ID 元素并导致通过一次调用打开两个下拉菜单。

    ID 应该只对一个元素是唯一的。

    要在这些下拉元素中使用相同的样式,请添加一个与 &lt;select id="soflow1" class="myDropdownClass"&gt; &amp;&amp; &lt;select id="soflow2" class="myDropdownClass"&gt; 等选择元素相同的类属性,并为 .myDropdownClass { //some style } 创建 CSS

    要将按钮放在选择元素下方,您可以在表格中执行此操作...

    <table>
        <tr>
            <td><select id="soflow1" class="myDropdownClass" ... /></td>
            <td><select id="soflow2" class="myDropdownClass" ... /></td>
        </tr>
        <tr>
            <td colspan="2"><button>text</button></td>
        </tr>
    </table>
    

    【讨论】:

      【解决方案3】:

      我喜欢将事件侦听器添加到表中,因为单击会使 dom 树冒泡。然后检查它是否是调用事件的类“add”的元素。如果是,则克隆表的行节点并将其附加到表体。我还将按钮放在表格页脚中,因此它始终位于底部。希望这会有所帮助。

      此方法还允许您更改表的结构,而无需重写 javascript 以正确爬上 dom 树。为 S&G 添加了删除行按钮。

      以类似的方式在每个选择元素上没有 id 的情况下获取值,您可以使用 solflow 元素列表中的元素索引作为唯一标识符和值。

      由于您通过克隆行来创建动态元素,因此需要将 solflow 的事件侦听器添加到新的 select 元素中,或者表格可以处理更改事件,在这种情况下,您只需添加一次更改处理程序,然后 solflow无论何时添加元素,都会改变气泡。以类似的方式,可以使用表格单击处理程序创建提交按钮,该处理程序从表格中的 solflow 元素中获取所有值,并将它们索引到 solflow 元素的数量,作为键值存储或作为与订单匹配的 solflow 值数组元素出现在其中。

      <table>
        <tbody>
          <tr>
            <td>
              <select class="solflow">
                <option>Select an Option</option>
                <option>Option 1</option>
                <option>Option 2</option>
              </select>
              <select class="solflow">
                <option>Select an Option</option>
                <option>Option 1</option>
                <option>Option 2</option>
              </select>
          </tr>
        </tbody>
        <tfoot>
          <tr>
            <td>
              <button class="button add" type="button">Add</button>
              <button class="button remove" type="button">Remove</button>
            </td>
          </tr>
        </tfoot>
      </table>
      <script>
        function tableClickHandler(e) {
          if (e.target.classList.contains('add')) {
              let tbody = this.querySelector('tbody');
              let row = tbody.querySelector('tr');
              tbody.appendChild( row.cloneNode(true) );
          }
          if (e.target.classList.contains('remove')) {
              var tbody = this.querySelector('tbody');
              var row = tbody.querySelectorAll('tr');
              if (row.length > 1) {
                tbody.removeChild(row[row.length-1]);
              }
          }
        }
      
        function tableChangeHandler(e) {
          if (e.target.classList.contains('solflow')) {
            let solflows = this.querySelectorAll('.solflow');
            let solflow = e.target;
            let index = -1;
            solflows.forEach(function(el, ind){
              if (el === solflow) { index = ind }
            });
            console.log(index, solflow.value);
          }
        }
      
        document.querySelector('table').addEventListener('click', tableClickHandler);
        document.querySelector('table').addEventListener('change', tableChangeHandler);
      </script>
      

      【讨论】:

        【解决方案4】:

        您可以使用for 循环循环两次并创建两个selects。如果您希望按钮始终位于选择项(添加的和初始的)下方,同时将新行添加到表中以进行选择,则应将按钮移到表外。

        另外,一个id 不能有多个元素。您最初有 2 个带有 id“soflow”的元素,当单击 Add 按钮时将添加更多元素。

        要计算添加了多少selects,您只需要一个全局变量,每次运行函数内的for 循环时增加一。

        <div class="container">
                <table id="selectTable">
                        <tr>
        
        
        
        <td>
        <select id="soflow">
          <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
          <option>Select an Option</option>
          <option>Option 1</option>
          <option>Option 2</option>
        </select>
        
        <select id="soflow2">
            <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
            <option>Select an Option</option>
            <option>Option 1</option>
            <option>Option 2</option>
          </select>
        <br/>
         </td>
        
        </tr>
        </table>
        <button class = "button" type="button" onClick ="addRow(this)">Add</button>
        </div>
        
        <script>
            var addedSelects = 0;//total number of dropdowns added
            function addRow(btn) {         
                var table = document.getElementById('selectTable');
                var soflow = document.getElementById("soflow2");
                var rowCount = table.rows.length;
                var row = document.createElement('tr');
                table.appendChild(row);
                //var element2 = document.createElement("input");
                var td = document.createElement('td');
                row.appendChild(td);
                for(let i = 0; i < 2; i++){
                var element2 = document.createElement("select");
                //element2.setAttribute("id", "soflow"+(i+1))
                //element2.type = "select";
                var option1 = document.createElement("option");
                option1.innerHTML = "Option1";
                option1.value = "1";
                element2.add(option1, null);
                var option2 = document.createElement("option");
                option2.innerHTML = "Option2";
                option2.value = "2";
                element2.add(option2, null);
                td.appendChild(element2);
                addedSelects++;
                }
            }
        </script>

        【讨论】:

        • 是的,但问题仍然存在,因为他指的是具有相同 ID 的两个选择元素,并且相同的不需要的行为将持续存在。
        • 这就是我要找的。不过一件小事。添加按钮应始终保留在底部,即在所有下拉菜单之后。目前固定在初始位置
        • @hev1 新的下拉菜单应该添加到之前的下拉菜单下面。此代码将它们添加到之前的代码旁边,即在同一行中。
        • @hev1 谢谢!还有一件事。有没有办法可以跟踪所有添加的下拉菜单?因为最后我需要获取所有下拉列表中当前选择的所有值。
        • @nazschi 没问题。您可以有一个全局变量,每次添加选择时都会增加一。我在我的代码 sn-p 中添加了这样一个变量。
        【解决方案5】:

        这应该可以解决问题

        function addRow() {         
            //Select the table
            var table = document.getElementsByTagName('table')[0];
            //Append a row
            table.innerHTML = table.innerHTML + '<tr>\
                <td>\
                    <select>\
                        <option>Select an Option</option>\
                        <option>Option 1</option>\
                        <option>Option 2</option>\
                    </select>\
                    <select>\
                        <option>Select an Option</option>\
                        <option>Option 1</option>\
                        <option>Option 2</option>\
                    </select>\
                </td>\
            </tr>';              
        }
        <div class="container">
            <table>
                <tr>
                    <td>
                        <select>
                            <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
                            <option>Select an Option</option>
                            <option>Option 1</option>
                            <option>Option 2</option>
                        </select>
        
                        <select>
                            <!-- This method is nice because it doesn't require extra div tags, but it also doesn't retain the style across all browsers. -->
                            <option>Select an Option</option>
                            <option>Option 1</option>
                            <option>Option 2</option>
                        </select>
                    </td>  
                </tr>
            </table>
            <button class = "button" type="button" onClick ="addRow()">Add</button>
        </div>

        添加按钮总是停留在底部,因为我把它移出了表格。我删除了选择标签上的 id,重复的 id 会给你错误,尝试使用document.getElementsByTagName('select')[x] 选择器并使用0(其中x)获取第一个下拉列表,1 获取第二个...我也只是使用文本而不是通过 JS 创建元素,因为在我看来它们更容易阅读、创建和修改。如果您有任何问题,请尽管提问。

        【讨论】:

        • innerHTML 是邪恶的; )
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多