一个表单中有两个提交按钮

692

我在表单中有两个提交按钮。如何在服务器端确定哪一个被点击了?

23个回答

9

name定义为array

<form action='' method=POST>
    (...) some input fields (...)
    <input type=submit name=submit[save] value=Save>
    <input type=submit name=submit[delete] value=Delete>
</form>

示例服务器代码 (PHP):

if (isset($_POST["submit"])) {
    $sub = $_POST["submit"];

    if (isset($sub["save"])) {
        // Save something;
    } elseif (isset($sub["delete"])) {
        // Delete something
    }
}

elseif非常重要,因为如果不使用elseif,两个条件都将被解析。


1
现在这是一个非常好的建议——主要是因为你可以很容易地添加更多带有更多情况的按钮,并使用一个带有默认操作的switch,如果有人添加了一个按钮并忘记将其添加到switch(和/或拼错了等等)。 - Gwyneth Llewelyn
此外,@Pato添加了一个类似的答案,这可能更习惯用语,但你的也可以! - Gwyneth Llewelyn
1
@GwynethLlewelyn 在我写自己的回答时,我没有看到另一个回答。它实际上是相同的,但这只是强调了大多数人喜欢这种逻辑。区别仅在于语义原因的名称,有助于新手或任何想要从此开始的人更好地理解。 - Thielicious
这会通过HTML验证吗?例如,没有引号? - Peter Mortensen
关于“将名称定义为数组”:您能详细说明一下这个数组的事情/约定/语法(特定于PHP),包括官方文档的链接吗?(但是不要包含“编辑:”,“更新:”或类似内容 - 答案应该看起来像今天写的。) - Peter Mortensen
为什么两者都被解析很重要呢?是为了性能吗?我认为这会是微不足道的。 - Peter Mortensen

9
一个HTML示例,用于在不同的按钮点击时发送不同的表单操作:
<form action="/login" method="POST">
    <input type="text" name="username" value="your_username" />
    <input type="password" name="password" value="your_password" />
    <button type="submit">Login</button>
    <button type="submit" formaction="/users" formmethod="POST">Add User</button>
</form>
同一个表单用于添加新用户和登录用户。

从未想过这里会有这个。 - Arun Prasad E S

6

因为您没有具体说明使用的是哪种服务器端脚本方法,所以我将给出一个适用于Python的示例,使用CherryPy(虽然它也可能对其他情境有用):

<button type="submit" name="register">Create a new account</button>
<button type="submit" name="login">Log into your account</button>
与其使用值来确定按下了哪个按钮,您可以使用名称(使用<button>标记而不是<input>)。这样,如果您的按钮恰好具有相同的文本,它就不会引起问题。所有表单项(包括按钮)的名称都作为URL的一部分发送。 在CherryPy中,每个表单项都是执行服务器端代码的方法的参数。因此,如果您的方法只有**kwargs作为参数列表(而不是 tediously 打出每个表单项的每个名称),则可以像这样检查按下了哪个按钮:
if "register" in kwargs:
    pass # Do the register code
elif "login" in kwargs:
    pass # Do the login code

6
作为一条提示,如果你有多个提交按钮并且按下键盘上的回车键,则默认按钮值将是DOM上第一个按钮的值。 例如:
<form>
  <input type="text" name="foo" value="bar">
  <button type="submit" name="operation" value="val-1">Operation #1</button>
  <button type="submit" name="operation" value="val-2">Operation #2</button>
</form>
如果在这个表单上按下Enter键,将会发送以下参数:
foo=bar&operation=val-1

谢谢。这正是我想要确认的。 - David

3
<form method="post">
    <input type="hidden" name="id" value="'.$id.'" readonly="readonly"/>'; // Any value to post PHP
    <input type='submit' name='update' value='update' formAction='updateCars.php'/>
    <input type='submit' name='delete' value='delete' formAction='sqlDelete.php'/>
</form>

这是什么?PHP?这看起来不像有效的PHP。它是heredoc吗?无论如何,需要解释一下。例如,什么是想法/要点?请通过编辑(更改)您的答案进行回复,而不是在评论中(不带“Edit:”,“Update:”或类似内容 - 答案应该看起来像今天写的)。 - Peter Mortensen

