jQuery在提交时设置每个勾选复选框的每个前一个兄弟的值

Posted

技术标签:

【中文标题】jQuery在提交时设置每个勾选复选框的每个前一个兄弟的值【英文标题】:jQuery set value of each previous sibling of each ticked checkbox upon submit 【发布时间】: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 是字段名,而不是客户端数组 【参考方案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 我已经更新了我的答案以反映更多选项。

以上是关于jQuery在提交时设置每个勾选复选框的每个前一个兄弟的值的主要内容,如果未能解决你的问题,请参考以下文章

firefox(火狐)下 js中设置checkbox属性checked="checked"已有,但复选框却不显示勾选的原因

jQuery - Kendo UI 复选框控件

如何使用 jQuery 重新填充表单提交时隐藏的 CSV 字段

用户提交弹出窗体时发送多个ajax调用

如何提交未选中复选框的值

当复选框分配有 jQuery 时,勾选不再起作用