jQuery序列化不注册checkbox
我使用jQuery.serialize来检索表单中的所有数据字段。
我的问题是,它没有检索checkbox没有选中。
它包括:
<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" checked="checked" />
但不是这个
<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" />
我怎样才能得到未检查checkbox的“值”?
jQuery serialize
紧密模仿标准forms在浏览器被序列化之前被附加到请求中的查询string或POST主体。 未勾选的checkbox不包含在浏览器中,这很有意义,因为它们具有布尔状态 – 它们可以由用户select(包含)或者不由用户select(不包括)。
如果你需要在序列化,你应该问自己“为什么?为什么不检查数据中的存在?”。
请记住,如果JavaScript序列化表单数据的方式与浏览器的行为方式不同,那么您将消除表单中任何优雅降级的机会。 如果您仍然需要这样做,只需使用带有是/否的<select>
框作为选项。 至less这样,禁用了JS的用户就不会离开你的网站,而且你也不会违背HTML规范中定义的行为。
<select id="event_allDay" name="event_allDay"> <option value="0" selected>No</option> <option value="1">Yes</option> </select>
我曾经在过去的一些网站上看到过这种做法 ,总是认为自己“为什么不使用checkbox” ?
为了build立在azatoth的天才答案,我已经稍微扩展了我的情况:
/* Get input values from form */ values = jQuery("#myform").serializeArray(); /* Because serializeArray() ignores unset checkboxes and radio buttons: */ values = values.concat( jQuery('#myform input[type=checkbox]:not(:checked)').map( function() { return {"name": this.name, "value": this.value} }).get() );
你不这样做,因为serialize是用来作为查询string的,在这种情况下,unchecked意味着它不在查询string中。
如果你真的想获得未经检查的checkbox的值,请使用:(未经testing偏离课程)
var arr_unchecked_values = $('input[type=checkbox]:not(:checked)').map(function(){return this.value}).get();
如果你想添加反序列化的checkbox到你的查询string中,把下面的代码添加到你的jquery提交函数中:
var moreinfo = ''; $('input[type=checkbox]').each(function() { if (!this.checked) { moreinfo += '&'+this.name+'=0'; } });
这是扩展“serializeArray”方法的另一个解决scheme(同时保留原始行为)。
//Store the reference to the original method:
var _serializeArray = $ ji.fn.serializeArray;
//Now extend it with newer "unchecked checkbox" functionality: $ji.fn.extend({ serializeArray: function () { //Important: Get the results as you normally would... var results = _serializeArray.call(this); //Now, find all the checkboxes and append their "checked" state to the results. this.find('input[type=checkbox]').each(function (id, item) { var $item = $ji(item); var item_value = $item.is(":checked") ? 1 : 0; var item_name = $item.attr('name'); var result_index = null; results.each(function (data, index) { if (data.name == item_name) { result_index = index; } }); if (result_index != null) { // FOUND replace previous value results[result_index].value = item_value; } else { // NO value has been found add new one results.push({name: item_name, value: item_value}); } }); return results; } });
这实际上会附加“true”或“false”布尔结果,但是如果您愿意,可以分别使用“1”和“0”,通过将值更改为value: $item.is(":checked") ? 1 : 0
value: $item.is(":checked") ? 1 : 0
。
用法
像往常一样,调用您的窗体上的方法: $form.serialize()
或$form.serializeArray()
。 会发生什么是serialize
使用serializeArray
无论如何,所以你得到正确的结果(尽pipe不同的格式)与你调用任何方法。
我在自己的系统中使用的一种技术,我相信这个技术是由Struts使用的,包括…
<input type="hidden" name="_fieldname" value="fieldvalue"/>
作为我的表单创build逻辑的一部分,紧挨着checkbox。
这使我能够重新构build在表单中提供哪些checkbox,但是没有被选中,用一点额外的逻辑来执行差异服务和检查,你有没有被选中的。 无论您使用HTML还是AJAX样式提交,提交内容也是一样的。
根据你使用服务器端的技术,你可能希望使用这个语法…
<input type="hidden" name="_fieldname[]" value="fieldvalue"/>
…可以很容易地把这些值作为一个列表。
使用非标准checkbox序列化的一个原因是在问题或当前答案中没有解决的是只反序列化(更改)在序列化数据中明确指定的字段 – 例如,当您使用jQuery序列化和反序列化/从一个cookie保存和加载prefererences。
Thomas Danemar对标准的serialize()
方法进行了修改,可以select使用checkboxesAsBools
选项: http : //tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/ – 这与上面通过@mydoghasworms列出了执行,还集成了标准的序列化。
我已经将它复制到Github,以防万一任何地方有任何改进: https : //gist.github.com/1572512
此外,“jquery.deserialize”插件现在可以正确反序列化checkboxesAsBools
序列化的checkbox值,并忽略序列化数据中未提及的checkbox: https : //github.com/itsadok/jquery.deserialize
jQuery序列化获取input的值属性。
现在如何获得checkbox和单选button的工作? 如果您设置checkbox的单击事件或单选button0或1,您将能够看到更改。
$( "#myform input[type='checkbox']" ).on( "click", function(){ if ($(this).prop('checked')){ $(this).attr('value', 1); } else { $(this).attr('value', 0); } }); values = $("#myform").serializeArray();
也当你想要设置checkbox与检查状态,例如PHP
<input type='checkbox' value="<?php echo $product['check']; ?>" checked="<?php echo $product['check']; ?>" />
var checkboxes = $('#myform').find('input[type="checkbox"]'); $.each( checkboxes, function( key, value ) { if (value.checked === false) { value.value = 0; } else { value.value = 1; } $(value).attr('type', 'hidden'); }); $('#myform').serialize();
使用Andybuild议的select字段不一定是用户体验的最佳select,因为它需要两次鼠标点击而不是一次。
而且,“select”在UI中使用的空间比checkbox要多得多。
Ash的答案是一个简单的解决scheme,但在数组字段的情况下不起作用。
在我的上下文中,我有一个可变长度的表单,它包含显示文本和checkbox字段混合的行:
<input type="checkbox" value="1" name="thisIsAChkArray[]"/> <input type="text" value="" name="thisIsATxtArray[]"/>
为了解码发布的数据,数组元素的顺序非常重要。 只是将未检查的项目附加到常规的Jquery序列化不会保留行元素的顺序。
这是一个基于Ash的答案提出的解决scheme:
(function($) { $.fn.serializeWithChkBox = function() { // perform a serialize form the non-checkbox fields var values = $(this).find('select') .add( $(this).find('input[type!=checkbox]') ) .serialize(); // add values for checked and unchecked checkboxes fields $(this).find('input[type=checkbox]').each(function() { var chkVal = $(this).is(':checked') ? $(this).val() : "0"; values += "&" + $(this).attr('name') + "=" + chkVal; }); return values; } })(jQuery);
诀窍是拦截表单post,并将checkbox更改为隐藏的input字段。
示例:简单提交
$('form').on("submit", function (e) { //find the checkboxes var $checkboxes = $(this).find('input[type=checkbox]'); //loop through the checkboxes and change to hidden fields $checkboxes.each(function() { if ($(this)[0].checked) { $(this).attr('type', 'hidden'); $(this).val(1); } else { $(this).attr('type', 'hidden'); $(this).val(0); } }); });
例如:AJAX
如果您通过ajax发布表单而不更新UI,则需要跳过更多的箍环。
$('form').on("submit", function (e) { e.preventDefault(); //clone the form, we don't want this to impact the ui var $form = $('form').clone(); //find the checkboxes var $checkboxes = $form.find('input[type=checkbox]'); //loop through the checkboxes and change to hidden fields $checkboxes.each(function() { if ($(this)[0].checked) { $(this).attr('type', 'hidden'); $(this).val(1); } else { $(this).attr('type', 'hidden'); $(this).val(0); } }); $.post("/your/path", $form.serialize());
我有一个类似的问题,以下允许我收集所有表单input值和选中/取消选中checkbox。
var serialized = this.$('#myform input').map(function() { return { name: this.name, id: this.id, value: this.checked ? "checked" : "false" }; });
有时未检查意味着其他值,例如检查可能意味着是未选中否或0,1等,这取决于你想给的意义..所以可能是另一种状态,除了“未经检查意味着它不在查询string中”
“这样可以更容易地将信息存储在数据库中,因为那么从Serialize中的字段数量将等于表中的字段数量,现在我必须控制哪些数据丢失了”,对了,这也是我的问题。 ..所以看来我必须检查这个不存在的价值….
但也许这可能是一个解决scheme? http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/
只需添加一个隐藏的input
<input type="hidden" name="your_specific_name">
不需要价值,我testing了这个为我工作
你可以用jQuery序列化来获得input值
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input type="checkbox" id="event_allDay" name="event_allDay" checked="checked" onchange="isChecked(this)" value="" /> <script> function isChecked(element) { $(element).val($(element).is(':checked').toString()); } isChecked('#event_allDay'); </script>
这个例子假设你想通过serialize
而不是serializeArray
来发布一个表单,而一个未经检查的checkbox意味着false
:
var form = $(formSelector); var postData = form.serialize(); var checkBoxData = form.find('input[type=checkbox]:not(:checked)').map(function () { return encodeURIComponent(this.name) + '=' + false; }).get().join('&'); if (checkBoxData) { postData += "&" + checkBoxData; } $.post(action, postData);
这将使用他们的选中状态将你的表单checkbox值设置为布尔值。
var form = $('#myForm'); var data = form.serializeObject(); $('#myForm input[type=checkbox]').each(function() { data[this.name] = this.checked; });
我们使用的框架会创build两个具有相同名称的input,这会在序列化表单时导致意外的行为。 我会得到每个checkbox值分析为一个双元素数组与string值。 根据您如何映射数据服务器端,您可能会得到意想不到的结果。
尝试这个:
$(':input [type =“checkbox”]:checked')。map(function(){return this.value})。get();
我发布了适合我的解决scheme!
var form = $('#checkboxList input[type="checkbox"]').map(function() { return { name: this.name, value: this.checked ? this.value : "false" }; }).get(); var data = JSON.stringify(form); data value is : "[{"name":"cb1","value":"false"},{"name":"cb2","value":"true"},{"name":"cb3","value":"false"},{"name":"cb4","value":"true"}]"