复选框输入是不是仅在选中后才发布数据?

Posted

技术标签:

【中文标题】复选框输入是不是仅在选中后才发布数据?【英文标题】:Do checkbox inputs only post data if they're checked?复选框输入是否仅在选中后才发布数据? 【发布时间】:2012-07-10 13:29:57 【问题描述】:

如果在提交表单时选中复选框输入值数据,浏览器是否是标准行为?

如果没有提供值数据,默认值是否总是“on”?

假设以上是正确的,所有浏览器的这种行为是否一致?

【问题讨论】:

【参考方案1】:

我有一个动态生成复选框的页面(表单),因此这些答案很有帮助。我的解决方案与这里的许多解决方案非常相似,但我不禁认为它更容易实现。

首先我把一个隐藏的输入框与我的复选框对齐,即

 <td><input class = "chkhide" type="hidden" name="delete_milestone[]" value="off"/><input type="checkbox" name="delete_milestone[]"   class="chk_milestone" ></td>

现在如果所有checkboxes 都未选中,则隐藏字段返回的值将全部关闭。

例如,这里有五个动态插入的复选框,POSTS 的形式有以下值:

  'delete_milestone' => 
array (size=7)
  0 => string 'off' (length=3)
  1 => string 'off' (length=3)
  2 => string 'off' (length=3)
  3 => string 'on' (length=2)
  4 => string 'off' (length=3)
  5 => string 'on' (length=2)
  6 => string 'off' (length=3)

这表明只有第 3 和第 4 个复选框是 onchecked

本质上,虚拟或隐藏输入字段只是表示一切都已关闭,除非在关闭索引下方有一个 “on”,然后在没有一行客户端的情况下为您提供所需的索引侧码。

.

【讨论】:

【参考方案2】:

html 中,每个 &lt;input /&gt; 元素都与一个(但不是唯一的)名称和值对相关联。仅当 &lt;input /&gt; 为“成功”时,此对才会在后续请求(在本例中为 POST 请求正文)中发送。

因此,如果您在 &lt;form&gt; DOM 中有这些输入:

<input type="text"     name="one"   value="foo"                        />
<input type="text"     name="two"   value="bar"    disabled="disabled" />
<input type="text"     name="three" value="first"                      />
<input type="text"     name="three" value="second"                     />

<input type="checkbox" name="four"  value="baz"                        />
<input type="checkbox" name="five"  value="baz"    checked="checked"   />
<input type="checkbox" name="six"   value="qux"    checked="checked" disabled="disabled" />
<input type="checkbox" name=""      value="seven"  checked="checked"   />

<input type="radio"    name="eight" value="corge"                      />
<input type="radio"    name="eight" value="grault" checked="checked"   />
<input type="radio"    name="eight" value="garply"                     />

将生成这些将提交给服务器的名称+值对:

one=foo
three=first
three=second
five=baz
eight=grault

注意:

twosix 被排除在外,因为它们设置了 disabled 属性。 three 被发送了两次,因为它有两个同名的有效输入。 four 未发送,因为它是不是 checkedcheckbox 尽管checkedsix,但未发送six,因为disabled 属性具有更高的优先级。 seven 没有发送name="" 属性,因此未提交。

关于您的问题:您可以看到未选中的复选框因此不会将其名称+值对发送到服务器 - 但其他具有相同名称的输入将与它一起发送。

像 ASP.NET MVC 这样的框架通过(偷偷地)将每个 checkbox 输入与呈现的 HTML 中的 hidden 输入配对来解决这个问题,如下所示:

@Html.CheckBoxFor( m => m.SomeBooleanProperty )

渲染:

<input type="checkbox" name="SomeBooleanProperty" value="true" />
<input type="hidden"   name="SomeBooleanProperty" value="false" />

如果用户没有选中该复选框,则将以下内容发送到服务器:

SomeBooleanProperty=false

如果用户确实选中了该复选框,那么两者都将被发送:

SomeBooleanProperty=true
SomeBooleanProperty=false

但是服务器将忽略=false 版本,因为它看到=true 版本,因此如果它没有看到=true,它可以确定该复选框已呈现并且用户没有检查它 - 如反对 SomeBooleanProperty 输入根本不被渲染。

【讨论】:

值得注意的是,如果您有多个字段,例如带有额外隐藏的文本框,那么后端将收到一个值数组。 如果您在输入名称的末尾使用[],它只会接收一个数组,默认行为是只提交具有该名称的最后一个元素,因此只要隐藏输入在之前复选框,它将起作用。 通过有两个同名的字段(隐藏字段+复选框字段),并选中复选框,帖子值是一个逗号分隔的值字符串,即。像“0,1” @beeglebug 您所描述的是 php 如何处理名称和值,[] 后缀不是 HTML 规范的一部分,浏览器不会对其进行特殊处理。如果没有[],PHP 将只允许访问单个值(最后一个值)而不是所有值。 使用隐藏属性 before 在我使用 GET 和 POST 和 PHP 测试过的所有浏览器中,该复选框都适用于我。当我将它放在复选框控件之后时,它总是呈现结果为假。【参考方案3】:

input type="hidden" name="is_main" value="0"

input type="checkbox" name="is_main" value="1"

所以您可以像我在应用程序中那样进行控制。 如果它检查则发送值 1 否则 0

【讨论】:

【参考方案4】:

以上答案都没有让我满意。 我发现最好的解决方案是在每个具有相同名称的复选框输入之前包含一个隐藏输入。

&lt;input type="hidden" name="foo[]" value="off"/&gt;

&lt;input type="checkbox" name="foo[]"/&gt;

然后在服务器端,使用一个小算法,您可以获得更像 HTML 应该提供的东西。

function checkboxHack(array $checkbox_input): array

    $foo = [];
    foreach($checkbox_input as $value) 
        if($value === 'on') 
            array_pop($foo);
        
        $foo[] = $value;
    
    return $foo;

这将是原始输入

array (
    0 => 'off',
    1 => 'on',
    2 => 'off',
    3 => 'off',
    4 => 'on',
    5 => 'off',
    6 => 'on',
),

函数会返回

array (
    0 => 'on',
    1 => 'off',
    2 => 'on',
    3 => 'on',
)  

【讨论】:

【参考方案5】:

在表单提交时不会发送未选中的复选框有同样的问题,我想出了另一个解决方案,而不是镜像复选框项目。

获取所有未选中的复选框

var checkboxQueryString;

$form.find ("input[type=\"checkbox\"]:not( \":checked\")" ).each(function( i, e ) 
  checkboxQueryString += "&" + $( e ).attr( "name" ) + "=N"
);

【讨论】:

【参考方案6】:

如果未选中复选框,则它不会影响表单提交时发送的数据。

HTML5 部分4.10.22.4 Constructing the form data set 描述了表单数据的构造方式:

如果满足以下任一条件,则跳过这些子步骤 对于这个元素: [...]

字段元素是一个输入元素,其类型 属性处于 Checkbox 状态,且选中状态为 false。

如果缺少value,则指定默认值on

否则,如果字段元素是类型属性处于复选框状态或单选按钮状态的输入元素,则运行这些进一步嵌套的子步骤:

如果字段元素具有指定的 value 属性,则令 value 为该属性的值;否则,让 value 为字符串“on”。

因此在表单数据构造过程中会跳过未选中的复选框。

HTML4 下需要类似的行为。所有兼容的浏览器都有这种行为是合理的。

【讨论】:

【参考方案7】:

我用这段代码解决了问题:

HTML 表单

<input type="checkbox" id="is-business" name="is-business" value="off" onclick="changeValueCheckbox(this)" >
<label for="is-business">Soy empresa</label>

以及通过改变复选框值形式的javascript函数:

//change value of checkbox element
function changeValueCheckbox(element)
   if(element.checked)
    element.value='on';
  else
    element.value='off';
  

服务器检查数据发布是“打开”还是“关闭”。我使用了playframework java

        final Map<String, String[]> data = request().body().asFormUrlEncoded();

        if (data.get("is-business")[0].equals('on')) 
            login.setType(new MasterValue(Login.BUSINESS_TYPE));
         else 
            login.setType(new MasterValue(Login.USER_TYPE));
        

