【发布时间】:2010-02-26 10:50:55
【问题描述】:
我在一个 html 页面上有两个表单。使用 jQuery,是否可以在提交第一个表单时将两个表单中的数据放入 POST 数据中?
【问题讨论】:
我在一个 html 页面上有两个表单。使用 jQuery,是否可以在提交第一个表单时将两个表单中的数据放入 POST 数据中?
【问题讨论】:
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() 是一个验证函数。这会导致问题吗?
一种方法是在数据验证检查成功后将 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().
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; }">
表单验证可以放在任何你喜欢的地方——如果你的验证器是提交者对象的另一个函数,那将是最有意义的,反之亦然。
【讨论】:
另一种将自己的数据合并到表单序列化中的方法
var data = {};
data['key'] = 'value';
e.preventDefault();
$.ajax({
url : url,
dataType : 'json',
type : 'post',
data : $(this).serialize() + '&' + $.param(data),
success : function(data) {
},
error : function() {
}
});
【讨论】:
虽然其他答案解决了您提出的问题,但如果您想在用户提交一个表单时发送两个表单的内容,那么可能值得考虑为什么您有 2 个单独的表单。 p>
如果您使用 2 种不同的形式在视觉上将它们分开,更好的方法可能是使用 CSS 将元素按照您的意愿放置在屏幕上。这样,您就不会依赖 Javascript 来确保您的表单被正确填充。
【讨论】:
这是一种用于合并两个表单的干净的 JavaScript 方法。我使用 Prototype 和 jQuery 使用 POST 请求对其进行测试,它可以工作。事情是这样的:
var data1 = document.getElementById('form1').serialize();
注意:form1 是表单的 id 。您需要在 <form id="form1"></form > 中设置它
var data2 = document.getElementById('form2').serialize();
注意:form2 是表单的 ID。需要设置在<form id="form2"></form >内
现在您有两个vars 和两个序列化数据(数组)。您可以轻松地合并它们。您的表单将具有关联。数组,当您尝试使用concat 函数时可能会遇到问题。
var mergeddata = data1 + '&' + data2;
就是这样!您可以轻松地通过 ajax 调用发送它们。例如Prototype.js:
new Ajax.Request(url, {
method: 'post',
parameters: mergeddata, ...
【讨论】:
我使用下面的代码在我的网站中提交了两个表单的数据。
这个想法是您使用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 !!');
}
}
}
【讨论】:
使用 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;
});
【讨论】:
我写了一个合并两个复合体的函数,来自不同的形式,如:
// 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'}
];
希望对你有帮助
【讨论】: