【问题标题】:Check if all input/select fields of a table row have values检查表行的所有输入/选择字段是否都有值
【发布时间】:2016-06-08 06:21:57
【问题描述】:

有一个表格,其中有一些输入和选择字段。我想检查一行的所有输入和选择字段是否都有值。这就是我的想法,但我必须使用closestfind 吗?我认为这不是最佳选择。

HTML

<table>
    <tr>
        <td><select><option></option><option>Select anything</option></td>
        <td><input type="text" name="field1"></td>
        <td><input type="text" name="field2"></td>
    </tr>
    <tr>
        <td><select><option></option><option>Select something</option></td>
        <td><input type="text" name="field3"></td>
        <td><input type="text" name="field4"></td>
    </tr>
</table>

JS

'change #table input, change #table select': function(event) {
  var $this = $(event.currentTarget),
      $row  = $this.closest('tr'),
      $elements = $row.find('input, select');

  var empty = false;
  $elements.each(function(index) {
    if (!$(this).val()) empty = true;
  });

  if (empty)
    console.log('some value is missing')
  else {
    console.log('valide');
    // do something with values
  }
}

【问题讨论】:

  • 我想我会把一行的所有inputselect元素放在同一个类中,然后按类查询。

标签: javascript jquery


【解决方案1】:

这里真的有两个问题:

  1. 选择表格行中所有输入的最佳方法
  2. 确保所有输入都有值

对于第一个问题,有潜意识的一面。确保它是一个输入,然后在更改输入的当前行的上下文中选择它。

