Javascript jQuery-serializeArray()未获取选中复选框的值
我有一个复选框的形式,作为一个标志 为了做到这一点,我添加了一个隐藏的输入元素,这样,如果没有选中复选框,仍然会保存一些内容Javascript jQuery-serializeArray()未获取选中复选框的值,javascript,jquery,html,checkbox,Javascript,Jquery,Html,Checkbox,我有一个复选框的形式,作为一个标志 为了做到这一点,我添加了一个隐藏的输入元素,这样,如果没有选中复选框,仍然会保存一些内容 <form action=""> ... <input type="hidden" name="foo" value="no" /> <input type="checkbox" name="foo" value="yes"> ... </form> serializeArr
<form action="">
...
<input type="hidden" name="foo" value="no" />
<input type="checkbox" name="foo" value="yes">
...
</form>
serializeArray()不应该模拟浏览器行为吗?如果是这样,如果选中复选框,它不应该返回“是”吗
简而言之,我使用的是jQuery v1.10.2:否。serializeArray方法仅在选中复选框的情况下返回复选框。因此,只要它不受控制,它就会忽略它。 不过,如果您选中了它,它将直接返回您输入的值
查看演示。在具有相同名称的多个输入的表单上使用
serializeArray
为每个元素返回多个对象(如果选中)。这意味着以下HTML将返回以下对象。因此,有问题的数据是存在的,并且是可用的。因此,我假设您正在尝试将数据操作到1个对象中,或者将其发布到一个服务器,该服务器只考虑该键的第一个值中的数据。您只需确保任何复选框
元素优先
返回的对象:
[
{
name:"foo",
value:"no"
},
{
name:"foo2",
value:"no"
},
{
name:"foo2",
value:"yes"
}
]
HTML:
另一种方法是去掉隐藏字段,在提交表单之前,检查每个未选中的复选框,并检查serializeArray
中是否有同名数据。如果不是,只需将其作为关闭添加到那里即可
$('#submit').on('click', function(){
var arr = $('form').serializeArray(),
names = (function(){
var n = [],
l = arr.length - 1;
for(; l>=0; l--){
n.push(arr[l].name);
}
return n;
})();
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, names) === -1){
arr.push({name: this.name, value: 'off'});
}
});
console.log(arr);
});
对多个字段使用相同的名称充其量是有问题的,前端系统或后端系统没有标准化的处理方法
使用相同名称的唯一原因是,如果您试图传递某种默认值,就像下面的情况一样,您正在执行简单的是/否操作
要模拟浏览器,您需要的是serialize
方法,而不是serializeArray
我将表单添加到一个页面--从我的控制台:
JSON.stringify(f.serializeArray());
"[{"name":"foo","value":"no"}]"
无复选标记
JSON.stringify(f.serialize());
""foo=no""
选中标记
JSON.stringify(f.serialize());
""foo=yes&foo=no""
如果您的后端系统变得混乱,并且拾取了错误的值,请颠倒您的复选标记和隐藏元素的顺序。事实:jQueryserializeArray()
不包含未选中的复选框,我们可能需要将它们发送到服务器(不过对于收音机来说没有问题)
解决方案:创建新的序列化:
//1. `sel` any collection of `form` and/or `input`, `select`, `textarea`
//2. we assign value `1` if not exists to radios and checkboxes
// so that the server will receive `1` instead of `on` when checked
//3. we assign empty value to unchecked checkboxes
function serialize(sel) {
var arr,
tmp,
i,
$nodes = $(sel);
// 1. collect form controls
$nodes = $nodes.map(function(ndx){
var $n = $(this);
if($n.is('form'))
return $n.find('input, select, textarea').get();
return this;
});
// 2. replace empty values of <input>s of type=["checkbox"|"radio"] with 1
// or, we end up with "on" when checked
$nodes.each(function(ndx, el){
if ((el.nodeName.toUpperCase() == 'INPUT') && ((el.type.toUpperCase() == 'CHECKBOX') || (el.type.toUpperCase() == 'RADIO'))){
if((el.value === undefined) || (el.value == ''))
el.value = 1;
}
});
// 3. produce array of objects: {name: "field attribute name", value: "actual field value"}
arr = $nodes.serializeArray();
tmp = [];
for(i = 0; i < arr.length; i++)
tmp.push(arr[i].name);
// 4. include unchecked checkboxes
$nodes.filter('input[type="checkbox"]:not(:checked)').each(function(){
if(tmp.indexOf(this.name) < 0){
arr.push({name: this.name, value: ''});
}
});
return arr;
}
//1`sel`form`和/或`input`、`select`、`textarea`的任意集合
//2. 如果收音机和复选框不存在,我们将赋值“1”
//这样,当选中时,服务器将接收'1'而不是'on'
//3. 我们将空值指定给未选中的复选框
函数序列化(sel){
var arr,
tmp,
我
$nodes=$(sel);
//1.收集表单控件
$nodes=$nodes.map(函数(ndx){
var$n=$(本);
如果($n.is('form'))
返回$n.find('input,select,textarea').get();
归还这个;
});
//2.将=[“checkbox”|“radio”]类型的s的空值替换为1
//或者,我们在检查时以“开”结束
$nodes.每个(功能(ndx、el){
如果((el.nodeName.toUpperCase()=='INPUT')&((el.type.toUpperCase()=='CHECKBOX')| |(el.type.toUpperCase()=='RADIO')){
如果((el.value==未定义)| |(el.value=='')
el.value=1;
}
});
//3.生成对象数组:{name:“字段属性名称”,value:“实际字段值”}
arr=$nodes.serializeArray();
tmp=[];
对于(i=0;i
我们之所以将空字符串指定给未选中的复选框,是因为选中的复选框会将其值提交给服务器,服务器是用html设置的,可以是零
因此,空值表示未选中的复选框。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<form url="http://application.localdev/api/v1/register" method="post" id="formReg" accept-charset="utf-8">
<input type="email" placeholder="email" name="email"><br>
<input type="text" placeholder="firstname" name="firstname"><br>
<input type="text" placeholder="lastname" name="lastname"><br>
<input type="number" placeholder="zip_code" name="zip_code"><br>
<input type="checkbox" name="general" value="true"> general<br>
<input type="checkbox" name="marketing" value="true"> marketing<br>
<input type="checkbox" name="survey" value="true"> survey<br>
<button type="submit">save</button>
</form>
<script>
$(document).ready(function() {
$('#formReg').on('submit', function(e){
// validation code here
e.preventDefault();
var values = {};
$.each($('#formReg').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, values) === -1){
values[this.name] = $(this).prop('checked')
}
});
console.log(values)
});
});
</script>
一般性
营销
调查
拯救
$(文档).ready(函数(){
$('#formReg')。关于('submit',函数(e){
//这里是验证代码
e、 预防默认值();
var值={};
$.each($('#formReg').serializeArray(),函数(i,字段){
值[field.name]=field.value;
});
$('input[type=“checkbox”]:未(:选中)')。每个(函数(){
if($.inArray(this.name,value)=-1){
值[this.name]=$(this.prop('checked'))
}
});
console.log(值)
});
});
序列化数组
不会返回未选中的复选框。我尝试使用此方法而不是序列化数组
:
$('input, select, textarea').each(
function(index){
var input = $(this);
alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') +
'Value: ' + input.val());
}
);
请尝试为隐藏和复选框类型输入使用不同的名称。@dotnetstep相同的名称是故意的,因为这只是我要传递的一个值。因此,您是说serializeArray()无法决定提交这两个值中的哪一个,这与不带JS的普通表单post不同。当数据通过$.post('url')发送时,不会$('form').serializeArray();
它发送两个数据。我只是显示两个数据都被记录,并且两个数据都是通过ajax发布的。这意味着您的服务器没有正确读取数据,很可能是因为有两个元素具有相同的数据。我建议您从复选框中删除名称,更改后只更新隐藏的field以消除混淆。我将立即在我的答案中添加此代码。@arvinsim我已更新了答案的底部,以包含另一种方法,而不使用任何隐藏字段。这将真正有助于消除混淆
//1. `sel` any collection of `form` and/or `input`, `select`, `textarea`
//2. we assign value `1` if not exists to radios and checkboxes
// so that the server will receive `1` instead of `on` when checked
//3. we assign empty value to unchecked checkboxes
function serialize(sel) {
var arr,
tmp,
i,
$nodes = $(sel);
// 1. collect form controls
$nodes = $nodes.map(function(ndx){
var $n = $(this);
if($n.is('form'))
return $n.find('input, select, textarea').get();
return this;
});
// 2. replace empty values of <input>s of type=["checkbox"|"radio"] with 1
// or, we end up with "on" when checked
$nodes.each(function(ndx, el){
if ((el.nodeName.toUpperCase() == 'INPUT') && ((el.type.toUpperCase() == 'CHECKBOX') || (el.type.toUpperCase() == 'RADIO'))){
if((el.value === undefined) || (el.value == ''))
el.value = 1;
}
});
// 3. produce array of objects: {name: "field attribute name", value: "actual field value"}
arr = $nodes.serializeArray();
tmp = [];
for(i = 0; i < arr.length; i++)
tmp.push(arr[i].name);
// 4. include unchecked checkboxes
$nodes.filter('input[type="checkbox"]:not(:checked)').each(function(){
if(tmp.indexOf(this.name) < 0){
arr.push({name: this.name, value: ''});
}
});
return arr;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<form url="http://application.localdev/api/v1/register" method="post" id="formReg" accept-charset="utf-8">
<input type="email" placeholder="email" name="email"><br>
<input type="text" placeholder="firstname" name="firstname"><br>
<input type="text" placeholder="lastname" name="lastname"><br>
<input type="number" placeholder="zip_code" name="zip_code"><br>
<input type="checkbox" name="general" value="true"> general<br>
<input type="checkbox" name="marketing" value="true"> marketing<br>
<input type="checkbox" name="survey" value="true"> survey<br>
<button type="submit">save</button>
</form>
<script>
$(document).ready(function() {
$('#formReg').on('submit', function(e){
// validation code here
e.preventDefault();
var values = {};
$.each($('#formReg').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, values) === -1){
values[this.name] = $(this).prop('checked')
}
});
console.log(values)
});
});
</script>
$('input, select, textarea').each(
function(index){
var input = $(this);
alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') +
'Value: ' + input.val());
}
);