考虑一个带有2个提交按钮的简单表单
<form method="post">
<button type="submit" name="command" value="cancel">Cancel Order</button>
<button type="submit" name="command" value="proceed">Save Order</button>
</form>
提交后,服务器将通过检查command
的值来了解用于提交表单的提交按钮。太好了!
在这种情况下,我使用表单的onsubmit
事件处理程序来预处理并通过AJAX发送表单数据。像这样:<form method="post" onsubmit="return ajaxSubmit(this);">
我正在使用此ajaxSubmit
函数作为检查任何提供的表单元素并通过Ajax发送数据的一般方法。这可以很好地确定文本字段的值,如果复选框被“选中”,在一个组中选择了哪个无线电等等。唯一看起来错误的东西(因为我不知道如何检查这个)是哪个提交按钮用于提交表单。即myForm["command"]
中没有任何内容可以告诉我实际使用了哪两个命令按钮。
相反,有没有办法访问服务器在发送之前使用JavaScript接收的相同“post”数据?
否则,这只是我需要解决的一个缺陷吗?什么是最好的方式?
修改 由于所有现代浏览器都会传递用于提交表单的按钮的名称/值(以及其他相关部分,例如从组中选择哪个选项,选中复选框名称/值等),任何人都可以解释为什么没有在将数据发送到服务器之前直接访问这些数据的方法?我们有没有理由不能这样做?
答案 0 :(得分:17)
相反,有没有办法访问服务器在发送之前使用JavaScript接收的相同“post”数据?
不是那么精确的数据,没有。
知道按下submit
按钮的常用方法是(不幸的是)将click
处理程序附加到按钮并让它们设置变量(或hidden
字段的值),然后您可以检查submit
事件处理程序。
由于您使用的是旧式DOM0事件处理程序属性,因此hidden
字段可能更适合您正在执行的操作:
<form method="post">
<input type="hidden" name="submitclicked" value="">
<button type="submit" name="command" value="cancel" onclick="submitClick(this);">Cancel Order</button>
<button type="submit" name="command" value="proceed" onclick="submitClick(this);">Save Order</button>
</form>
... submitClick
看起来像这样:
function submitClick(button) {
button.form.submitclicked.value = button.value;
}
...但我建议改为使用DOM2样式的事件处理程序,或至少在代码块中附加DOM0处理程序,因为您可以避免创建全局函数,共享数据而不创建全局变量等。
为了清楚起见,您不必在每个元素上指定onclick
属性,我上面这样做的唯一原因是因为您使用的是DOM0处理程序。
处理它的更好方法是使用事件冒泡。由于click
事件从其后代控件(包括提交按钮)冒泡到表单,您可以在表单上挂钩事件,然后查看它是否发生在提交按钮上,如果是,那么是什么按钮的value
是。
例如,这里有一个DOM0处理程序,动态附加到表单,它将提示单击的提交按钮的值:
var form = document.getElementById("theForm");
form.onclick = function(e) {
// Get the event
e = e || window.event;
// Did it originate in an input[type=submit]?
if (e.target.tagName === "INPUT" &&
e.target.type === "submit") {
// Yes
alert(e.target.value);
}
};
或者在任何现代浏览器上使用DOM2处理程序(不是IE8或更早版本,但很容易为那些添加attachEvent
,这与addEventListener
做的事情大致相同[并且早于它]) :
document.getElementById("theForm").addEventListener("click", function(e) {
// Did it originate in an input[type=submit]?
if (e.target.tagName === "INPUT" &&
e.target.type === "submit") {
// Yes
alert(e.target.value);
}
}, false);
或使用库使其更容易(这里是jQuery,但大多数都有此功能,称为事件委托):
$("#theForm").delegate("input[type=submit]", "click", function() {
alert(this.value);
return false;
});
Live Example | Source(我在那里使用delegate
,因为我喜欢清晰度;使用最新版本的jQuery,你可以使用超重载on
,但它是如果你选择,请注意参数的顺序是不同的。)
这里的重点是它并不复杂,困难或特别麻烦。
重新提出编辑的结束问题:
...任何人都可以解释为什么在将数据发送到服务器之前无法直接访问这些数据?
可能不是,不。重要的是要了解很多这些东西才刚刚发展起来。与表单一起发送的提交按钮的值是一个HTML的东西,显然在做DOM HTML表单模块时,任何人都没有说“嘿,我们应该在表单上只存在一个属性提交事件,告诉您提交表单的内容。“它可能应该发生在某人身上,但显然,它没有。
答案 1 :(得分:4)
另一个解决方案是使用单选按钮而不是提交按钮(尽管如此,您必须将收音机设计为按钮)。
提交后,该字段的值应该是单击的值。您可以使用jQuery的$("[name=command]:selected]")
或$("#theForm").serialize()
<form method="post" onsubmit="return ajaxSubmit(this);" id="theForm">
<input type="radio" name="command" value="cancel" id="cancel" onClick="document.getElementById('theForm').submit();">
<label for="cancel">Cancel Order</label>
<input type="radio" name="command" value="proceed" id="proceed" onClick="document.getElementById('theForm').submit();">
<label for="proceed">Save Order</label>
</form>
答案 2 :(得分:2)
我认为你可以通过删除另一个没有点击的按钮来解决这个问题。之后,您可以运行jQuery的serialize(),或访问任何其他方式留下的按钮的值。
代码如下:
<form method="post">
<button type="submit" id=cancel name="command" value="cancel" onclick="document.getElementByid('submit').remove();submitClick(this);">Cancel Order</button>
<button type="submit" id=submit name="command" value="proceed" onclick="document.getElementByid('cancel').remove();submitClick(this);">Save Order</button>
</form>
答案 3 :(得分:1)
一切都是合理的,但是如果您要在所有提交按钮上附加点击处理程序,那么通过提交功能的环节来管理您的提交详细信息就没有多大意义了。
只需使点击处理程序触发表单提交,同时将足够的上下文信息传递到组合中。等等,点击处理程序通常会告诉你已经点击的来源(这是你的上下文信息),特别是如果使用一些jQuery-ish框架。
所以而不是:
<form onsubmit="doSubmit()" ...>
<input type="submit" onclick="updateSourceTo('cancel');" ... />
<input type="submit" onclick="updateSourceTo('submit');" ... />
使用:
<form ...>
<input type="button" onclick="doSubmit('cancel');" ... />
<input type="button" onclick="doSubmit('submit');" ... />
或者,如果您要通过查看点击事件目标来检测来源:
<form ...>
<input type="button" onclick="handleSubmitButtonClick();" ... />
<input type="button" onclick="handleSubmitButtonClick();" ... />
对于handleSubmitButtonClick的细节,我应该提到form.submit()和jQuery的event.target之类的东西。
我承认,与提交提交范式保持一致可以促进形成处理的某种纯粹主义,但IMO已经使用两个提交按钮进入非纯粹的土地。