jQuery - 通过单个请求提交多个表单,不使用Ajax

14
我有一个包含多个表单的页面。 我正在尝试提交其中一个表单(比如表单 A)(不是通过 Ajax,因为我需要在提交处理后加载结果页面),但是我需要另一个表单的内容(比如表单 B)与表单 A 一起提交,也就是将表单 A和B的内容一起作为一个请求提交到相同的URL,且如前所述,不作为Ajax请求。 提交应该是POST请求。而且,表单仅包含非文件上传字段(即input、select、textarea字段)。 我看到了一些建议,例如: Posting/submitting multiple forms in jQuerySubmitting two forms with a single button 但请注意,这些与我的情况不符,因为表单是在不同的请求中提交的,或者它们是通过 Ajax 提交的。 我想通过 (jQuery 的) serialize() 获取一个表单的内容,但如何将该字符串附加到由POST提交的表单? 或者您有其他想法来完成这个任务吗?
解决方案: 根据Sheepy的想法,我编写了以下代码。我还使用了来自以下链接的Pointy的答案: submit multiple forms to same page
//Arguments: "name"s of forms to submit.
//First argument: the form which according to its "action" all other forms will be submitted.
//Example: mergeForms("form1","form2","form3","form4")
function mergeForms() {
    var forms = [];
    $.each($.makeArray(arguments), function(index, value) {
        forms[index] = document.forms[value];
    });
    var targetForm = forms[0];
    $.each(forms, function(i, f) {
        if (i != 0) {
            $(f).find('input, select, textarea')
                .hide()
                .appendTo($(targetForm));
        }
    });
    $(targetForm).submit();
}
6个回答

8

在提交之前,您需要将表格2中的数据复制到表格1中。以下是基本操作:

$.each ( $('#form2 input, #form2 select, #form2 textarea').serializeArray(), function ( i, obj ) {
  $('<input type="hidden">').prop( obj ).appendTo( $('#form1') );
} );

此函数将从form2选择输入,获取它们当前的值,然后为每个输入创建一个新的隐藏输入,并将它们添加到form1中。根据您的情况,您可能需要先检查在form1中是否存在同名的输入。

这不会包括禁用的输入。 - Chris
是的@Chris。禁用的输入不会被正常提交,所以这是可以预期的。jQuery的serializeArray也尊重禁用属性,因此您需要在代码之前启用它们,并在之后重新禁用它们。 - Sheepy

3
一种将数据直接注入到POST请求中(而不是子字段中)的解决方案。
<form id="form1">
    <input ... />
    <input ... />
</form>

<form id="form2">
    <input ... />
    <input ... />
</form>

<form id="result" action="..." method="POST" onsubmit="merge(); return true;">
    <input type="submit" />
</form>


<script type="text/javascript">
    function merge() {
        $result = $("#result");
        $("#form1 input, #form2 input, #form1 select, #form2 select, #form1 textarea, #form2 textarea").each(function() {
            $result.append("<input type='hidden' name='"+$(this).attr('name')+"' value='"+$(this).val()+"' />");
        });
    }
</script>

2
您一次只能提交一个请求,否则页面将重新加载,除非您使用 AJAX。另外一个选项是创建一个脚本来连接您两个表单的序列化数据 - 但到那时,为什么不直接使用一个大表单呢?
提示:关于如何合并两个表单,第二个链接中的答案提供了示例。

根据情况,用户可能只想提交表单B;或者提交表单A(这种情况下也应该提交表单B)。 - rapt
在我的情况下,我有一个“搜索”表单和一个“搜索过滤器”表单。它们在本质上是相互关联的,但在用户界面中分别显示,但通过JavaScript组合它们的值可能比尝试找出布局以使它们都显示而不干扰页面可能具有的任何其他表单更容易... - James Alday

1

表单 A:

<form method="post" action="next.html" onsubmit="this.formbVal.value = $('#formb').serialize(); return true;">
    <input type="hidden" name="formbVal" value="" />
    <input type="submit">
</form>

表格 B:

<form id="formb" method="post" action="#" onsubmit="return false;">
</form>

问题在于我得到整个表单B作为一个新值。但是服务器上的代码期望与表单B匹配的特定值列表(有时提交表单B时没有任何其他表单)。我可以继续在服务器上分析formVal并将其拆分,但这不够优雅。让JavaScript以可接受的格式发送表单。 - rapt

0

我发现你的解决方案会将表单复制到另一个不可见的表单中,但问题在于原始表单将被清除,因此无法编辑原始表单(例如,在表单验证错误后)。

为了解决这个问题,我尝试在将元素附加到不可见表单之前克隆它们。我像这样编辑了你的代码:

//Arguments: "name"s of forms to submit.
//First argument: the form which according to its "action" all other forms will be submitted.
//Example: mergeForms("form1","form2","form3","form4")    
function mergeForms() {
        var forms = [];
        $.each($.makeArray(arguments), function(index, value) {
            forms[index] = document.forms[value];
        });
        var targetForm = forms[0];
        $.each(forms, function(i, f) {
            if (i != 0) {
                $(f).find('input, select, textarea')
                    .clone()
                    .hide()
                    .appendTo($(targetForm));
            }
        });

不幸的是,它现在无法复制选择元素中选定的值。

希望有人能帮助我改进这个脚本。


-1

你可以像这样做一些事情

$('#SubmitBtn).click(function () {
        $("#formId").attr("action", "http://www.YourSite.com/");
        $("#formId").attr("method", "post");
        $("#formId").attr("target","_blank");
        $('#formId').submit();
    });

这将在新窗口中提交表单到http://www.YourSite.com/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接