HTML 表单中的多个提交按钮

Posted

技术标签:

【中文标题】HTML 表单中的多个提交按钮【英文标题】:Multiple submit buttons in an HTML form 【发布时间】:2010-09-05 05:30:53 【问题描述】:

假设您在 html 表单中创建了一个向导。一键后退,一键前进。由于当您按下 Enter 时,back 按钮首先出现在标记中,因此它将使用该按钮来提交表单。

例子:

<form>
  <!-- Put your cursor in this field and press Enter -->
  <input type="text" name="field1" />

  <!-- This is the button that will submit -->
  <input type="submit" name="prev" value="Previous Page" />

  <!-- But this is the button that I WANT to submit -->
  <input type="submit" name="next" value="Next Page" />
</form>

我想决定当用户按下 Enter 时使用哪个按钮来提交表单。这样,当您按下 Enter 时,向导将移至下一页,而不是上一页。您必须使用tabindex 来执行此操作吗?

【问题讨论】:

只用于浮动:left 【参考方案1】:

我只是在做float右侧按钮的伎俩。

这样Prev 按钮位于Next 按钮的左侧,但Next 在HTML 结构中排在第一位:

.f 
  float: right;

.clr 
  clear: both;
<form action="action" method="get">
  <input type="text" name="abc">
  <div id="buttons">
    <input type="submit" class="f" name="next" value="Next">
    <input type="submit" class="f" name="prev" value="Prev">
    <div class="clr"></div><!-- This div prevents later elements from floating with the buttons. Keeps them 'inside' div#buttons -->
  </div>
</form>

优于其他建议的好处:没有 javascript 代码,可访问,并且两个按钮都保留type="submit"

【讨论】:

请不要在不更改标签顺序的情况下执行此操作,这样点击标签按钮将在按钮出现在屏幕上时循环显示它们。 遗憾的是,这仅在按钮彼此相对靠近时才有效。在更复杂的情况下,比如一个更大的页面,每个角落都有几个按钮,但都在一个单一的形式中,这根本无法管理。【参考方案2】:

把之前的按钮类型改成这样的按钮:

<input type="button" name="prev" value="Previous Page" />

现在 下一步 按钮将成为默认按钮,此外,您还可以向其添加 default 属性,以便您的浏览器会像这样突出显示它:

<input type="submit" name="next" value="Next Page" default />

【讨论】:

您在说什么default 属性? 没有“默认”属性,这将是有效的:w3.org/html/wg/drafts/html/master/…(不在 HTML5 中,HTML 4.01 过渡/严格,XHTML 1.0 严格)。而且我不明白为什么将输入类型从submit 更改为button 会更好。您可以在一个表单中拥有多个提交类型的输入元素而不会出现问题。我真的不明白为什么这个答案如此受欢迎。 输入“按钮”类型不会执行表单操作。您可以使用 onclick 或其他东西,从而执行“默认”表单操作(通过按“提交”类型按钮执行)之外的另一个功能。这就是我一直在寻找的东西,这就是我支持它的原因。不能代表“默认”属性,这不是我的问题的一部分;)感谢您的澄清。 @Sk8erPeter, @Jonas .... 嗯.. 我怀疑这个default 属性是一个全局属性;枚举属性..与枚举状态有关:w3.org/html/wg/drafts/html/master/…。除此之外..此答案的按钮方面不是答案..它是“条件建议”或查询(问题本身)。 @Jonas: 是的,type="button" 不提交表单,type="submit" 可以,但是更改这些按钮的类型绝对不是解决方案,因为这些按钮的行为方式应该基本相同- OP 的问题是如何使“下一步”按钮成为按下 Enter 键的默认按钮。在接受的答案中有一个可能的解决方案。 @BrettCaswell:更改这些按钮的类型是一个糟糕的解决方法(请参阅我之前的评论)。 HTML 中的input 标记(如前所述)没有有效的default 属性,并且(流行的)浏览器不会突出显示具有该属性的按钮,这意味着该属性没有非标准实现 - 所以我仍然不知道@Wally Lawless 在说什么,以及为什么这个答案被高估了。 HTML5 中只引入了一个有效的default 属性,但仅适用于&lt;track&gt; 标签:developer.mozilla.org/en-US/docs/Web/HTML/Element/track【参考方案3】:

为您的提交按钮提供相同的名称,如下所示:

<input type="submit" name="submitButton" value="Previous Page" />
<input type="submit" name="submitButton" value="Next Page" />

当用户按下 Enter 并且 request 转到服务器时,您可以在服务器端代码中检查 submitButton 的值,其中包含一组形成name/value 对。比如在ASP Classic:

If Request.Form("submitButton") = "Previous Page" Then
    ' Code for the previous page
ElseIf Request.Form("submitButton") = "Next Page" Then
    ' Code for the next page
End If

参考:Using multiple submit buttons on a single form

【讨论】:

这不是用户要求的。用户想知道如何控制在按下输入时激活表单中的哪个提交按钮,即。这是默认按钮。 在您甚至不知道按钮标签的 I18n 应用程序中不起作用。 在什么系统或技术解决方案中,服务器本身不知道用于下一步和返回按钮的标签是什么?服务器不是首先生成了下一步和返回按钮吗? (如果本地化是在客户端处理的,我想服务器可能不知道,但我从来没有听说过 HTML) 这个答案完全错过了这个问题,可能是针对不同的问题。怎么这么多赞???更不用说永远不要检查按钮的标签......这会带来很多麻烦。即使是简单的情况:“我们应该将字符串缩写为 'Prev. Page'”会破坏您的网站功能。【参考方案4】:

如果默认使用的第一个按钮在不同浏览器中是一致的,请将它们放在源代码中的正确位置,然后使用 CSS 来切换它们的外观位置。

floatfloat 左右可以在视觉上切换它们,例如。

【讨论】:

【参考方案5】:

有时提供的solution by palotasb 是不够的。在某些用例中,例如“过滤器”提交按钮放置在“下一个和上一个”等按钮上方。我找到了一个解决方法:复制提交按钮,它需要充当隐藏 div 中的默认提交按钮,并将其放在表单中任何其他提交按钮上方。

从技术上讲,当按下 Enter 时,它会通过不同的按钮提交,而不是单击可见的 Next 按钮时提交。但是由于名称和值相同,所以结果没有区别。

<html>
<head>
    <style>
        div.defaultsubmitbutton 
            display: none;
        
    </style>
</head>
<body>
    <form action="action" method="get">
        <div class="defaultsubmitbutton">
            <input type="submit" name="next" value="Next">
        </div>
        <p><input type="text" name="filter"><input type="submit" value="Filter"></p>
        <p>Filtered results</p>
        <input type="radio" name="choice" value="1">Filtered result 1
        <input type="radio" name="choice" value="2">Filtered result 2
        <input type="radio" name="choice" value="3">Filtered result 3
        <div>
            <input type="submit" name="prev" value="Prev">
            <input type="submit" name="next" value="Next">
        </div>
    </form>
</body>
</html>

【讨论】:

【参考方案6】:

纯 HTML 无法做到这一点。这个技巧你必须依赖 JavaScript。

但是,如果您在 HTML 页面上放置两个表单,则可以这样做。

Form1 会有上一个按钮。

Form2 将有任何用户输入 + 下一个按钮。

当用户在 Form2 中按下 Enter 时,会触发 Next submit 按钮。

【讨论】:

【参考方案7】:

我会使用 JavaScript 来提交表单。该函数将由表单元素的 OnKeyPress 事件触发,并检测是否选择了 Enter 键。如果是这种情况,它将提交表单。

这里有两个页面提供了有关如何执行此操作的技术:1、2。基于这些,这里是一个使用示例(基于here):

<SCRIPT TYPE="text/javascript">//<!--
function submitenter(myfield,e) 
  var keycode;
  if (window.event) 
    keycode = window.event.keyCode;
   else if (e) 
    keycode = e.which;
   else 
    return true;
  

  if (keycode == 13) 
    myfield.form.submit();
    return false;
   else 
    return true;
  

//--></SCRIPT>

<INPUT NAME="MyText" TYPE="Text" onKeyPress="return submitenter(this,event)" />

【讨论】:

禁用 javascript 会怎样? 你不应该使用 来注释掉 JS,这些标签不是 Javascript 语言标记 @Marecky 他们不会注释掉 JS。在支持 【参考方案8】:

如果您真的只是希望它像安装对话框一样工作,只需将焦点放在 OnLoad 的“下一步”按钮上。

这样,如果用户点击Return,表单就会提交并继续前进。如果他们想返回,可以点击 Tab 或点击按钮。

【讨论】:

他们的意思是有人填写表格并在文本字段中点击返回。【参考方案9】:

你可以用 CSS 做到这一点。

先用Next 按钮将按钮放入标记中,然后再用Prev 按钮。

然后使用 CSS 将它们定位为您想要的显示方式。

【讨论】:

喜欢palotasb's answer?【参考方案10】:

这在大多数浏览器中无需 JavaScript 或 CSS 即可工作:

<form>
    <p><input type="text" name="field1" /></p>
    <p><a href="previous.html">
    <button type="button">Previous Page</button></a>
    <button type="submit">Next Page</button></p>
</form>

Firefox、Opera、Safari 和 Google Chrome 都可以使用。 与往常一样,Internet Explorer 是个问题。

此版本在 JavaScript 开启时有效:

<form>
    <p><input type="text" name="field1" /></p>
    <p><a href="previous.html">
    <button type="button" onclick="window.location='previous.html'">Previous Page</button></a>
    <button type="submit">Next Page</button></p>
</form>

所以这个解决方案的缺陷是:

如果您在关闭 JavaScript 的情况下使用 Internet Explorer,上一页将无法工作。

请注意,后退按钮仍然有效!

【讨论】:

如果没有 javascript,您将无法激活“上一页”按钮,因为 type="button" ! 您的建议的问题是按钮 type="button" 不会发布表单,因此它基本上什么都不做,而带有锚点的第二个版本会创建 GET 而不是 POST。 【参考方案11】:

如果您在一个页面上有多个活动按钮,那么您可以执行以下操作:

将您要在 Enter 按键上触发的第一个按钮标记为表单上的默认按钮。对于第二个按钮,将其与键盘上的 Backspace 按钮相关联。 Backspace 事件代码为 8。

$(document).on("keydown", function(event) 
  if (event.which.toString() == "8") 
    var findActiveElementsClosestForm = $(document.activeElement).closest("form");

    if (findActiveElementsClosestForm && findActiveElementsClosestForm.length) 
      $("form#" + findActiveElementsClosestForm[0].id + " .secondary_button").trigger("click");
    
  
);
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>

<form action="action" method="get" defaultbutton="TriggerOnEnter">
  <input type="submit" id="PreviousButton" name="prev" value="Prev" class="secondary_button" />
  <input type="submit" id='TriggerOnEnter' name="next" value="Next" class="primary_button" />
</form>

【讨论】:

【参考方案12】:

只需更改 Tab 键顺序即可完成此操作。把事情简单化。

另一个简单的选择是将后退按钮放在 HTML 代码中的提交按钮之后,但将其浮动到左侧,以便它出现在提交按钮之前的页面上。

【讨论】:

在决定将哪个按钮设为默认按钮时,将忽略 Tab 键顺序。根据 HTML 规范:A form element's default button is the first submit button in tree order whose form owner is that form element.【参考方案13】:

另一个简单的选择是在 HTML 代码中将后退按钮放在提交按钮之后,但将其浮动到左侧,因此它出现在提交按钮之前的页面上。

只需更改 Tab 键顺序即可完成此操作。保持简单。

【讨论】:

【参考方案14】:

The first time I came up against this, I came up with an onclick()/JavaScript hack when choices are not prev/next that I still like for its simplicity.它是这样的:

@model myApp.Models.myModel

<script type="text/javascript">
    function doOperation(op) 
        document.getElementById("OperationId").innerText = op;
        // you could also use Ajax to reference the element.
    
</script>

<form>
  <input type="text" id = "TextFieldId" name="TextField" value="" />
  <input type="hidden" id="OperationId" name="Operation" value="" />
  <input type="submit" name="write" value="Write" onclick='doOperation("Write")'/>
  <input type="submit" name="read" value="Read" onclick='doOperation("Read")'/>
</form>

当点击任一提交按钮时,它会将所需的操作存储在隐藏字段中(该字段是包含在与表单关联的模型中的字符串字段),并将表单提交给控制器,控制器会做出所有决定。在 Controller 中,您只需编写:

// Do operation according to which submit button was clicked
// based on the contents of the hidden Operation field.
if (myModel.Operation == "Read")

     // Do read logic

else if (myModel.Operation == "Write")

     // Do write logic

else

     // Do error logic

您也可以使用数字操作代码稍微加强这一点,以避免字符串解析,但除非您使用枚举,否则代码的可读性、可修改性和自记录性较差,而且解析是微不足道的。

【讨论】:

如果你仔细阅读了这个问题,这里没有提到“点击”提交按钮,只是在文本字段中按 Enter 并定义激活哪个按钮。您提供的代码是针对一个不同的问题,它已经有几个很好的解决方案,尽管您的也是一个不错的解决方案。你有原始问题的解决方案吗?【参考方案15】:

来自https://html.spec.whatwg.org/multipage/forms.html#implicit-submission

表单元素的默认按钮是树中的第一个提交按钮 表单所有者是该表单元素的订单。

如果用户代理支持让用户隐式提交表单 (例如,在某些平台上,在输入文本时按“回车”键 字段被聚焦隐式提交表单)...

让下一个输入为 type="submit" 并将上一个输入更改为 type="button" 应该会提供所需的默认行为。

<form>
   <input type="text" name="field1" /> <!-- put your cursor in this field and press Enter -->

   <input type="button" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
   <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

【讨论】:

【参考方案16】:

这是我尝试过的:

    您需要确保为按钮指定不同的名称 编写一个if 语句,在单击任一按钮时执行所需的操作。

 

<form>
    <input type="text" name="field1" /> <!-- Put your cursor in this field and press Enter -->

    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

php 中,

if(isset($_POST['prev']))

    header("Location: previous.html");
    die();


if(isset($_POST['next']))

    header("Location: next.html");
    die();

【讨论】:

问题是在文本字段上按回车键将使用第一个提交按钮提交表单,而不是使用预期的按钮(示例中的第二个)。找出用于提交表单的提交按钮很容易,这不是问题!【参考方案17】:
<input type="submit" name="prev" value="Previous Page"> 
<input type="submit" name="prev" value="Next Page"> 

保持所有提交按钮的名称相同:“prev”。

唯一的区别是value 属性具有唯一值。当我们创建脚本时,这些唯一值将帮助我们确定按下了哪个提交按钮。

并编写如下代码:

    btnID = ""
if Request.Form("prev") = "Previous Page" then
    btnID = "1"
else if Request.Form("prev") = "Next Page" then
    btnID = "2"
end if

【讨论】:

问题是在文本字段上按回车键将使用第一个提交按钮提交表单,而不是使用预期的按钮(示例中的第二个)。找出用于提交表单的提交按钮很容易,这不是问题!【参考方案18】:

当我发现 ASP 按钮有一个名为 UseSubmitBehavior 的属性时,我试图找到基本相同问题的答案时遇到了这个问题提交。

