【发布时间】:2010-12-21 00:53:47
【问题描述】:
我有很多默认选中的复选框。我的用户可能会取消选中一些(如果有的话)复选框并保留其余的选中状态。
有什么方法可以使表单 POST 的复选框未选中,而不是已选中的复选框?
【问题讨论】:
-
使用两个无线电输入怎么样?
我有很多默认选中的复选框。我的用户可能会取消选中一些(如果有的话)复选框并保留其余的选中状态。
有什么方法可以使表单 POST 的复选框未选中,而不是已选中的复选框?
【问题讨论】:
到目前为止,我最喜欢的解决方案是放置一个与可能未选中的复选框同名的隐藏输入。我认为它的工作原理是,如果未选中复选框,隐藏输入仍然成功并发送到服务器,但如果选中复选框,它将覆盖之前的隐藏输入。这样您就不必跟踪已发布数据中的哪些值预期来自复选框。
<form>
<input type='hidden' value='0' name='selfdestruct'>
<input type='checkbox' value='1' name='selfdestruct'>
</form>
【讨论】:
为具有不同 ID 的复选框添加隐藏输入:
<input id='testName' type='checkbox' value='Yes' name='testName'>
<input id='testNameHidden' type='hidden' value='No' name='testName'>
在提交表单之前,根据选中的条件禁用隐藏输入:
if(document.getElementById("testName").checked) {
document.getElementById('testNameHidden').disabled = true;
}
【讨论】:
checkbox 元素的底层设计很糟糕吗?它们是二进制控件,它们应该发送二进制值。
我使用原生 JavaScript 解决了这个问题:
<input type="hidden" name="checkboxName" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">
注意这两个输入元素之间不要有任何空格或换行符!
您可以使用this.previousSibling.previousSibling 获取“上层”元素。
使用 PHP,您可以检查命名隐藏字段的 0(未设置)或 1(设置)。
【讨论】:
<fieldset name='fs1'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> <fieldset name='fs2'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> * 假设那里有新行。他们似乎没有在迷你标记代码块中工作
previousElementSibling 代替previousSibling。支持nearly everywhere,它会忽略文本节点。
我个人最喜欢的是添加一个同名的隐藏字段,如果未选中复选框,将使用该字段。但解决方案并不像看起来那么简单。
如果添加此代码:
<form>
<input type='hidden' value='0' name='selfdestruct'>
<input type='checkbox' value='1' name='selfdestruct'>
</form>
浏览器不会真正关心你在这里做什么。浏览器会将这两个参数发送到服务器,服务器必须决定如何处理它们。
例如,PHP 将最后一个值作为要使用的值(参见:Authoritative position of duplicate HTTP GET query keys)
但我使用过的其他系统(基于 Java)却是这样做的——它们只为您提供第一个价值。 相反,.NET 会给你一个包含两个元素的数组
我会尝试使用 node.js、Python 和 Perl 进行测试。
【讨论】:
request.getParameterValues
您不需要为所有复选框创建隐藏字段,只需复制我的代码即可。
如果未选中,它将更改复选框的值 value 将分配 0 并且如果选中复选框,则将 value 分配给 1
$("form").submit(function () {
var this_master = $(this);
this_master.find('input[type="checkbox"]').each( function () {
var checkbox_this = $(this);
if( checkbox_this.is(":checked") == true ) {
checkbox_this.attr('value','1');
} else {
checkbox_this.prop('checked',true);
//DONT' ITS JUST CHECK THE CHECKBOX TO SUBMIT FORM DATA
checkbox_this.attr('value','0');
}
})
})
【讨论】:
一种常见的技术是在每个复选框中携带一个隐藏变量。
<input type="checkbox" name="mycheckbox" />
<input type="hidden" name="mycheckbox.hidden"/>
在服务器端,我们首先检测隐藏变量列表,对于每个隐藏变量,我们尝试查看表单数据中是否提交了相应的复选框条目。
服务器端算法可能如下所示:
for input in form data such that input.name endswith .hidden
checkboxName = input.name.rstrip('.hidden')
if chceckbName is not in form, user has unchecked this checkbox
以上内容并未完全回答问题,但提供了实现类似功能的另一种方法。
【讨论】:
我知道这个问题已经 3 年了,但我找到了一个我认为效果很好的解决方案。
您可以检查是否分配了 $_POST 变量并将其保存在变量中。
$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';
isset() 函数检查是否分配了 $_POST 变量。按逻辑,如果未分配,则不选中复选框。
【讨论】:
$('input[type=checkbox]').on("change",function(){
var target = $(this).parent().find('input[type=hidden]').val();
if(target == 0)
{
target = 1;
}
else
{
target = 0;
}
$(this).parent().find('input[type=hidden]').val(target);
});
<p>
<input type="checkbox" />
<input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
<input type="checkbox" />
<input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
<input type="checkbox" />
<input type="hidden" name="test_checkbox[]" value="0" />
</p>
如果您省略复选框的名称,则不会通过。 只有 test_checkbox 数组。
【讨论】:
您可以在表单的提交事件中执行一些 Javascript。这就是你所能做的,没有办法让浏览器自己做到这一点。这也意味着您的表单会因没有 Javascript 的用户而中断。
最好在服务器上知道有哪些复选框,这样您就可以推断出那些在已发布的表单值(PHP 中的$_POST)中没有被选中的复选框。
【讨论】:
$_REQUEST 是一个很好的做法,因为如果您的脚本同时支持这两种方法,它允许一些代码重用。
我实际上会做以下事情。
让我的隐藏输入字段与复选框输入同名
<input type="hidden" name="checkbox_name[]" value="0" />
<input type="checkbox" name="checkbox_name[]" value="1" />
然后当我发布时,我首先删除 $_POST 数组中拾取的重复值,然后显示每个唯一值。
$posted = array_unique($_POST['checkbox_name']);
foreach($posted as $value){
print $value;
}
我从remove duplicate values from array 的帖子中得到这个
【讨论】:
checkbox_name[],每个值都将输入到一个数组中,然后您可以拉取该数组。例如:$_POST['checkbox_name'][0] 等等,随着有多少字段具有相同名称的增加而增加。另一个例子是,如果你有三个名为field_name[] 的字段,你可以获得field_name 的第二个值,例如$_POST['field_name'][1]。如果您有多个同名字段,它的用途可能会非常惊人。
我也喜欢你只发布一个额外的输入字段的解决方案,使用 JavaScript 对我来说似乎有点 hacky。
根据您使用的后端将取决于哪个输入先行。
对于使用第一次出现的服务器后端 (JSP),您应该执行以下操作。
<input type="checkbox" value="1" name="checkbox_1"/>
<input type="hidden" value="0" name="checkbox_1"/>
对于使用最后一次出现的服务器后端(PHP、Rails),您应该执行以下操作。
<input type="hidden" value="0" name="checkbox_1"/>
<input type="checkbox" value="1" name="checkbox_1"/>
对于所有事件都存储在列表数据类型 ([],array) 中的服务器后端。 (Python / Zope)
您可以按照您喜欢的任何顺序发布,您只需要尝试使用checkbox 类型属性从输入中获取值。因此,如果复选框在隐藏元素之前,则列表的第一个索引,如果复选框在隐藏元素之后,则为最后一个索引。
对于所有事件都用逗号连接的服务器后端(ASP.NET / IIS)
您需要使用逗号作为分隔符来(拆分/分解)字符串以创建列表数据类型。 ([])
现在,如果复选框位于隐藏元素之前,您可以尝试获取列表的第一个索引,如果复选框位于隐藏元素之后,则获取最后一个索引。
【讨论】:
“我已经采用了服务器方法。似乎工作正常 - 谢谢。-reach4thelasers 2009 年 12 月 1 日 15:19” 我想向业主推荐它。正如所引用的:javascript解决方案取决于服务器处理程序的方式(我没有检查它)
如
if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";
【讨论】:
这里的大多数答案都需要使用 JavaScript 或重复输入控件。有时这需要完全在服务器端处理。
我相信解决这个常见问题的(预期的)关键是表单的提交输入控件。
要成功解释和处理复选框的未选中值,您需要了解以下内容:
通过检查表单是否已提交(为提交输入元素分配一个值),可以假定任何未选中的复选框值。
例如:
<form name="form" method="post">
<input name="value1" type="checkbox" value="1">Checkbox One<br/>
<input name="value2" type="checkbox" value="1" checked="checked">Checkbox Two<br/>
<input name="value3" type="checkbox" value="1">Checkbox Three<br/>
<input name="submit" type="submit" value="Submit">
</form>
使用 PHP 时,检测哪些复选框被勾选是相当简单的。
<?php
$checkboxNames = array('value1', 'value2', 'value3');
// Persisted (previous) checkbox state may be loaded
// from storage, such as the user's session or a database.
$checkboxesThatAreChecked = array();
// Only process if the form was actually submitted.
// This provides an opportunity to update the user's
// session data, or to persist the new state of the data.
if (!empty($_POST['submit'])) {
foreach ($checkboxNames as $checkboxName) {
if (!empty($_POST[$checkboxName])) {
$checkboxesThatAreChecked[] = $checkboxName;
}
}
// The new state of the checkboxes can be persisted
// in session or database by inspecting the values
// in $checkboxesThatAreChecked.
print_r($checkboxesThatAreChecked);
}
?>
可以在每次页面加载时加载初始数据,但只有在提交表单后才能修改。由于复选框的名称是预先知道的,因此可以单独遍历和检查它们,因此没有它们的单个值表示它们没有被检查。
【讨论】:
我首先尝试了 Sam 的版本。 好主意,但它会导致表单中有多个具有相同名称的元素。如果您使用任何基于名称查找元素的 javascript,它现在将返回一个元素数组。
我已经在 PHP 中解决了 Shailesh 的想法,它对我有用。 这是我的代码:
/* 如果存在原始字段,则删除“.hidden”字段,否则使用“.hidden”值。 */ foreach ($_POST['frmmain'] as $field_name => $value) { // 只查看以 '.hidden' 结尾的元素 if ( !substr($field_name, -strlen('.hidden')) ) { 休息; } // 获取不带 '.hidden' 的名称 $real_name = substr($key, strlen($field_name) - strlen('.hidden')); // 如果原件不存在,则使用“.hidden”中的值创建一个“假”原件字段 if ( !array_key_exists( $real_name, $POST_copy ) ) { $_POST[$real_name] = $value; } // 删除 '.hidden' 元素 未设置($_POST[$field_name]); }【讨论】:
我使用这个 jQuery 块,它将在提交时为每个未选中的复选框添加一个隐藏的输入。它将保证您每次都获得为每个复选框提交的值,而不会弄乱您的标记,也不会冒着忘记在稍后添加的复选框上执行此操作的风险。它也与您使用的任何后端堆栈(PHP、Ruby 等)无关。
// Add an event listener on #form's submit action...
$("#form").submit(
function() {
// For each unchecked checkbox on the form...
$(this).find($("input:checkbox:not(:checked)")).each(
// Create a hidden field with the same name as the checkbox and a value of 0
// You could just as easily use "off", "false", or whatever you want to get
// when the checkbox is empty.
function(index) {
var input = $('<input />');
input.attr('type', 'hidden');
input.attr('name', $(this).attr("name")); // Same name as the checkbox
input.attr('value', "0"); // or 'off', 'false', 'no', whatever
// append it to the form the checkbox is in just as it's being submitted
var form = $(this)[0].form;
$(form).append(input);
} // end function inside each()
); // end each() argument list
return true; // Don't abort the form submit
} // end function inside submit()
); // end submit() argument list
【讨论】:
还可以拦截form.submit事件,在提交前反查
$('form').submit(function(event){
$('input[type=checkbox]').prop('checked', function(index, value){
return !value;
});
});
【讨论】:
$('form').submit(function () {
$(this).find('input[type="checkbox"]').each( function () {
var checkbox = $(this);
if( checkbox.is(':checked')) {
checkbox.attr('value','1');
} else {
checkbox.after().append(checkbox.clone().attr({type:'hidden', value:0}));
checkbox.prop('disabled', true);
}
})
});
【讨论】:
我看到这个问题很老而且有很多答案,但无论如何我都会给我一分钱。 正如一些人所指出的,我的投票是针对表单的“提交”事件的 javascript 解决方案。无需加倍输入(特别是如果您的名称和属性长且 php 代码与 html 混合),无需服务器端麻烦(这需要知道所有字段名称并一一检查),只需获取所有未检查的项目,为它们分配一个 0 值(或任何您需要指示“未检查”状态的值),然后将它们的属性“已检查”更改为 true
$('form').submit(function(e){
var b = $("input:checkbox:not(:checked)");
$(b).each(function () {
$(this).val(0); //Set whatever value you need for 'not checked'
$(this).attr("checked", true);
});
return true;
});
这样你就会有一个像这样的 $_POST 数组:
Array
(
[field1] => 1
[field2] => 0
)
【讨论】:
我所做的有点不同。首先,我更改了所有未选中复选框的值。为“0”,然后将它们全部选中,这样就会提交值。
function checkboxvalues(){
$("#checkbox-container input:checkbox").each(function({
if($(this).prop("checked")!=true){
$(this).val("0");
$(this).prop("checked", true);
}
});
}
【讨论】:
我更喜欢整理 $_POST
if (!$_POST['checkboxname']) !$_POST['checkboxname'] = 0;
注意,如果 POST 没有 'checkboxname' 值,则它没有被选中,因此,分配一个值。
您可以创建一个包含您的 ckeckbox 值的数组并创建一个函数来检查值是否存在,如果不存在,它会记住未选中的值,您可以分配一个值
【讨论】:
如果您使用 jquery,最简单的解决方案是“虚拟”复选框加上隐藏输入:
<input id="id" type="hidden" name="name" value="1/0">
<input onchange="$('#id').val(this.checked?1:0)" type="checkbox" id="dummy-id"
name="dummy-name" value="1/0" checked="checked/blank">
将值设置为当前的 1/0 值以用于 BOTH 输入,如果 1 则选中=选中。输入字段(活动)现在将始终显示为 1 或 0。还可以单击复选框更多在提交之前不止一次,并且仍然可以正常工作。
【讨论】:
Ajax 操作示例 is(':checked') 使用 jQuery 而不是 .val();
var params = {
books: $('input#users').is(':checked'),
news : $('input#news').is(':checked'),
magazine : $('input#magazine').is(':checked')
};
参数将在 TRUE 或 FALSE 中获得值..
【讨论】:
复选框通常将存储在数据库中的二进制数据表示为 Yes/No、Y/N 或 1/0 值。 HTML复选框确实只有在选中复选框时,才能向服务器发送值!这意味着其他站点上的服务器脚本必须提前知道网页上所有可能的复选框,以便能够存储正(选中)或负(未选中)值。实际上只有负值是问题(当用户取消选中先前(预)检查的值时 - 如果服务器事先不知道应该发送此名称,那么当什么都不发送时服务器如何知道这一点)。如果您有一个动态创建 UPDATE 脚本的服务器端脚本,则会出现问题,因为您不知道应该接收哪些所有复选框才能为选中的复选框设置 Y 值,为未选中(未收到)的复选框设置 N 值。
由于我将值“Y”和“N”存储在我的数据库中并通过页面上选中和未选中的复选框来表示它们,因此我为每个值(复选框)添加了带有“Y”和“N”值的隐藏字段,然后使用复选框只是为了视觉表现,使用简单的 JavaScript 函数 check() 根据选择设置 if 的值。
<input type="hidden" id="N1" name="N1" value="Y" />
<input type="checkbox"<?php if($N1==='Y') echo ' checked="checked"'; ?> onclick="check(this);" />
<label for="N1">Checkbox #1</label>
使用一个 JavaScript onclick 监听器并为我网页上的每个复选框调用函数 check():
function check(me)
{
if(me.checked)
{
me.previousSibling.previousSibling.value='Y';
}
else
{
me.previousSibling.previousSibling.value='N';
}
}
这种方式'Y'或'N'值总是发送到服务器端脚本,它知道应该更新哪些字段,并且不需要将复选框“on”值转换为“Y”或未收到复选框进入'N'。
注意:空格或新行也是兄弟,所以这里我需要 .previousSibling.previousSibling.value。如果之间没有空格,则只有 .previousSibling.value
您不需要像以前那样显式添加 onclick 侦听器,您可以使用 jQuery 库动态添加带有功能的点击侦听器来更改页面中所有复选框的值:
$('input[type=checkbox]').click(function()
{
if(this.checked)
{
$(this).prev().val('Y');
}
else
{
$(this).prev().val('N');
}
});
【讨论】:
@cpburnz 说对了,但是代码太多了,下面是同样的想法,使用更少的代码:
JS:
// jQuery OnLoad
$(function(){
// Listen to input type checkbox on change event
$("input[type=checkbox]").change(function(){
$(this).parent().find('input[type=hidden]').val((this.checked)?1:0);
});
});
HTML(注意使用数组名称的字段名称):
<div>
<input type="checkbox" checked="checked">
<input type="hidden" name="field_name[34]" value="1"/>
</div>
<div>
<input type="checkbox">
<input type="hidden" name="field_name[35]" value="0"/>
</div>
<div>
对于 PHP:
<div>
<input type="checkbox"<?=($boolean)?' checked="checked"':''?>>
<input type="hidden" name="field_name[<?=$item_id?>]" value="<?=($boolean)?1:0?>"/>
</div>
【讨论】:
所有答案都很好,但是如果您在同名表单中有多个复选框,并且您想发布每个复选框的状态。然后我通过放置一个带有复选框的隐藏字段(与我想要的名称相关的名称)解决了这个问题。
<input type="hidden" class="checkbox_handler" name="is_admin[]" value="0" />
<input type="checkbox" name="is_admin_ck[]" value="1" />
然后通过下面的jquery代码控制checkbox的变化状态:
$(documen).on("change", "input[type='checkbox']", function() {
var checkbox_val = ( this.checked ) ? 1 : 0;
$(this).siblings('input.checkbox_handler').val(checkbox_val);
});
现在在更改任何复选框时,它将更改相关隐藏字段的值。在服务器上,您只能查看隐藏字段而不是复选框。
希望这能帮助遇到此类问题的人。加油:)
【讨论】:
您可以在提交表单之前添加隐藏元素。
$('form').submit(function() {
$(this).find('input[type=checkbox]').each(function (i, el) {
if(!el.checked) {
var hidden_el = $(el).clone();
hidden_el[0].checked = true;
hidden_el[0].value = '0';
hidden_el[0].type = 'hidden'
hidden_el.insertAfter($(el));
}
})
});
【讨论】:
复选框的问题是,如果它们没有被选中,那么它们就不会与您的表单一起发布。如果您选中一个复选框并发布一个表单,您将在 $_POST 变量中获得复选框的值,您可以使用它来处理表单,如果未选中它,则不会向 $_POST 变量添加任何值。
在 PHP 中,您通常可以通过对复选框元素进行 isset() 检查来解决此问题。如果您期望的元素未在 $_POST 变量中设置,那么我们知道该复选框未选中并且该值可能为 false。
if(!isset($_POST['checkbox1']))
{
$checkboxValue = false;
} else {
$checkboxValue = $_POST['checkbox1'];
}
但是,如果您创建了一个动态表单,那么您将不会总是知道复选框的名称属性,如果您不知道复选框的名称,那么您就不能使用 isset 函数来检查它是否有与 $_POST 变量一起发送。
【讨论】:
function SubmitCheckBox(obj) {
obj.value = obj.checked ? "on" : "off";
obj.checked = true;
return obj.form.submit();
}
<input type=checkbox name="foo" onChange="return SubmitCheckBox(this);">
【讨论】:
如果您想提交一组复选框值(包括未选中的项目),那么您可以尝试这样的操作:
<form>
<input type="hidden" value="0" name="your_checkbox_array[]"><input type="checkbox">Dog
<input type="hidden" value="0" name="your_checkbox_array[]"><input type="checkbox">Cat
</form>
$('form').submit(function(){
$('input[type="checkbox"]:checked').prev().val(1);
});
【讨论】:
一线解决方案:
$option1ChkBox = array_key_exists('chkBoxName', $_POST) ? true : false;
【讨论】: