禁用除第一行以外的所有行,并在上面的行充满数据时启用每一行

Posted

技术标签:

【中文标题】禁用除第一行以外的所有行,并在上面的行充满数据时启用每一行【英文标题】:disable all rows except first row and enable each row when the above row is filled with data 【发布时间】:2019-04-19 21:59:13 【问题描述】:

我有一个 4 行的 html 表,当用户在 first 中输入所有详细信息时,我只想启用第一行并禁用所有其他 3 行并启用第二行(输入订单 ID,选择 Product1,输入描述并从下拉列表中选择 Product2)。 同样,当用户在第二行中输入所有详细信息时启用第三行。 我尝试在<tr> 中使用disabled="disabled" 来禁用最后3 行,但它没有按预期工作。

另一个验证检查是当用户在每一行的描述列中输入值时,它只应该检查用户在其中选择的值 Product1 和 Product2 列,如果在 Product1 和 Product2 下拉列表中选择的值相同,则显示错误消息(Product1 和 Product2 值不能相同)。

演示:http://plnkr.co/edit/7s3QQXrrmaH3nUXQ0td5?p=preview

html代码:

<table id="productTable" border="1">
    <thead>
    <tr>
        <th>Order ID</th>
        <th>Product1</th>
        <th>Description</th>
        <th>Product2</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td><input type="text" name="orderNum" value=""></td>
        <td>
            <select class="product1" >
                <option value=""></option>
            </select>
        </td>
        <td>
            <input type="text" name="description" value="">
        </td>
        <td>
            <select class="product2" >
                <option value=""></option>
            </select>
        </td>
    </tr>
    <tr disabled="disabled">
        <td><input type="text" name="orderNum" value=""></td>
        <td>
            <select class="product1" >
                <option value=""></option>
            </select>
        </td>
        <td>
            <input type="text" name="description" value="">
        </td>
        <td>
            <select class="product2" >
                <option value=""></option>
            </select>
        </td>
    </tr>
    <tr disabled="disabled">
        <td><input type="text" name="orderNum" value=""></td>
        <td>
            <select class="product1" >
                <option value=""></option>
            </select>
        </td>
        <td>
            <input type="text" name="description" value="">
        </td>
        <td>
            <select class="product2" >
                <option value=""></option>
            </select>
        </td>
    </tr>
    <tr disabled="disabled">
        <td><input type="text" name="orderNum" value=""></td>
        <td>
            <select class="product1" >
                <option value=""></option>
            </select>
        </td>
        <td>
            <input type="text" name="description" value="">
        </td>
        <td>
            <select class="product2" >
                <option value=""></option>
            </select>
        </td>
    </tr>
    </tbody>
</table> <br>
<button name="submit" id="dataButton" onClick="getData()" disabled>Get Data</button>

js代码:

 function populateSelect() 
     var ids = ["pid":"laptop","des":"laptop","pid":"Mobile","des":"Mobile","pid":"IPAD mini.","des":"IPAD mini."]
      var productDropdown1 = $(".product1"); 
      var productDropdown2 = $(".product2");
      $.each(ids, function(index,value) 
      $("<option />").text(value.des).val(value.pid).appendTo(productDropdown1);
        $("<option />").text(value.des).val(value.pid).appendTo(productDropdown2);
      );

       $("select").change(function() 
          
       var row = $(this).closest("tr");
       var product1_drop = $('.product1',row).val();
       var product2_drop = $('.product2',row).val();
       if(product1_drop == product2_drop )       
            alert('Product1 and Product2 cannot have same value');
      
   );
 

使用上面的 js 代码,当用户从下拉列表中选择值时,它会检查验证,但我想当用户在文本框中输入文本时检查两个下拉列表(Product1 和 Product2)是否有相同的值并在该行附近显示错误消息,而不是弹出对话框。

【问题讨论】:

你必须禁用表单控件元素而不是行 @charlietfl - 你能提供一些输入吗,提前谢谢 好的开始可以做类似$('#productTable tbody tr:gt(0) :input').prop('disabled',true)的事情,它应该禁用除第一行之外的所有内容 感谢您的输入..当仅在第一行中填写所有字段时,我仍然无法动态启用每一行,因为当输入所有字段时,我只需要启用直接行当前行。令人惊讶的是,我找不到相同的合适示例……谢谢。 取决于用例。可以使用按钮并在单击时验证前一行,或使用输入事件并检查该行上的每个元素是否具有值然后启用下一行 【参考方案1】:

如果我正确理解了您的问题,那么您正在尝试执行以下代码。您可以使用事件委托将 1 个事件侦听器附加到父 tr 以侦听对该行中所有 &lt;input&gt;select 元素的更改。

让事件侦听器检查所有input 元素是否都有值,如果有,则使用NonDocumentTypeChildNode.nextElementSibling 从下一行中的下一个元素中删除disabled 属性

function initTable(rowQuantity, columnQuantity) 
  const tbody = document.getElementById('productTable').querySelector('tbody');
  for (let i = 0; i < rowQuantity; i++) 
    let row = document.createElement("tr");
    for (let j = 0; j < columnQuantity; j++) 
      let cell = document.createElement("td");
      let content = null;
      let option = null;

      switch (j) 
        case 0:
          content = document.createElement("input");
          content.setAttribute("type", "text");
          content.setAttribute("name", "orderNum");
          break;
        case 1:
          content = document.createElement("select");

          option = document.createElement("option");
          option.setAttribute("value", "dog");
          option.appendChild(document.createTextNode("Dog"));
          content.appendChild(option);

          option = document.createElement("option");
          option.setAttribute("value", "cat");
          option.appendChild(document.createTextNode("Cat"));
          content.appendChild(option);

          option = document.createElement("option");
          option.setAttribute("value", "hamster");
          option.appendChild(document.createTextNode("Hamster"));
          content.appendChild(option);
          break;
        case 2:
          content = document.createElement("input");
          content.setAttribute("type", "text");
          content.setAttribute("name", "description");
          break;
        case 3:
          content = document.createElement("select");

          option = document.createElement("option");
          option.setAttribute("value", "x");
          option.appendChild(document.createTextNode("X"));
          content.appendChild(option);

          option = document.createElement("option");
          option.setAttribute("value", "y");
          option.appendChild(document.createTextNode("Y"));
          content.appendChild(option);

          option = document.createElement("option");
          option.setAttribute("value", "z");
          option.appendChild(document.createTextNode("Z"));
          content.appendChild(option);
          break;
      

      if (i > 0) 
        content.setAttribute('disabled', true);
      
      cell.appendChild(content);
      row.appendChild(cell);
    

    //Event delegation to the parent
    row.addEventListener('change', function(e) 
      const cells = e.currentTarget.querySelectorAll('td');
      const selections = Array.prototype.reduce.call(cells, (sum, cell) => 
        if (cell.children[0].value) 
          sum += 1;
        
        return sum;
      , 0);

      if (selections === columnQuantity) 
        if (row.nextElementSibling) 
          let nextRowEls = row.nextElementSibling.querySelectorAll('input');
          Array.prototype.forEach.call(nextRowEls, el => el.disabled = false);
          nextRowEls = row.nextElementSibling.querySelectorAll('select');
          Array.prototype.forEach.call(nextRowEls, el => el.disabled = false);
        
      
    )

    tbody.appendChild(row);
  


initTable(4, 4);
<table id="productTable" border="1">
  <thead>
    <tr>
      <th>Order ID</th>
      <th>Product1</th>
      <th>Description</th>
      <th>Product2</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

【讨论】:

感谢您的努力,但如果可能的话,我正在寻找更简单的方法来验证使用 jquery。谢谢。

以上是关于禁用除第一行以外的所有行,并在上面的行充满数据时启用每一行的主要内容,如果未能解决你的问题,请参考以下文章

选择 Mariadb 中除顶行以外的所有行

MySQL - 查询除第一行之外的所有行[重复]

c_str() 输入一个字符串 - 除第一行之外的所有其他行都将丢失

jQuery删除除第一行之外的所有表行

随机播放数据框中的特定行[重复]

jQuery选择除第一个以外的所有内容