首先,jQuery 在后台使用 Sizzle (https://sizzlejs.com/) 引擎进行选择。需要注意的一件事是该引擎对选择器字符串的“从右到左”处理。

因此,最佳选择在某种程度上是特定于浏览器的,但最快的选择方法是在现代浏览器中使用 ID 后跟一个类。一些较旧的浏览器也不会按类别进行选择,但让我们留待您研究。

选择:做事的方式不好

鉴于此,让我们看一下您可能会使用的复杂选择器:

'div.mycontainer div.mytablecontainer&gt;table#mytable.mytableclass tr td select, div.mycontainer div.mytablecontainer&gt;table#mytable.mytableclass tr td input'

首先不要使用它。现在来探讨为什么不这样做:还记得我们讨论过“从右到左”选择器处理吗?为了讨论,让我们将选择器缩小到最后一部分:

"div.mycontainer div.mytablecontainer&gt;table#mytable.mytableclass tr td input"

然后从右边开始:

  1. “查找 DOM 中的所有输入”,
  2. 使用这些输入的列表,“在 td 元素中查找所有输入
  3. 使用那些td 元素,找到tr 中的所有元素
  4. .mytableclass 元素中找到所有tr
  5. 在 ID 为 mytable 的元素中查找所有元素(请记住,此 ID 必须是唯一的)
  6. 现在继续,找到 table 元素的单个元素 id
  7. 这是类mytablecontainer 的元素的直接子元素
  8. 这是一个DIV元素div
  9. 这是类mycontainer的元素的子元素
  10. 这是一个DIV元素div

哇,那里的工作量很大。但我们还没有完成!我们必须为那里的 OTHER 选择器做同样的事情。

选择:更好的做事方式

现在让我们做得更好;首先,让我们利用现代浏览器类选择器向我们所有的“作用域”输入添加一个类——我们想要检查条目的东西。

<input class="myinput" />

它确实需要type="" 属性,但暂时忽略它。让我们使用它。

$('#mytable').find('.myinput');

这是做什么的:

  1. 选择ID为'mytable'的元素,这是所有浏览器中最快的选择器;我们已经在 DOM 中删除了这 47 个其他表。
  2. 查找类为class="myinput"的所有元素; 该表中;在现代浏览器中,这也非常快

完成。哇!工作量要少得多。

关于.find() 而不是"#mytable input" 的旁注

还记得我们的从右到左吗?找到 DOM 中的所有输入,然后缩小到我们在该表中找到的那些输入,现在不要停止。

或者(更有可能)"#mytable .myinput"

所以我们选择一组元素的“规则”是:

  1. 尽可能使用 ID 将范围限制到某个容器
  2. 单独使用 ID,而不是更复杂的选择器的一部分
  3. 在有限范围内查找元素(如果可以,按类)
  4. 使用类,因为现代浏览器对此进行了出色的选择优化。
  5. 当您开始在选择器中添加空格“”或“>”时,.find().children() 会更好吗?在一个小的 DOM 中也许维护可能更容易,但在 4 年内哪个更容易理解?

第二个问题:不具体但仍然存在

您不能简单地将!$(this).val() 用于输入。 对于无效的复选框。单选按钮呢?那&lt;input type="button" &gt; 稍后有人添加到行中呢?哎呀。

所以只需向您希望验证的所有“输入”添加一个类并由它们选择:

<input type="text" class="validateMe" />
<select class="validateMe" >...

附注您可能想要嗅探输入的类型并基于此进行验证:How to get input type using jquery?

编辑:请记住,您的验证输入可能具有“真/假”值,因此这可能会失败:!$(this).val()(此处想到单选按钮,复选框)

一些代码和标记:

<table id="mytable">
  <tr>
    <td>
      <select class="myinput">
        <option></option>
        <option>Select anything</option>
      </select>
    </td>
    <td>
      <input class="myinput" type="text" name="field1" />
    </td>
    <td>
      <input class="myinput" type="text" name="field2" />
    </td>
  </tr>
  <tr>
    <td>
      <select class="myinput">
        <option></option>
        <option>Select something</option>
      </select>
    </td>
    <td>
      <input class="myinput" type="text" name="field3" />
    </td>
    <td>
      <input class="myinput" type="text" name="field4" />
    </td>
  </tr>
</table>
<div id="results">

</div>

可能不想要一个全局(命名空间“选择器”)

var selectors = '.myinput';
$('#mytable').on('change', selectors, function(event) {
  var $this = $(event.currentTarget),
    $row = $this.closest('tr'),
    $elements = $row.find(selectors);
  var $filledElements = $elements.filter(function(index) {
    return $(this).val() || this.checked;
  });

  var hasEmpty = $filledElements.length !== $elements.length
  var rowIndex = $row.index();
  $('#results').append("Row:" + rowIndex + " has " + $filledElements.length + ' of ' + $elements.length + ' and shows ' + hasEmpty + '<br />');
  if (hasEmpty)
    console.log('some value is missing');
  else {
    console.log('valide');
    // do something with values
  }
});

还有一些可以玩的东西:https://jsfiddle.net/MarkSchultheiss/fqadx7c0/

【讨论】:

  • 非常感谢您的出色回答。我学到了很多。谢谢。
  • @Mark Schultheiss - 当每个元素的 不同时会发生什么?那么选择器需要动态更新。
【解决方案2】:

如果您只在知道要选择哪个父级的情况下仅选择特定元素,则应尝试使用.filter() 仅过滤掉不具有如下值的元素:

$('button').click(function() {

    var h = $('table :input').filter(function() {
       return $(this).val() == "" && $(this);
    }).length;

    alert(h);

});

DEMO

【讨论】:

  • 您的&amp;&amp; $(this); 将始终为真,因为您确实选择了一个元素,因此在这里没有用处。如果文本字段的值为空格“”,您将其显示为“有效”,但我想知道它是否真的存在 - 可能是一个特定于空值的问题域(只有空格或没有)
  • @MarkSchultheiss :是的,这对于类型复选框和收音机将失败。错过了。举个例子,上面提供了 OP 提供的 html。虽然输入需要正则表达式来检查有效性,因为您和我的代码将通过任何填充空格的文本字段。
【解决方案3】:

我做了这件事

https://plnkr.co/edit/q3iXSbvVWEQdLSR57nEi

$(document).ready(function() {
  $('button').click(function() {
    var table = $('table');
    var rows = table.find('tr');
    var error = 0;

    for (i = 0; i < rows.length; i++) {
      var cell = rows.eq(i).find('td');
      for (a = 0; a < cell.length; a++) {
        var input = cell.eq(a).find(':input');

        if (input.val() === "") {
          input.css("border", "solid 1px red");
          error++;
        } else {
          input.css("border", "solid 1px rgb(169, 169, 169)");
        }
      }
    } 

    if (error > 0){
      alert('Errors in the form!')
      return false;
    } else {
      alert('Form Ok!')
      return true;
    }
  })
})

简单的 Jquery 验证,搜索所有输入(包括选择),如果它为空,则递增错误计数器并更改类。如果错误计数器>0,则提示错误并返回false;

也许不是最好的解决方案,但它确实可以帮助入门。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 2023-01-31
    • 1970-01-01
    相关资源
    最近更新 更多