一种形式的两个提交按钮


534

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


考虑将接受的答案更改为Parrots的答案
彼得·莫滕森

2
@PeterMortensen-今天公认的答案和Parrot的答案都不是最好的。有关使用attribute的最新HTML5解决方案,请参见Leo的答案formaction。或查看kiril的答案,了解如何使用户可见的HTML与发送到浏览器的值无关-与Greg或Parrot的答案相比,以更易于编码的方式解决国际化问题。
制造商史蒂夫(Steve),

Answers:


446

如果给每个人起一个名字,被点击的人将作为其他任何输入被发送出去。

<input type="submit" name="button_1" value="Click me">

101
还要确保按钮的名称具有正确的名称!例如,“ button-1”将不起作用。可以为某人节省很多麻烦,因此请记住这一点。
pdolinaj 2013年

22
通常,表单中的所有输入都与表单一起发送。由于仅在单击按钮后才提交按钮的值,因此您必须在表单值中搜索这些预定义的名称。我认为另一个答案(stackoverflow.com/a/21778226/88409)涉及给他们全部相同的名字,但值不同,这更有意义。然后,您只需在一个已知的表单字段名称下获取值。这也使显而易见的是,对于给定的输入名称,仅发送一个值(单击的值),就像单选按钮的工作方式(相同的名称,不同的值)一样。
Triynko,2015年

6
@Triynko,正如罗宾·格林(Robin Green)在该答案的评论中所说的那样,这对于国际化来说更好。例如,如果页面以西班牙语呈现,则按钮的文本可能会有所不同。因此,在这种情况下,使代码的逻辑依赖于该按钮的文本将不起作用。用名称命名更安全,因为它是一个不显示给用户的值,因此可以更多地视为“私有”变量,而较少作为向用户发送的消息。
sfarbota

澄清@sfarbota的评论:Parrot答案中显示的第一个解决方案是有问题的,因为它依赖于测试用户可见的值。这是可疑的-更改用户可见的单词时中断的代码被视为“脆弱”。Parrot答案中显示的第二种解决方案很好-它与此解决方案相同。Parrot的第二种解决方案还显示了要编写的相应代码,因此,比起这一种,它是一个更有用的答案。
制造商

2
有关使用attribute的最新HTML5解决方案,请参见Leo的答案formaction。或参阅kiril的答案,了解如何使用户可见的HTML与发送给浏览器的值无关,从而解决了国际化问题。
制造商史蒂夫(Steve),

875

解决方案1:
给每个输入一个不同的值并保持相同的名称:

<input type="submit" name="action" value="Update" />
<input type="submit" name="action" value="Delete" />

然后在代码中检查哪个触发了:

if ($_POST['action'] == 'Update') {
    //action for update here
} else if ($_POST['action'] == 'Delete') {
    //action for delete
} else {
    //invalid action!
}

这样做的问题是您将逻辑绑定到输入中用户可见的文本。


解决方案2:为
每个输入一个唯一的名称,并检查$ _POST是否存在该输入:

<input type="submit" name="update_button" value="Update" />
<input type="submit" name="delete_button" value="Delete" />

并在代码中:

if (isset($_POST['update_button'])) {
    //update action
} else if (isset($_POST['delete_button'])) {
    //delete action
} else {
    //no button pressed
}

37
出于国际化的目的,最好使用选定的答案。
罗宾·格林

11
答案本身就是@LaszloPapp,如果您使用上面选择的答案,则可以在不影响逻辑的情况下使表格国际化(即翻译成不同的语言或方言)。如果在此答案中使用第一个选项,则逻辑取决于表单实际使用的语言
Robin Green

1
@RobinGreen:我认为大多数人会使用第二种逻辑,不是吗?
lpapp 2013年

5
i 18n = i n,并且18代表在第一个和最后一个之间的18个字母。
Buttle Butkus

18
OP并没有要求PHP。
Rudey 2014年

110

更好的解决方案包括使用按钮标签提交表单:

<form>
    ...
    <button type="submit" name="action" value="update">Update</button>
    <button type="submit" name="action" value="delete">Delete</button>
</form>