<asp:Button runat="server" ID="SumbitButton" UseSubmitBehavior="False" Text="Submit" />

以防万一有人正在寻找 ASP.NET 按钮的方式来做到这一点。

【讨论】:

【参考方案19】:

使用 JavaScript(这里是 jQuery),您可以在提交表单之前禁用 prev 按钮。

$('form').on('keypress', function(event) 
    if (event.which == 13) 
        $('input[name="prev"]').prop('type', 'button');
    
);

【讨论】:

【参考方案20】:

我用这种方式解决了一个非常相似的问题:

    如果启用了 JavaScript(现在大多数情况下),那么在通过 JavaScript (jQuery) 加载页面时,所有提交按钮都会“降级”到按钮。 “degraded”按钮类型按钮的点击事件也通过 JavaScript 处理。

    如果未启用 JavaScript,则表单将通过多个提交按钮提供给浏览器。在这种情况下,在表单内的textfield 上点击 Enter 将使用第一个按钮而不是预期的 default 提交表单,但至少该表单仍然可用:您可以使用 prevnext 按钮提交。

工作示例:

<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    </head>

    <body>
        <form action="http://httpbin.org/post" method="post">
            If JavaScript  is disabled, then you CAN submit the form
            with button1, button2 or button3.

            If you press enter on a text field, then the form is
            submitted with the first submit button.

            If JavaScript is enabled, then the submit typed buttons
            without the 'defaultSubmitButton' style are converted
            to button typed buttons.

            If you press Enter on a text field, then the form is
            submitted with the only submit button
            (the one with class defaultSubmitButton)

            If you click on any other button in the form, then the
            form is submitted with that button's value.

            <br />

            <input type="text" name="text1" ></input>
            <button type="submit" name="action" value="button1" >button 1</button>
            <br />

            <input type="text" name="text2" ></input>
            <button type="submit" name="action" value="button2" >button 2</button>
            <br />

            <input type="text" name="text3" ></input>
            <button class="defaultSubmitButton" type="submit" name="action" value="button3" >default button</button>
        </form>

        <script>
            $(document).ready(function()

                /* Change submit typed buttons without the 'defaultSubmitButton'
                   style to button typed buttons */
                $('form button[type=submit]').not('.defaultSubmitButton').each(function()
                    $(this).attr('type', 'button');
                );

                /* Clicking on button typed buttons results in:
                   1. Setting the form's submit button's value to
                      the clicked button's value,
                   2. Clicking on the form's submit button */
                $('form button[type=button]').click(function( event )
                    var form = event.target.closest('form');
                    var submit = $("button[type='submit']",form).first();
                    submit.val(event.target.value);
                    submit.click();
                );
            );
        </script>
    </body>
</html>

【讨论】:

【参考方案21】:

您可以使用Tabindex 来解决此问题。更改按钮的顺序也是实现此目的的更有效方法。

更改按钮的顺序并添加 float 值,以将它们分配到您希望在 HTML 视图中显示的位置。

【讨论】:

【参考方案22】:

与其苦于多次提交、JavaScript 或类似的东西来做一些上一个/下一个事情,另一种选择是使用轮播来模拟不同的页面。 这样做:

您不需要多个按钮、输入或提交来执行上一个/下一个操作,您只有一个 input type="submit" 和一个 form。 在提交表单之前,整个表单中的值都存在。 用户可以完美地转到任何上一页和任何下一页来修改值。

使用 Bootstrap 5.0.0 的示例:

<div id="carousel" class="carousel slide" data-ride="carousel">
    <form action="index.php" method="post" class="carousel-inner">
        <div class="carousel-item active">
            <input type="text" name="lastname" placeholder="Lastname"/>
        </div>
        <div class="carousel-item">
            <input type="text" name="firstname" placeholder="Firstname"/>
        </div>
        <div class="carousel-item">
            <input type="submit" name="submit" value="Submit"/>
        </div>
    </form>
    <a class="btn-secondary" href="#carousel" role="button" data-slide="prev">Previous page</a>
    <a class="btn-primary" href="#carousel" role="button" data-slide="next">Next page</a>
