【问题标题】:jQuery set value of each previous sibling of each ticked checkbox upon submitjQuery在提交时设置每个勾选复选框的每个前一个兄弟的值
【发布时间】:2021-12-01 03:00:24
【问题描述】:

我一直在为此寻找解决方案,发现最有效的方法是通过像这样的 hacky 解决方法,但没有一个发布了一种有效的方法来使用大量复选框数组。

我环顾四周,看到了一种脚本方式——让隐藏的输入成为 POST 源,并在提交时根据它们相邻的复选框更改值。但是 jquery 似乎不起作用——它总是提交一个 0 值(无论隐藏输入中的 value 属性是什么。

$(document).ready(function() {
  $('#frm').submit(function() {
    $('input[type="checkbox"]:checked').prev('.checkboxHandler').val(1);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<input type="hidden" class="checkboxHandler" name="isHeadOfFamily[]" value="0">
<td><input type="checkbox"></td>
<input type="hidden" class="checkboxHandler" name="isEmployed[]" value="0">
<td><input type="checkbox"></td>
<! and so on-->

【问题讨论】:

  • 您的代码有效
  • 不清楚您为什么将01 存储在隐藏的文本字段中。为什么不使用复选框的checked 属性状态?它提供相同的 truefalse 二进制响应。
  • 我需要将 0 和 1 的值存储在 sql 中。不幸的是,未选中的框不会发布任何内容,并且尝试在 PHP 上设置它会导致数组错位
  • @inNeedOfHelp 您可以迭代它们中的每一个并构建您自己的表单数据。为此使用三级运算符:例如isHeadOfHouse.push(($(el).prop("checked") ? 1 : 0));。请记住,如果您将二进制变量发送到 PHP 和 SQL,它会这样处理它。
  • @Twisty 它可以是像“true”这样的任何值,所以“1”同样有意义。无论如何,服务器都必须解析结果。为什么要讨论二进制值? isHeadOfHouse 是字段名,而不是客户端数组

标签: javascript html jquery checkbox


【解决方案1】:

您的代码有效

我们讨论后我会删除这个答案

我已将隐藏更改为文本并添加了 preventDefault 以显示它的工作原理

$(document).ready(function() {
  $('#frm').on("submit",function(e) {
    e.preventDefault(); //while testing
    $('input[type="checkbox"]:checked').prev('.checkboxHandler').val(1);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="frm">
<input type="text" class="checkboxHandler" name="isHeadOfFamily[]" value="0">
<td><input type="checkbox"></td>
<input type="text" class="checkboxHandler" name="isEmployed[]" value="0">
<td><input type="checkbox"></td>
<! and so on-->
<input type="submit"/>
</form>

【讨论】:

  • 奇怪。它仍然对我不起作用,他们仍然不会更改文本值。但是,我可以更改隐藏输入的 value 属性,它会成功提交给 SQL 到其中的任何内容。我的这些复选框的 PHP 与其他字段的其余部分相同,并且它们正确提交,所以我想知道这个问题的根源是什么。
  • 我不知道。也许将表单指向一个简单的表单回显脚本
【解决方案2】:

考虑以下示例。

$(function() {
  function getTableData(table) {
    var results = [];
    $("tbody > tr", table).each(function(i, row) {
      results.push({
        id: $(row).data("uid"),
        isHeadofHousehold: $("input", row).eq(0).prop("checked"),
        isEmployed: $("input", row).eq(1).prop("checked")
      });
    });
    return results;
  }
  $('#frm').on("submit", function(e) {
    e.preventDefault();
    var formData = getTableData($("#myTable"));
    console.log(formData);
  });
});
.checkbox {
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="frm">
  <table id="myTable">
    <thead>
      <tr>
        <th>Name</th>
        <th>Head of Household</th>
        <th>Employed</th>
      </tr>
    </thead>
    <tbody>
      <tr data-uid="1001">
        <td>Homer Simpson</td>
        <td class="checkbox"><input type="checkbox" name="isHeadOfFamily[]" checked></td>
        <td class="checkbox"><input type="checkbox" name="isEmployed[]" checked></td>
      </tr>
      <tr data-uid="1002">
        <td>Marge Simpson</td>
        <td class="checkbox"><input type="checkbox" name="isHeadOfFamily[]"></td>
        <td class="checkbox"><input type="checkbox" name="isEmployed[]"></td>
      </tr>
    </tbody>
  </table>
  <input type="submit" value="Save" />
</form>

你现在有:

[
  {
    "id": 1001,
    "isHeadofHousehold": true,
    "isEmployed": true
  },
  {
    "id": 1002,
    "isHeadofHousehold": false,
    "isEmployed": false
  }
]

然后您可以使用 AJAX 将此数据 POST 回 PHP,以便将更改保存到 SQL。如前所述,如果您愿意,可以将它们分别切换为10

更新

回到 OP 想要的方法,考虑以下。

$(function() {
  $("#frm").on("change", "input[type='checkbox']", function(event) {
    $(this).prev(".checkboxHandler").val($(this).prop("checked") ? 1 : 0);
  });
});
.checkbox {
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="frm">
  <table id="myTable">
    <thead>
      <tr>
        <th>Name</th>
        <th>Head of Household</th>
        <th>Employed</th>
      </tr>
    </thead>
    <tbody>
      <tr data-uid="1001">
        <td>Homer Simpson</td>
        <td class="checkbox">
          <input type="hidden" class="checkboxHandler" name="isHeadOfFamily[]" value="1" />
          <input type="checkbox" checked />
        </td>
        <td class="checkbox">
          <input type="hidden" class="checkboxHandler" name="isEmployed[]" value="1" />
          <input type="checkbox" checked />
        </td>
      </tr>
      <tr data-uid="1002">
        <td>Marge Simpson</td>
        <td class="checkbox">
          <input type="hidden" class="checkboxHandler" name="isHeadOfFamily[]" value="0" />
          <input type="checkbox" />
        </td>
        <td class="checkbox">
          <input type="hidden" class="checkboxHandler" name="isEmployed[]" value="0" />
          <input type="checkbox" />
        </td>
      </tr>
    </tbody>
  </table>
  <input type="submit" value="Save" />
</form>

这会在用户进行更改时更新隐藏文本框的值。

如果您坚持使用原始代码,请使用以下代码:

$('input[type="checkbox"]:checked').prevAll('.checkboxHandler').val(1);

强烈建议不要使用它,因为这是一种单向逻辑,如果用户在提交表单之前取消选中某个框,则不会捕获更改。

更新 2

根据此处评分最高的答案,您也可以这样做:

<td>
  <input type="hidden" name="isHeadOfFamily[]" value="0">
  <input type="checkbox" name="isHeadOfFamily[]" value="1">
</td>
<td>
  <input type="hidden" name="isEmployed[]" value="0">
  <input type="checkbox" name="isEmployed[]" value="1">
</td>

唯一需要注意的是,如果用户选中一个框,两个值都会被发送。因此,按照建议,如果未选中,请在提交时禁用隐藏。

$("#frm").submit(function(){
  $('input[type="checkbox"]:checked').prevAll().prop("disabled", true);
});

【讨论】:

  • 为什么不直接序列化表单?
  • @mplungjan 也可以。这完全取决于 OP 需要将什么发送回服务器或数据在 HTML 中的呈现方式。
  • 但实际上他现有的代码应该可以工作,没有这一切,所以他需要看看为什么它不工作
  • @mplungjan 我同意 OP 的现有代码应该可以工作。我认为它可能需要迭代每个元素,因此.prev() 存在适当的关系来识别元素。如果有 7 个“行”,原始选择器将有多达 7 个潜在元素。 要选择所有前面的兄弟元素,而不仅仅是前面的相邻兄弟元素,请使用.prevAll() 方法。
  • @mplungjan 我已经更新了我的答案以反映更多选项。
猜你喜欢
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 2021-08-28
  • 1970-01-01
  • 2020-08-05
  • 2021-04-04
相关资源
最近更新 更多