按钮的HTML (例如..>Update<..,用户看到的内容;由于提供了HTML,因此value用户不可见;仅发送到服务器。这样就不会给国际化和多种显示语言带来麻烦(在在以前的解决方案中,按钮的标签也是发送到服务器的值)。


13
显然,浏览器的行为有所不同。一些提交值属性,另一些提交标记之间的字符串。因此,请谨慎使用此属性。
Jeroen Dierckx 2014年

1
我想提供的片段是完全支持(w3schools.com/tags/att_button_type.asp
基里尔

2
@kiril该链接的代码段使用两种不同的<button>submitreset。请注意,reset它不会提交任何内容,只会重置表单。因此,耶隆的观点仍然存在。
fizruk 2014年

7
好吧,你的权利。然后,我检查了HTML5 W3C工作草案。引用:>> value属性给出元素的值,以用于表单提交。元素的值是元素的value属性的值(如果有的话),否则为空字符串。>>注意:仅当按钮本身用于启动表单提交时,按钮(及其值)才包含在表单提交中。
kiril 2014年

8
@杰伦·布尔(Jeroen Bull)。哪些浏览器在标签之间提交文本?输入或按钮只能提交“值”属性。按钮实际上可以在其标签之间包含任何内容,包括图像或其他HTML标签。这就是在输入元素上使用按钮的全部意义,并且您试图建议浏览器将所有内容都转储为值?没门。
Triynko 2015年

93

formaction属性有一种新的HTML5方法:

<button type="submit" formaction="/action_one">First action</button>
<button type="submit" formaction="/action_two">Second action</button>

显然,这在IE9和更早版本中不起作用,但是对于其他浏览器,您应该没问题(请参阅:w3schools.com HTML <button> formaction Attribute)。

就个人而言,我通常使用Javascript以这种方式作为备份来远程提交表单(以便更快地获得反馈)。在这两者之间,唯一未覆盖的人是IE <9(禁用Javascript)。

当然,如果您基本上是在服务器端采取相同的操作而不管按下了哪个按钮,那么这可能是不合适的,但是通常,如果有两个用户端操作可用,那么它们也将映射到两个服务器端操作。

编辑: 正如Pascal_dher在评论中指出的那样,该属性在<input>标签上也可用。


1
也可用于“输入”标签。按照w3schools编码:使用按钮标记时,不同的浏览器可能会提交不同的值:w3schools.com/tags/tag_button.asp
Pascal_dher 2015年

3
我从事Web开发已经12年了,这对我来说是新手,实际上正是我所需要的。谢谢!
KyleFarris

1
不客气@KyleFarris!我相信这只是在最近才成为可能,所以如果您还没有发现它,那就不足为奇了。
Leo

2
给Rails用户的注意:如果使用创建表单,则添加此属性将无效form_tag。我使它起作用的唯一方法是切换form_for并使用f.submit formaction: 'your_path'
fgblomqvist


27

这非常容易测试

<form action="" method="get">

<input type="submit" name="sb" value="One">
<input type="submit" name="sb" value="Two">
<input type="submit" name="sb" value="Three">

</form>

只需将其放在HTML页面中,单击按钮,然后查看URL


5
在这里使用GET是一种不好的做法,应尽可能使用POST。
Syncrossus

6
@Syncrossus这是出于测试目的。
艾蒂安·马丁

22

使用formactionHTML属性(第5行):

<form action="/action_page.php" method="get">
    First name: <input type="text" name="fname"><br>
    Last name: <input type="text" name="lname"><br>
    <button type="submit">Submit</button><br>
    <button type="submit" formaction="/action_page2.php">Submit to another page</button>
</form>


@ToolmakerSteve-但是用户已投票赞成。随便挑!!
user12379095


11

处理多个提交按钮的最佳方法是在服务器脚本中使用切换大小写

<form action="demo_form.php" method="get">

Choose your favorite subject:

<button name="subject" type="submit" value="html">HTML</button>
<button name="subject" type="submit" value="css">CSS</button>
<button name="subject" type="submit" value="javascript">Java Script</button>
<button name="subject" type="submit" value="jquery">jQuery</button>

</form>

服务器代码/服务器脚本-提交表单的位置:

demo_form.php

<?php

switch($_REQUEST['subject']) {

    case 'html': //action for html here
                break;

    case 'css': //action for css here
                break;

    case 'javascript': //action for javascript here
                        break;

    case 'jquery': //action for jquery here
                    break;
}

?>

资料来源:W3Schools.com


是的,它是你必须有关于动作脚本的想法(服务器端脚本技术),您可以使用任何脚本/文件来处理提交的数据如PHP,ASP,JSP等 <form action="demo_form.php" method="get">
SHAILESH Sonare

好的。这令人困惑,因为还有一种名为ActionScript的语言。您应该说:“服务器代码”或“服务器脚本”。
平民

我不知道您可以使用按钮来做到这一点
William Isted

10

也许这里建议的解决方案在2009年有效,但是ive测试了所有上述建议的答案,并且没有人在任何浏览器中工作。

我发现可行的唯一解决方案是这样的:(但是我认为使用起来有点难看)

<form method="post" name="form">
<input type="submit" value="dosomething" onclick="javascript: form.action='actionurl1';"/>
<input type="submit" value="dosomethingelse" onclick="javascript: form.action='actionurl2';"/>


2
为什么不只是使用formaction="actionurl1"?您不需要JavaScript。
rybo111

3
@ rybo111 IE9浏览器(女巫相对来说仍被广泛使用)不支持formaction
clueless007

1
@inaliaghle True,大约1%的用户-这取决于项目针对的对象。大约1%的用户不使用JavaScript。
rybo111

1
对于未来的读者:使用javascript并没有错,如本答案所示。这是一个有用的技能。OTOH,评价较高的答案也可以正常工作-忽略此答案的开头句子。如果由于某种原因您无法获得其他答案,请以SO问题的形式发布完整的代码,说明发生了什么(或没有发生),并询问您做错了什么。
制造商史蒂夫(Steve)

6

定义namearray

<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非常重要,因为如果没有解析,两者都会被解析。请享用。


现在,这是一个很好的建议-主要是因为您可以轻松地在更多情况下添加更多按钮,并且switch如果一个按钮添加了一个按钮却忘记了将其添加到switch(和/或拼写错误等),则可以将其与默认操作配合使用
Gwyneth Llewelyn

此外,@ Pato添加了一个类似的答案,该答案可能更惯用,但您的工作正常!
Gwyneth Llewelyn

1
@GwynethLlewelyn我写自己的答案时没有看到其他答案,也没有注意到。实际上是一样的,但这只是强调大多数人如何喜欢这种逻辑。区别只是出于语义原因与名称,对菜鸟的理解或喜欢以其开头的人的区别。
残忍的

5

由于您未指定要使用的服务器端脚本编写方法,因此,我将为您提供一个使用CherryPy的适用于Python的示例(尽管它也可能对其他上下文有用):

<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其参数列表(而不是乏味地键入每个表单项的每个名称),那么您可以检查一下按下了哪个按钮,如下所示:

if "register" in kwargs:
    pass #Do the register code
elif "login" in kwargs:
    pass #Do the login code

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>

2

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


您很可能是指POST数组。
ypnos

3
不一定,如果表单的方法是“ POST”,它将不会显示在GET数组中。大多数表格都是通过POST提交的。
鹦鹉

2
/或者在技术上是正确的,但是如此错误。您可以使用method =“ GET”提交表单,但是这很值得。
比尔蜥蜴

4
仅当使用不当时,它才“值得一试”:w3.org/2001/tag/doc/whenToUseGet.html
墨卡托

2
是的,我并不是要建议GET,而是要概括一些东西。
约翰Bubriski

1

您也可以这样操作(如果您有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']);

http://php.net/manual/zh/function.key.php


这类似于@Thielicious 发布的答案,但是您的答案可能更惯用。就个人而言,我更喜欢使用字母数字标签作为索引(而不是数字)以提高可读性(更容易记住每个按钮应该做什么),但是使用YMMV。但是利用$_POST['row']作为关联数组的优势很聪明!
Gwyneth Llewelyn

1
我同意,如果要处理静态按钮,则应使用命名键。但在某些情况下,您无法做到。有时您会动态生成这些输入。最常见的情况是一列行,每个行都由一个ID标识。我想我在写答案时(4年前!)正在考虑这种情况。我已经对其进行了编辑,因此更明显的是该数字是一个id而不是一个索引。
Pato

做得好!是的,我同意,现在更明显了。我仍然相信您的答案比@Thielicious的答案稍好(甚至可能更有效率,尤其是在有许多按钮的情况下)。
Gwyneth Llewelyn

1

您在一个表单示例中执行多个提交按钮的操作

 <input type="submit" name="" class="btn action_bg btn-sm loadGif" value="Add Address" title="" formaction="/addAddress"> 
 <input type="submit" name="" class="btn action_bg btn-sm loadGif" value="update Address" title="" formaction="/updateAddress"> 

0

很简单,您可以在不同的提交按钮上更改表单的动作。

在文档中尝试一下。

$(".acceptOffer").click(function () {
       $("form").attr("action", "/Managers/SubdomainTransactions");
});

$(".declineOffer").click(function () {
       $("form").attr("action", "/Sales/SubdomainTransactions");
});

0

您还可以使用href属性,并发送带有每个按钮附加值的get。但是那时就不需要表格了

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

这对于POST路由下的控制器不起作用。
哈维·蒙特罗

因此,“发送获取”
乔纳森·拉利伯特

3
很抱歉不同意,但GET并不总是适合。如果您“修改模型的状态”,则永远不要使用GET,因为刷新浏览器可能会透明地发送两次相同的请求。使用GET只有“查看”的东西,POST送的状态变化(添加,删除,编辑等)的请求。然后在您的POST控制器操作中更改状态(数据库,会话...)并投射重定向响应,然后GET使用新的更改状态。这样做GET的模型状态的改变是非常肮脏,任何良好的编码器应该避免这样。不好意思这么说。清理代码rulez。
哈维·蒙特罗

真正。但是玩肮脏有时可能是干净的。这取决于您正在做什么。就个人而言,它不会在获取上映射删除和编辑请求,但是有一些方法可以使其工作..例如,检查它是否已被删除,或者检查用户是否有权这样做等等……
Jonathan Laliberte

-1

您可以像这样显示按钮:

<input type="submit" name="typeBtn" value="BUY">
<input type="submit" name="typeBtn" value="SELL">

然后在代码中,您可以使用以下方法获取值:

if request.method == 'POST':
    #valUnits = request.POST.get('unitsInput','')
    #valPrice = request.POST.get('priceInput','')
    valType = request.POST.get('typeBtn','')

(valUnits和valPrice是我从留作说明的表单中提取的其他一些值)


-1

由于您未指定要使用的服务器端脚本编写方法,因此我将为您提供一个适用于PHP的示例

<?php
   if(isset($_POST["loginForm"]))
   {
    print_r ($_POST); // FOR Showing POST DATA
   }
   elseif(isset($_POST["registrationForm"]))
   {
    print_r ($_POST);
   }
   elseif(isset($_POST["saveForm"]))
   {
    print_r ($_POST);
   }
   else{

   }
?>
<html>
<head>
</head>
<body>
  
  <fieldset>
    <legend>FORM-1 with 2 buttons</legend>
      <form method="post" >
      <input type="text" name="loginname" value ="ABC" >

     <!--Always use type="password" for password --> 
     <input type="text" name="loginpassword" value ="abc123" >
     
     <input type="submit" name="loginForm" value="Login"><!--SUBMIT Button 1 -->
     <input type="submit" name="saveForm" value="Save">  <!--SUBMIT Button 2 -->
   </form>
  </fieldset>



  <fieldset>
    <legend>FORM-2 with 1 button</legend>
     <form method="post" >
      <input type="text" name="registrationname" value ="XYZ" >
      
     <!--Always use type="password" for password -->
     <input type="text" name="registrationpassword" value ="xyz123" >
     
     <input type="submit" name="registrationForm" value="Register"> <!--SUBMIT Button 3 -->
   </form>
  </fieldset>
  

</body>
</html>

形式

当单击登录-> loginForm时

当点击保存-> saveForm

当点击注册-> registrationForm

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.