【讨论】:

【参考方案8】:

当且仅当复选框被选中时,复选框才会发布值'on'。 Insted 捕捉复选框值,您可以使用隐藏输入

JS

var chk = $('input[type="checkbox"]');
    chk.each(function()
        var v = $(this).attr('checked') == 'checked'?1:0;
        $(this).after('<input type="hidden" name="'+$(this).attr('rel')+'" value="'+v+'" />');
    );

chk.change(function() 
        var v = $(this).is(':checked')?1:0;
        $(this).next('input[type="hidden"]').val(v);
    );

HTML

<label>Active</label><input rel="active" type="checkbox" />

【讨论】:

【参考方案9】:

就像 ASP.NET 变体一样,除了将具有相同名称的隐藏输入放在实际的复选框(同名)之前。只会发送最后一个值。这样,如果选中一个框,则发送其名称和值“on”,而如果未选中,则发送相应隐藏输入的名称以及您可能希望为其提供的任何值。最后,您将读取 $_POST 数组,其中包含所有选中和未选中的元素,“on”和“false”值,没有重复的键。易于在 PHP 中处理。

【讨论】:

【参考方案10】:

浏览器只发送复选框输入是标准行为吗 是否在表单提交时检查数据?

是的,因为否则就没有可靠的方法来确定复选框是否被实际选中(如果它改变了值,那么当你希望的值被选中时,可能会存在这种情况与那个相同它被交换到)。

如果没有提供值数据,默认值是否总是“on”?

其他答案确认“开”是默认设置。但是,如果您对该值不感兴趣,只需使用:

if (isset($_POST['the_checkbox']))
    // name="the_checkbox" is checked

【讨论】:

【参考方案11】:

来自 HTML 4 规范,它应该在几乎所有浏览器中保持一致:

http://www.w3.org/TR/html401/interact/forms.html#checkbox

复选框(和单选按钮)是可以切换的开/关开关 由用户。选中控制元素时,开关处于“打开”状态 属性已设置。提交表单时,仅“打开”复选框 控制可以成功。

成功的定义如下:

成功的控件对于提交是“有效的”。每一个成功的 控件将其控件名称与其当前值配对,作为 提交的表单数据集。必须定义成功的控件 在 FORM 元素中,并且必须有一个控件名称。

【讨论】:

【参考方案12】:

是的,标准行为是仅在选中复选框时才发送值。这通常意味着您需要有一种方法来记住您期望在服务器端使用哪些复选框,因为并非所有数据都来自表单。

默认值始终为“on”,这应该在浏览器之间保持一致。

这在W3C HTML 4 recommendation:

复选框(和单选按钮)是可以切换的开/关开关 由用户。选中控制元素时,开关处于“打开”状态 属性已设置。提交表单时,仅“打开”复选框 控制可以成功。

【讨论】:

不幸的是,这很痛苦,只有选中的复选框被发送到服务器,而不是未选中的复选框。如果您事先知道页面上有哪些复选框,那么在服务器端脚本上管理它们就没有问题。问题是当您事先不知道时 - 根据某些业务逻辑在页面上动态创建复选框。然后你必须制作技巧并为这些复选框使用并行隐藏输入字段并使用 JavaScript 来实现它们。 创建具有“允许不成功控件(即 type="checkbox")的一致性验证器的关键是将这些表单控件指定为transient。当它们不成功时,相应地动态更改您的 sanitizer 和验证器。 解决方法:使用 &lt;select&gt; 和两个选项 onoff :-) 建议使用隐藏输入携带复选框值。

以上是关于复选框输入是不是仅在选中后才发布数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何实现Jquery复选框选中全部/取消选中带有复选框的所有功能?

ios - 单元格表格视图内的视图位置仅在滚动后才会更改

Angular 反应复选框仅在第一次单击后正确切换

带按钮的多个复选框

仅在选中复选框时提交表单

用于检查输入是不是“选中”或未“选中”的复选框功能