</div>

【讨论】:

【参考方案23】:

一种可能比 CSS 浮动方法更现代的方法可能是使用 flexbox 和弹性项目上的 order 属性的解决方案。可能是这样的:

<div style="display: flex">
  <input type="submit" name="next" value="Next Page" style="order: 1" />
  <input type="submit" name="prev" value="Previous Page" style="order: 0" />
</div>

当然,这是否可行取决于您的文档结构,但我发现弹性项目比浮动元素更容易控制。

【讨论】:

【参考方案24】:

我认为这是一个简单的解决方案。将 Previous 按钮 type 更改为 button,并将新的 onclick 属性添加到值为 jQuery(this).attr('type','submit'); 的按钮。

因此,当用户单击上一个按钮时,其type 将更改为submit,并且表单将使用上一个按钮提交。

<form>
  <!-- Put your cursor in this field and press Enter -->
  <input type="text" name="field1" />

  <!-- This is the button that will submit -->
  <input type="button" onclick="jQuery(this).attr('type','submit');" name="prev" value="Previous Page" />

  <!-- But this is the button that I WANT to submit -->
  <input type="submit" name="next" value="Next Page" />
</form>

【讨论】:

【参考方案25】:

当一个按钮被鼠标点击(希望是触摸)时,它会记录 X,Y 坐标。当它被表单调用时,情况并非如此,这些值通常为零。

所以你可以这样做:

function(e) 
  const isArtificial = e.screenX === 0 && e.screenY === 0
    && e.x === 0 && e.y === 0
    && e.clientX === 0 && e.clientY === 0;

    if (isArtificial) 
      return; // DO NOTHING
     else 
      // OPTIONAL: Don't submit the form when clicked
      // e.preventDefault();
      // e.stopPropagation();
    

    // ...Natural code goes here

【讨论】:

您似乎将多个按钮输入与单个图像输入混淆了。 不是真的,e 应该是MouseEvent。查看属性 (developer.mozilla.org/en-US/docs/Web/API/MouseEvent)。 如果按钮是用鼠标单击的,isArtificial 将为 false。因为,clientXclientY 这样的属性不会为零,而是鼠标坐标。 什么是“自然密码” 是的,回想起来我本可以更清楚地表达这个答案。在这种情况下,自然代码是指用于表单未自动调用事件处理程序的实例的代码。用户主动单击(或点击)提交按钮的实例。【参考方案26】:

使用您给出的示例:

<form>
    <input type="text" name="field1" /><!-- Put your cursor in this field and press Enter -->
    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

如果您点击“上一页”,则只会提交“上一页”的值。如果您点击“下一页”,则只会提交“下一页”的值。

但是,如果您在表单的某处按 Enter,则“prev”和“next”都不会提交。

因此,使用伪代码您可以执行以下操作:

If "prev" submitted then
    Previous Page was click
Else If "next" submitted then
    Next Page was click
Else
    No button was click

【讨论】:

没有任何按钮被触发的情况(不使用js)。如果您按 ENTER 键,代码中的第一个按钮将捕获该事件。在 html 示例中,它是 prev 按钮。

以上是关于HTML 表单中的多个提交按钮的主要内容,如果未能解决你的问题,请参考以下文章

HTML 表单上的多个提交按钮 - 将一个按钮指定为默认按钮 [重复]

JavaScript给表单提交加上回车按钮,大侠请帮忙 答好我会在加分的 谢谢!!

如何在一个form里用多个提交按钮

HTML 表单上的默认提交按钮是如何确定的?

如何使用 Angular JS 处理表单中的多个提交按钮?

Rails:一个表单中的多个提交按钮