2
您也可以像这样做(如果您有N个输入,我认为这非常方便)。
<input type="submit" name="row[456]" value="something">
<input type="submit" name="row[123]" value="something">
<input type="submit" name="row[789]" value="something">
常见的用例是为每个按钮使用来自数据库的不同 ID,这样您就可以在服务器端知道单击了哪一行。 在服务器端(本示例中使用 PHP),您可以将 "row" 读取为一个数组以获取该 ID。 $_POST['row'] 将是一个仅包含一个元素的数组,格式为 [ id => value ] (例如:[ '123' => 'something' ])。 因此,要获取所单击的 ID,请执行以下操作:
$index = key($_POST['row']);

key


这与@Thielicious 发布的答案类似,但你的可能更符合惯用语。个人更喜欢使用字母数字标签作为索引(而不是数字)以提高可读性(更容易记住每个按钮应该做什么),但因人而异。但利用$_POST['row']作为关联数组是聪明的! - Gwyneth Llewelyn
1
我同意,如果你正在处理静态按钮,应该使用命名键。但在某些情况下,你不能这样做。有时你会动态生成这些输入。最常见的情况是一列行的列表,每个行都有一个id标识。我想当时我就是考虑到了这种情况,所以写下了答案(4年前!)。我已经编辑过了,现在更明显地表明数字是一个id而不是索引。 - Pato
1
干得好!是的,我同意,现在更明显了;我仍然认为你的答案比@Thielicious的答案稍微好一些(如果有很多按钮,可能甚至更有效率)。 - Gwyneth Llewelyn

2
更新后的答案是使用具有formactionformtarget属性的按钮。 在这个例子中,第一个按钮会在新标签页中打开不同的url/preview。其余三个按钮使用在form标签中指定的action
<button type='submit' class='large' id='btnpreview' name='btnsubmit' value='Preview' formaction='/preview' formtarget='blank' >Preview</button>
<button type='submit' class='large' id='btnsave' name='btnsubmit' value='Save' >Save</button>
<button type='submit' class='large' id='btnreset' name='btnsubmit' value='Reset' >Reset</button>
<button type='submit' class='large' id='btncancel' name='btnsubmit' value='Cancel' >Cancel</button>

完整的文档在这里


2
我认为您应该能够读取GET数组中的名称/值。 我认为未被点击的按钮不会出现在该列表中。

3
如果表单的方法是“POST”,它不会出现在GET数组中,但并不一定如此。大多数表单都是通过POST提交的。 - Parrots
2
"Either/or is technically right, and yet so wrong. You can submit a form with method="GET", but it is cringeworthy." "二者择一在技术上是正确的,但却是错误的。你可以使用method="GET"提交表单,但这是令人不快的。" - Bill the Lizard
4
只有在不恰当使用时才会让人感到“尴尬”: http://www.w3.org/2001/tag/doc/whenToUseGet.html。 - mercator
2
是的,我并不是在尝试建议使用GET方法,我只是在试图概括事情。 - John B
你可以随时使用 $_REQUEST[] - Gwyneth Llewelyn
显示剩余2条评论

1
在HTML5中,您可以在输入字段中使用formactionformmethod属性。
<form action="/addimage" method="POST">
<button>Add image</button>
<button formaction="/home" formmethod="get">Cancel</button>
<button formaction="/logout" formmethod="post">Logout</button>
</form>

0

你也可以使用 href 属性,并为每个按钮附加值发送 get 请求。但是这样就不需要表单了。

href="/SubmitForm?action=delete"
href="/SubmitForm?action=save"

这对于 POST 路由下的控制器不起作用。 - Xavi Montero
发送一个 GET。 - Jonathan Laliberte
3
很抱歉我不同意,但GET并不总是适用的。如果您“修改模型状态”,那么您绝不能使用GET,因为刷新浏览器可能会导致自动发送两次相同的请求。只能使用GET来“查看”内容,并使用POST发送状态更改的请求(添加、删除、编辑等)。然后在您的POST控制器操作中更改状态(数据库、session...),并生成一个重定向响应,然后GET新的更改状态。对于模型状态更改使用GET非常不好,任何优秀的编码人员都应该避免这样做。很抱歉这么说,但干净的代码规则。 - Xavi Montero
真的。但有时玩得太过分有时会变得很干净。这取决于您正在做什么。个人而言,我不会在GET请求上映射删除和编辑请求,但有方法使其正常工作...例如检查它是否已被删除,或检查用户是否有权限这样做等等... - Jonathan Laliberte

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