jQuery serializeArray 不包含单击的提交按钮

问题描述 投票:0回答:6

我有一个有两个按钮的表单。一个用于保存记录,另一个用于取消保存过程。我正在使用

rails.js
(对于那些不了解的人来说是一个常见的 AJAX/jQuery 插件) javascript 文件,它与 jQuery 一起使用,以进行不显眼的 javascript/ajax 调用。当我通过 ajax 发送表单数据时,我希望将我单击的按钮的名称和值与其余数据一起提交,以便我可以根据单击的按钮来决定要做什么。

rails.js
文件中的方法使用
.serializeArray()
向服务器发送表单数据。问题是这不包括我单击的按钮的名称/值对。 jQuery 的网站指出他们是故意这样做的(尽管我认为他们应该这样做):

.serializeArray()
方法使用成功控件的标准W3C规则来确定它应该包含哪些元素;特别是该元素不能被禁用并且必须包含名称属性。没有序列化提交按钮值,因为表单没有被序列化。使用按钮提交。”

他们怎么能假设表单不是使用按钮提交的?我认为这是没有意义的,也是一个错误的假设。

根据 W3C 规则,为提交表单而激活的按钮被视为成功的控件

既然 jQuery 的开发人员决定故意这样做,我是否可以假设还有另一种方法DOESN'T在序列化中排除激活的按钮?

编辑:这是我的表单的快速示例...

<!DOCTYPE html5>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
  $(document).ready(function() {
    $('#form').submit(function(e) {
      // put your breakpoint here to look at e
      var x = 0;
    });
  });
</script>
</head>
<body>
  <form id="form">
    <input name="name" type="text"><br/>
    <input name="commit" type="submit" value="Save"/>
    <input name="commit" type="submit" value="Cancel"/>
  </form>
</body>
jquery serialization w3c form-submit
6个回答
76
投票

是否有另一种方法排除序列化中激活的按钮?

没有,该行为基于

 
submit<form>
 事件 
,而不是按钮 ,例如在 JavaScript 中按 Enter 或调用
.submit()
。您在这里混合了 2 个概念,
.serialize()
.serializeArray()
可能与按钮单击有关,也可能没有 anything - 这只是一个单独的事件,它们没有连接。这些方法的级别更高:您可以出于任何原因随时序列化表单(或其子集)。

但是,您可以像从该按钮提交的普通表单一样添加提交名称/值对,例如,如果您从按钮提交:

$("#mySubmit").click(function() {
  var formData = $(this).closest('form').serializeArray();
  formData.push({ name: this.name, value: this.value });
  //now use formData, it includes the submit button
});

13
投票

这里有一个相当巧妙的方法来解决这个问题:

<form>
    <input type="hidden" name="stuff" value="">
    <button type="submit" onclick="this.form.stuff.value=this.value" value="reset">reset</button>
    <button type="submit" onclick="this.form.stuff.value=this.value" value="delete">delete</button>
</form>

8
投票

我使用以下代码片段,基本上添加了一个具有相同名称的隐藏元素

 var form = $("form");
 $(":submit",form).click(function(){
            if($(this).attr('name')) {
                $(form).append(
                    $("<input type='hidden'>").attr( { 
                        name: $(this).attr('name'), 
                        value: $(this).attr('value') })
                );
            }
        });

 $(form).submit(function(){
     console.log($(this).serializeArray());
 });

3
投票

此解决方案是“通用”的,因为它将处理您的所有输入提交,并在提交时将每个输入作为表单变量传递。

$(document).ready(function(){
    $('input:submit').each(function(){
        $(this).click(function(){
            var formData = $(this).closest('form').serializeArray();
            formData.push({ name: $(this).attr('name'), value: $(this).val() });
        });
    });
});

1
投票
    var form = button.closest('form');
    var serialize = form.serialize();

    if (button.attr('name') !== undefined) {
        serialize += '&'+button.attr('name')+'=';
    }

0
投票

有点晚了,但如果您不想将事件绑定到表单上的每个按钮,您可以包含以下内容:

$form.on('submit', function (e) {

    let formData = $(this).serializeArray();

    if (
        e.originalEvent
        && undefined !== e.originalEvent.submitter
        && undefined !== e.originalEvent.submitter.name
        && typeof e.originalEvent.submitter.name == "string"
        && e.originalEvent.submitter.name.length() >= 1
        && undefined !== e.originalEvent.submitter.value
    ) {
        formData.push({
            name: e.originalEvent.submitter.name,
            value: e.originalEvent.submitter.value,
        });
    }

    // ...

});

表单上任何具有至少 1 个字符长的字符串名称和定义值的提交按钮都将包含在

formData
对象数组中。

© www.soinside.com 2019 - 2024. All rights reserved.