【问题标题】:Access 'post' data using JavaScript or check which submit button was used to submit the form使用 JavaScript 访问“发布”数据或检查使用哪个提交按钮提交表单
【发布时间】:2012-12-06 17:15:05
【问题描述】:

考虑一个带有 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 发送表单数据。像这样:&lt;form method="post" onsubmit="return ajaxSubmit(this);"&gt;

我使用这个ajaxSubmit 函数作为检查任何提供的表单元素并改为通过Ajax 发送数据的通用方法。这可以很好地确定文本字段的值,如果复选框被“选中”,在组中选择了哪个收音机等等。它似乎唯一出错的事情(因为我不确定如何检查这个)是哪个提交按钮用于提交表单。即myForm["command"] 中没有任何内容可以说明实际使用了 2 个命令按钮中的哪一个。

相反,有没有办法访问服务器在发送之前使用 JavaScript 接收的相同“发布”数据?

否则,这只是我需要解决的缺陷吗?最好的方法是什么?

编辑: 由于所有现代浏览器都会传递用于提交表单的按钮的名称/值(以及其他相关部分,例如从组中选择哪个选项、选中的复选框名称/值等),任何人都可以解释为什么没有在发送到服务器之前直接访问这些数据的方法?我们不能这样做有什么原因吗?

【问题讨论】:

  • 也许我理解错了,但是如果你使用 AJAX 将表单数据发送到服务器,为什么要使用 'post' 呢?另外,要确定按下了哪个提交按钮,您不能只提供 ID 属性并将它们传递给 AJAX 例程吗?
  • Ajax 例程是一个名为“ajaxSubmit”的通用函数,它接受一个表示 HTML 表单标签及其元素的 JavaScript“表单”对象。在许多情况下,我使用它来用 Ajax 代替常规的表单提交(和页面刷新)。我喜欢我可以通过 post 提交 Ajax 并期望在服务器端获得相同的结果。
  • 请注意,如果您使用button 而不是input type="submit",旧版本的 IE 将发送所有按钮值,而不仅仅是您单击的那个。

标签: javascript html ajax


【解决方案1】:

相反,有没有办法访问服务器在发送之前使用 JavaScript 接收的相同“发布”数据?

不是那个确切的数据,不。

了解按下哪个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 事件从其后代控件(包括提交按钮)冒泡到表单,您可以在表单上挂钩事件,然后查看它是否发生在提交按钮上,如果是,那么该按钮的@ 987654339@是。

例如,这里有一个动态附加到表单的 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);
  }
};

Live Example | Source

或者在任何现代浏览器上使用 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);

Live Example | Source

或者使用一个库来简化(这里是jQuery,不过大部分都有这个功能,叫做事件委托):

$("#theForm").delegate("input[type=submit]", "click", function() {
  alert(this.value);
  return false;
});

Live Example | Source(我在那里使用delegate,因为我喜欢清晰;对于最新版本的jQuery,你可以使用超重载的on,但不太清楚。如果你选择to,注意参数的顺序是不同的。)

这里的重点是它并不复杂、困难或特别麻烦。

关于您的编辑的结束问题:

...谁能解释为什么在发送到服务器之前无法直接访问这些数据?

可能不会,不。重要的是要了解很多这些东西刚刚进化。与表单一起发送的提交按钮的值是 HTML 的东西,显然在执行 DOM HTML 表单模块时,任何人都没有想到“嘿,我们应该在表单上有一个仅在表单期间存在的属性提交事件,告诉您提交表单的内容。”可能应该有人想到,但显然没有。

【讨论】:

  • 谢谢。这是我发现解决此问题的唯一(也许是最好的)方法。
  • @Matthew:我已经添加了更多示例并(在某种程度范围内)解决了您编辑中的问题。
  • 再次感谢。这使表单保持相当完整(我们真正要做的只是添加一个额外的隐藏字段)并进行一些事件处理以使其正常工作。
【解决方案2】:

另一种解决方案是使用单选按钮而不是提交按钮(不过,您必须将单选按钮设计为看起来像按钮)。

提交后,该字段的值应该是被点击的那个。您可以使用 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>

【讨论】:

  • 良好的“跳出框框”思维。我没有考虑过这样的事情。
【解决方案3】:

我认为您可以通过删除未点击的另一个按钮来解决此问题。之后,您可以运行 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>

【讨论】:

    【解决方案4】:

    一切都是合理的,但如果您要在所有提交按钮上附加点击处理程序,那么通过提交功能来管理您的提交详细信息就没有多大意义了。

    只需让点击处理程序触发表单提交,同时将足够的上下文信息传递给组合。等等,点击处理程序通常已经告诉你点击的来源(有你的上下文信息),尤其是在使用一些 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 之类的东西。

    我承认,遵守 submit-onsubmit 范式促进了某种纯粹的表单处理,但 IMO 使用两个提交按钮已经进入了非纯粹的领域。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 2014-10-08
      • 2012-02-10
      • 1970-01-01
      • 2014-07-15
      相关资源
      最近更新 更多