【问题标题】:Merge values from two forms on submit在提交时合并来自两个表单的值
【发布时间】:2010-02-26 10:50:55
【问题描述】:

我在一个 html 页面上有两个表单。使用 jQuery,是否可以在提交第一个表单时将两个表单中的数据放入 POST 数据中?

【问题讨论】:

    标签: jquery html


    【解决方案1】:

    jQuery 序列化支持多个表单元素,所以可以这样做:

    $('#form1, #form2').serialize();
    

    对于你的情况,你可以这样做:

    $('#form1').submit(function() {
        var action = $(this).attr('action');
        if (!EntryCheck()) return false;
        $.ajax({
            url  : action,
            type : 'POST',
            data : $('#form1, #form2').serialize(),
            success : function() {
                window.location.replace(action);
            }
        });
        return false;
    });
    

    【讨论】:

    • 我已经有 onsubmit="return EntryCheck()" 用于 form1。其中EntryCheck() 是一个验证函数。这会导致问题吗?
    • 这对我仍然不起作用。它不会带我进入操作页面
    • @Brian - 我已经编辑了我的答案。请注意,它将调用您的操作位置两次——一次在 POST 方法中发送数据,一次在 GET 方法中去那里。您可以检查执行了哪种请求方法并采取相应措施。
    【解决方案2】:

    一种方法是在数据验证检查成功后将 form2 的所有输入复制到 form1 中。这假设您没有进行 AJAX 提交。

    // new onsubmit function for form1
    function form1_onsubmit()
    {
        if (!EntryCheck()) return false; 
    
        $('#form2 :input').not(':submit').clone().hide().appendTo('#form1');
    
        return true;
    }
    

    如果您想满足两次点击提交,可能是因为服务器提交失败,我们需要在复制新输入之前删除所有复制的输入。

    // new onsubmit function for form1
    function form1_onsubmit()
    {
        $('#form1 :input[isacopy]').remove();
    
        if (!EntryCheck()) return false; 
    
        $('#form2 :input').not(':submit').clone().hide().attr('isacopy','y').appendTo('#form1');
    
        return true;
    }
    

    【讨论】:

    • 这几乎奏效了,然后我注意到在clone() 的文档中:“出于性能原因,某些表单元素的动态状态(例如,输入文本区域的用户数据和用户选择select) 不会复制到克隆的元素。当克隆输入元素时,元素的动态状态(例如,输入文本输入的用户数据和用户对复选框所做的选择)会保留在克隆的元素中元素。”
    • 追加两个序列化.....$("form1").add($("form2")).serializeArray().
    【解决方案3】:

    Lachlan Roche 的解决方案只复制元素,而不复制值。这也将处理值,并可用于处理任一表单提交:

    <script type="text/javascript">
      var submitter = {
        combine: function (form1, form2) {
          $('#' + form1 + ' :input[isacopy]').remove();
          $('#' + form2 + ' :input').not(':submit').not('textarea').not('select').each(function() { $(this).attr('value', $(this).val()); });
          $('#' + form2 + ' textarea').each(function() { $(this).text($(this).val()); });
          $('#' + form2 + ' select').each(function() { $('option[value!="' + $(this).val() + '"]', this).remove(); $('option[value="' + $(this).val() + '"]', this).attr('selected', 'selected'); });
          $('#' + form2 + ' :input').not(':submit').clone().hide().attr('isacopy','y').appendTo('#' + form1);
          return true;
        }
      };
    </script>
    

    您的表单标签看起来像(注意传递给函数的表单 ID 已切换):

    <form name="my_first_form" id="my_first_form" method="post" onsubmit="if (!submitter.combine('my_first_form', 'my_second_form')) { return false; }">
    ...
    <form name="my_second_form" id="my_second_form" method="post" onsubmit="if (!submitter.combine('my_second_form', 'my_first_form')) { return false; }">
    

    表单验证可以放在任何你喜欢的地方——如果你的验证器是提交者对象的另一个函数,那将是最有意义的,反之亦然。

    【讨论】:

      【解决方案4】:

      另一种将自己的数据合并到表单序列化中的方法

              var data = {};
              data['key'] = 'value';
      
              e.preventDefault();
              $.ajax({
                  url : url,
                  dataType : 'json',
                  type : 'post',
                  data : $(this).serialize() + '&' + $.param(data),
                  success : function(data) {
      
                  },
                  error : function() {
      
                  }
              });
      

      【讨论】:

      • $.param({key: 'value', anotherKey: 'anotherValue'}) - $.param 可以接受的更直观的示例。
      【解决方案5】:

      虽然其他答案解决了您提出的问题,但如果您想在用户提交一个表单时发送两个表单的内容,那么可能值得考虑为什么您有 2 个单独的表单。 p>

      如果您使用 2 种不同的形式在视觉上将它们分开,更好的方法可能是使用 CSS 将元素按照您的意愿放置在屏幕上。这样,您就不会依赖 Javascript 来确保您的表单被正确填充。

      【讨论】:

      • 鉴于我正在使用“formvalidator.net”来验证 onBlur 或 onSubmit 的输入,您将如何在验证后切换可见性?除了将表单分成 2 个表单之外,我真的没有看到其他方法,第一个提交验证并显示第二个表单,而最后一个提交所有数据。
      【解决方案6】:

      这是一种用于合并两个表单的干净的 JavaScript 方法。我使用 Prototype 和 jQuery 使用 POST 请求对其进行测试,它可以工作。事情是这样的:

      var data1 = document.getElementById('form1').serialize();
      

      注意:form1 是表单的 id 。您需要在 &lt;form id="form1"&gt;&lt;/form &gt; 中设置它

      var data2 = document.getElementById('form2').serialize();
      

      注意:form2 是表单的 ID。需要设置在&lt;form id="form2"&gt;&lt;/form &gt;

      现在您有两个vars 和两个序列化数据(数组)。您可以轻松地合并它们。您的表单将具有关联。数组,当您尝试使用concat 函数时可能会遇到问题。

      var mergeddata = data1 + '&' + data2;
      

      就是这样!您可以轻松地通过 ajax 调用发送它们。例如Prototype.js:

       new Ajax.Request(url, {
                              method: 'post',
                              parameters: mergeddata, ...
      

      【讨论】:

        【解决方案7】:

        我使用下面的代码在我的网站中提交了两个表单的数据。

        这个想法是您使用serialize 获取多种形式的数据,然后组合该数据并将其与$.ajax 函数的data 参数相等。

        .

        // submits two forms simultaneously
        function submit_forms(form1_id, form2_id)
        {
            var frm1_name = $("#" + form1_id).attr('name');
            var frm2_name = $("#" + form2_id).attr('name');
        
            if (frm1_name == frm2_name)
            {
                alert('The two forms can not have the same name !!');
            }
            else
            {
                var frm1_data = $("#" + form1_id).serialize();
                var frm2_data = $("#" + form2_id).serialize();
        
                if (frm1_data && frm2_data)
                {
                    $("#div_busy").html('<strong>Processing...</strong><br /><img id="busy" src="./images/progress_bar.gif" border="0" style="display:none;" />');
                    $("#busy").fadeIn('slow');
        
                    $.ajax(
                    {
                           type: "POST",
                           url: "process_sticker_request.php",
                           data: frm1_data + "&" + frm2_data,
                           cache: false,
        
                           error: function()
                           {
                                $("#busy").hide('slow');
                                $("#div_busy").css({'color':'#ff0000', 'font-weight':'bold'});
                                $("#div_busy").html('Request Error!!');
                           },
                           success: function(response)
                           {
                                $("#div_busy").hide('slow');
                                $("#hdnFormsData").html(response);
        
                                    // open popup now with retrieved data
                                    window.open('', 'popup2', 'toolbars = 1, resizable=1, scrollbars=1, menubar=1');
                                    document.getElementById("prt").action = 'win_sticker.php';
                                    document.getElementById("prt").target = 'popup2';
                                    document.getElementById("prt").submit();
        
                                    // reset the action of the form
                                    document.getElementById("prt").action = 'list_preview.php';
        
                           }
                     });                
                }
                else
                {
                    alert('Could not submit the forms !!');
                }
            }
        }
        

        【讨论】:

        • 虽然您的回答远远超出了 OP 问题的范围,但它确实帮助我了解了你们如何完成 AJAX 请求的进度条,所以谢谢您^^
        【解决方案8】:

        使用 serialize 合并表单并使用 ajax 提交对我有用,直到我添加了一个“导出”按钮(将数据作为 excel 文件发送)。为此,我需要进行完整的回发。所以我最终采用了这种方法。它选择了适当的合并技术,并在此过程中修复了按钮、选择和文本区域的一些问题:

        $("body").on("submit", ".combineForm", function () {
        
            var frm = $(this);
            var action = frm.attr("action");
            var method = frm.attr("method");
            var target = frm.data("updateTarget");
        
            var combined = $(".combineForm");
        
            //get the submit button that was clicked
            var btn = $(this).find("button[type=submit]:focus");
            var btnName = btn.attr("name");
            var btnValue = btn.attr("value");
        
            //create an in memory form to avoid changing the existing form
            var f = $("<form action='" + action + "' method='" + method + "'/>")
        
            //Browsers send the name and value of the clicked button but serialize, clone and our copy can't
            //So add a hidden field to simulate browser behaviour
            if (btnName)
                f.append("<input name='" + btnName + "' type='hidden' value='" + btnValue + "' />")
        
            if (btnValue === "export") {//exporting to a file needs full submit
        
                //merge forms with class 'combineForm' by copying values into hidden inputs
                // - cloning doesn't copy values of select or textareas
                combined.find(":input").not("submit").each(function () {
                    var inp = $("<input name='"
                                + $(this).attr("name")
                                + "' type='hidden' value='"
                                + $(this).val() + "' />")
                    f.append(inp);
                });
        
                f[0].submit();
                return false;
            }
        
            //merge forms for ajax submit
            var data = combined.serialize() + "&" + f.serialize();
            $.ajax({
                url: action,
                type: 'POST',
                data: data,
                dataType: "html",
                success: function (html) {
                    $(target).html(html);
                }
            });
        
            return false;
        });
        

        【讨论】:

          【解决方案9】:

          我写了一个合并两个复合体的函数,来自不同的形式,如:

          // Each Object came from serializeArray()
          var obj = $('form').serializeArray();
          obj = JSON.stringify(obj);
          obj = JSON.parse(obj);
          

          // 示例

          obj1 = [
                  { name: 'name1', value: 'value1'},
                  { name: 'name2', value: 'value2'},
                  { name: 'name3', value: 'value3'}
              ];
          
          obj2 = [
                  { name: 'name4', value: 'value4'},
                  { name: 'name2', value: 'value5'},
                  { name: 'name1', value: 'value6'}
              ];
          
          
          function mergeTwoJsonObj( obj1, obj2 ){
          
              var obj3 = [];
              for (var index in obj1) {
                  obj = {name: obj1[index].name, value: obj1[index].value};
                  obj3.push(obj);
              }
              for (var index in obj2) {
                  obj = {name: obj2[index].name, value: obj2[index].value};
                  var isExist = false;
                  var existAt;
          
                  for (var j in obj3) {
                      if( obj3[j].name === obj2[index].name){
                          isExist = true;
                          existAt  = j;
                          break;
                      }
                  }
          
                  if(!isExist) {
                      obj3.push(obj);
                  } else {
                      obj3[j].value = obj2[index].value;
                  }
          
              }
          
              obj3 = JSON.stringify(obj3);
              obj3 = JSON.parse(obj3)
          
              return obj3;
          
          }
          

          对于示例 obj1,它返回 obj2:

          // 示例

           obj3 = [
                  { name: 'name1', value: 'value6'},
                  { name: 'name2', value: 'value5'},
                  { name: 'name3', value: 'value3'},
                  { name: 'name4', value: 'value4'}
              ];
          

          希望对你有帮助

          【讨论】:

            猜你喜欢
            • 2011-10-16
            • 2015-09-16
            • 1970-01-01
            • 2023-01-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-09
            相关资源
            最近更新 更多