ChatGPT解决这个技术问题 Extra ChatGPT

jQuery serializeArray 不包括被点击的提交按钮

我有一个有两个按钮的表单。一个用于保存记录,另一个用于取消保存过程。我正在使用 rails.js (一个常见的 AJAX/jQuery 插件,供那些不知道的人使用) javascript 文件,它与 jQuery 一起用于不显眼的 javascript/ajax 调用。当我通过 ajax 发送表单数据时,我希望我单击的按钮的名称和值与其余数据一起提交,以便我可以根据单击的按钮决定要做什么。

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

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

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

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

由于 jQuery 的开发人员已经决定故意这样做,我可以假设还有另一种方法不排除序列化中的激活按钮吗?

编辑:这是我的表单可能是什么样子的快速示例......

<!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>
对于其他发现此问题的人,<button> 标记也存在同样的问题。

L
Luke

[有]另一种不排除序列化中激活按钮的方法吗?

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

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

$("#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
});

@Nick,感谢您的快速回复。我将编辑 rails.js(并可能提交一个补丁)来完成这项工作。我会试一试。
@DJTripleThreat - 我对他们的代码不太熟悉,是否可以在外部替换事件处理程序?如果你能发布它,我会看看
@Nick - 查看 gh: github.com/rails/jquery-ujs/blob/master/src/rails.js 上的文件。查看第 34 行和第 76 行的处理程序。有没有办法找出在 .submit(function(e){}) 传递的 event 对象中单击了哪个按钮?
@DJTripleThreat - 您可以使用 e.target 并将其传递给 callRemote 可能是最简单的路线,只需让它接受一个事件参数,在里面使用 e.target,您可以检查 if($(e.target).is(":submit"))...
嗯,当来自 .submit 时,e.target 始终是 HTMLFormElement。我没有看到任何决定单击哪个按钮的内容。 Chrome 的开发者工具窗口显示 e 有一个名为 button 的变量,但它始终未定义。
K
KyleMit

这是解决此问题的一种相当巧妙的方法:

<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>

d
digitalPBK

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

 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());
 });

R
Robert Waddell

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

$(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() });
        });
    });
});

您不需要 each 调用 - 只需直接在代表所有输入元素的 jquery 对象上调用 click
k
kjdion84
    var form = button.closest('form');
    var serialize = form.serialize();

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