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

标签 javascript jquery html css

我有一个包含 4 行的 html 表格,我只想启用第一行并禁用所有其他 3 行,当用户在 first 中输入所有详细信息时启用第二行(输入订单 ID,选择产品 1,输入描述并从下拉列表中选择产品 2)。 同样,当用户在第二行中输入所有详细信息时,启用第三行。 我尝试使用 disabled="disabled"<tr>禁用最后 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)是否具有相同的值并在该行附近显示错误消息而不是弹出对话框。

最佳答案

如果我正确理解您的问题,那么您正在尝试执行类似我下面的代码的操作。您可以使用事件委托(delegate)将 1 个事件监听器附加到父级 tr监听所有 <input> 的变化和 select该行中的元素。

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

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>

关于javascript - 禁用除第一行以外的所有行,并在上面的行充满数据时启用每一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53342499/

相关文章:

使用 FOR 循环的 Javascript 表单验证

javascript - jquery 有时不调整 div 宽度

javascript - 将 div 置于另一个 div 之下

javascript - 防止 iOS 11.3 溢出弹跳

javascript - D3水平堆叠条形图添加和删除数据

javascript - Jquery 元素用法

javascript - 在不丢失附加事件监听器的情况下修改 HTML 标记

asp.net - Javascript 文件依赖 - 选择性加载资源文件并防止重复

带有图像的 HTML 圆 div 试图获取悬停文本

javascript - 了解jQuery函数的调用/初学者小响应式布局脚本的反馈