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

Posted

技术标签:

【中文标题】HTML 表单上的多个提交按钮 - 将一个按钮指定为默认按钮 [重复]【英文标题】:Multiple submit buttons on HTML form – designate one button as default [duplicate] 【发布时间】:2010-12-30 02:42:37 【问题描述】:

我有一个包含三个提交按钮的表单,如下所示:

<input type="submit" name="COMMAND" value="&lsaquo; Prev">
<input type="submit" name="COMMAND" value="Save">
<input type="reset"  name="NOTHING" value="Reset">
<input type="submit" name="COMMAND" value="Next &rsaquo;">
<input type="button" name="NOTHING" value="Skip &rsaquo;" onclick="location = 'yada-yada.asp';">

按钮行混合了提交、重置和 javascript 按钮。按钮的顺序可能会发生变化,但在任何情况下,保存按钮都会保留在上一个和下一个按钮之间。

这里的问题是当用户点击Enter提交表单时,post变量“COMMAND”包含“Prev”;正常,因为这是表单上的第一个提交按钮。但是,我希望在用户通过 Enter 按钮提交表单时触发“下一步”按钮。这有点像将其设置为默认提交按钮,即使它之前还有其他按钮。

【问题讨论】:

如果您(或其他任何人)有兴趣,我有一个类似的问题,并使用这个 (***.com/questions/12082683/…) css 技巧将我的主要提交按钮放在表单的顶部,但显示它位于表单的底部,容器是唯一需要固定尺寸的元素(padding-bottom 表示主提交按钮的高度或包含元素),因此它可以轻松地根据表单内容动态增长 necrothread 回答:如果您碰巧在服务器端使用 ASP.NET WebForms,请附上&lt;ASP:Panel Defaultbutton="btnThatShouldBeDefault"&gt;。这会根据插入符号的位置自动生成 javascript,从而使正确的按钮成为默认按钮。 Multiple submit buttons in an html form 的可能重复项 【参考方案1】:

第一个按钮始终是默认按钮;它不能改变。虽然您可以尝试使用 JavaScript 修复它,但表单在没有脚本的浏览器中会出现意外行为,并且需要考虑一些可用性/可访问性的极端情况。例如,Zoran 链接的代码会在&lt;input type="button"&gt; 中意外地在 Enter 键中提交表单,这通常不会发生,并且不会捕获 IE 提交表单以在其他非字段内容上按 Enter 键的行为在表格中。因此,如果您使用该脚本在表单中单击 &lt;p&gt; 中的某些文本并按 Enter,则将提交错误的按钮……如果如该示例中给出的那样,真正的默认按钮是“删除”,则尤其危险!

我的建议是忘记使用脚本技巧来重新分配默认值。跟随浏览器的流程,只需将默认按钮放在第一位。如果您无法破解布局来为您提供所需的屏幕顺序,那么您可以通过在源代码中首先使用一个虚拟的不可见按钮来做到这一点,其名称/值与您想要默认的按钮相同:

<input type="submit" class="defaultsink" name="COMMAND" value="Save" />

.defaultsink 
    position: absolute; left: -100%;

(注意:定位用于将按钮按下屏幕外,因为display: nonevisibility: hidden 对按钮是否被视为默认以及是否已提交具有浏览器变量的副作用。)

【讨论】:

在您的引导下,我发现以下对我有用:&lt;input type="submit" name="..." value="..." style="display:none;" /&gt; 位于 &lt;form&gt; 标记的正下方,复制了稍后出现在表单中的可见按钮。 第一个按钮是默认按钮,但可以更改:-)。对非默认按钮使用 type=button,对默认按钮使用 type=submit(示例如下:***.com/a/24245422/774971) @GrahamKlyne - display:none 在当今的浏览器中无法始终如一地工作。例如,请参阅codepen.io/shanplourde/pen/pJYrJV。 @dmitry_romanov + 他的评论支持者:不,type=button不会提交表单,因此不会解决 OP 的问题,根据@spikyjt 的评论(在上面某处) . @Sz。它被写成“设置类型=提交到你想默认的按钮……”;其他按钮的作用取决于 UI 创建者。问题是不是让第一个按钮成为默认按钮,而是另一个按钮,这是通过技巧解决的。我有同样的问题,解决方案对我很有效:-)【参考方案2】:

我的建议是不要反对这种行为。您可以使用浮点数有效地更改顺序。例如:

<p id="buttons">
<input type="submit" name="next" value="Next">
<input type="submit" name="prev" value="Previous">
</p>

与:

#buttons  overflow: hidden; 
#buttons input  float: right; 

将有效地颠倒顺序,因此“下一步”按钮将是按回车键触发的值。

这种技术将涵盖许多情况,而无需求助于更骇人听闻的 JavaScript 方法。

【讨论】:

还有其他可能的“CSS”定位技巧吗? 我设法将下一个按钮向右推(1)向右浮动(2)所有其他按钮向左浮动(3)所有按钮显示块(4)所有按钮,包括下一个按钮,按源顺序指定。 效果很好,谢谢!我只是补充一点,如果您希望按钮组仍然向左浮动,只需将“按钮”id 元素括在浮动左 div 中,然后您的按钮将根据需要重新排序,下一个在上一个之后,但按钮组将保持向左浮动。 谢谢,这个解决方案很棒!!!我在想一些丑陋的 javascript hack。 这个解决方案的主要问题是它破坏了标签索引。使用 CSS 重新定位按钮不会改变它们的 tabindex 顺序。所以按标签不会始终从上/下,从左到右。有关解决此问题的解决方案,请参阅 ***.com/a/31911751/442472。【参考方案3】:

type=submit 设置为您希望默认的按钮,将type=button 设置为其他按钮。现在在下面的表单中,您可以在任何输入字段中按 Enter,Render 按钮将起作用(尽管它是表单中的第二个按钮)。

例子:

    <button id='close_button' class='btn btn-success'
            type=button>
      <span class='glyphicon glyphicon-edit'> </span> Edit program
    </button>
    <button id='render_button' class='btn btn-primary'
            type=submit>             <!--  Here we use SUBMIT, not BUTTON -->
      <span class='glyphicon glyphicon-send'> </span> Render
    </button>

在 FF24 和 Chrome 35 中测试。

【讨论】:

除了type="button"不提交表单。这里的要求是其他按钮仍然提交表单,但不是默认的。需要额外的 javascript 才能让他们提交表单,这意味着最好使用 CSS 重新定位。【参考方案4】:

Quick'n'dirty 你可以创建一个隐藏的提交按钮副本,当按下回车键时应该使用它。

示例 CSS

input.hidden 
    width: 0px;
    height: 0px;
    margin: 0px;
    padding: 0px;
    outline: none;
    border: 0px;

示例 HTML

<input type="submit" name="next" value="Next" class="hidden" />
<input type="submit" name="prev" value="Previous" />
<input type="submit" name="next" value="Next" />

如果现在有人在您的表单中点击输入,(隐藏的)下一步按钮将用作提交者。

在 IE9、Firefox、Chrome 和 Opera 上测试

【讨论】:

我唯一的其他建议是确保您解决可访问性问题和 tabindex 问题。由于该按钮在技术上并未隐藏,因此实际上只有屏幕阅读器和辅助设备才能识别该按钮。此外,按钮仍然是可选项卡的。设置 tabindex="-1" 可以纠正这个问题。 要对辅助工具(屏幕阅读器)隐藏按钮,请将 role=none 添加到其属性中。 一个简单的“显示:无;”似乎也有效?这还解决了屏幕阅读器问题。 "display: none" 不适用于我测试过的所有浏览器/浏览器版本。 除上述之外,使用display: none 在 Firefox 和 Chrome 中有效,但在 Safari 中无效。为了获得最佳的跨浏览器支持,我使用了以下 CSS:height: 0; visibility: hidden;,并具有以下属性:aria-hidden="true" tabindex="-1"【参考方案5】:

如果您使用的是 jQuery,here 的评论中的这个解决方案非常巧妙:

$(function()
    $('form').each(function () 
        var thisform = $(this);
        thisform.prepend(thisform.find('button.default').clone().css(
            position: 'absolute',
            left: '-999px',
            top: '-999px',
            height: 0,
            width: 0
        ));
    );
);

只需将class="default" 添加到您想成为默认按钮的按钮。它将该按钮的隐藏副本放在表单的开头。

【讨论】:

【参考方案6】:

我正在复活这个,因为我正在研究一种非 JavaScript 的方法来做到这一点。我没有进入关键处理程序,并且 CSS 定位的东西导致制表符顺序中断,因为 CSS 重新定位不会更改制表符顺序。

我的解决方案基于https://***.com/a/9491141 的回复。

解决方案来源如下。 tabindex 用于纠正隐藏按钮的选项卡行为,以及 aria-hidden 以避免屏幕阅读器读出按钮/辅助设备识别按钮。

<form method="post" action="">
  <button type="submit" name="useraction" value="2nd" class="default-button-handler" aria-hidden="true" tabindex="-1"></button>
  <div class="form-group">
    <label for="test-input">Focus into this input: </label>
    <input type="text" id="test-input" class="form-control" name="test-input" placeholder="Focus in here and press enter / go" />
  </div>

DOM 中的第一个按钮 DOM 中的第二个按钮 DOM 中的第三个按钮

此解决方案的基本 CSS:

.default-button-handler 
  width: 0;
  height: 0;
  padding: 0;
  border: 0;
  margin: 0;

【讨论】:

虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。【参考方案7】:

另一种解决方案,使用 jQuery:

$(document).ready(function() 
  $("input").keypress(function(e) 
    if (e.which == 13) 
      $('#submit').click();
      return false;
    

    return true;
  );
);

这应该适用于以下表单,使“更新”成为默认操作:

<form name="f" method="post" action="/action">
  <input type="text" name="text1" />
  <input type="submit" name="button2" value="Delete" />
  <input type="submit" name="button1" id="submit" value="Update" />
</form>

还有:

<form name="f" method="post" action="/action">
  <input type="text" name="text1" />
  <button type="submit" name="button2">Delete</button>
  <button type="submit" name="button1" id="submit">Update</button>
</form>

仅当表单上的输入字段具有焦点时,才会捕获 Enter 键。

【讨论】:

【参考方案8】:

您不应该使用同名按钮。这是不好的语义。相反,您应该修改后端以查找设置的不同名称值:

<input type="submit" name="COMMAND_PREV" value="&lsaquo; Prev">
<input type="submit" name="COMMAND_SAVE" value="Save">
<input type="reset"  name="NOTHING" value="Reset">
<input type="submit" name="COMMAND_NEXT" value="Next &rsaquo;">
<input type="button" name="NOTHING" value="Skip &rsaquo;" onclick="window.location = 'yada-yada.asp';">

由于我不知道你在后台使用的是什么语言,我给你一些伪代码:

if (input name COMMAND_PREV is set) 

 else if (input name COMMAND_SAVE is set) 

 else if (input name COMMENT_NEXT is set) 


【讨论】:

+1 依靠按钮的value 来决定哪个被点击是非常脆弱的。任何小的 UI 更改或本地化工作都需要更改支持以检测它。此外,其中包含非 ASCII 字符,您需要绝对确保您的编码在任何地方都设置正确! 嗯...我可以忍受,但这仍然意味着“上一个”充当“默认”按钮。 @Salman,您应该将我的建议与@cletus 关于 CSS 定位的建议结合使用,以确保您首先正确声明默认按钮。 这是一个有效的观点,但它没有回答问题。【参考方案9】:

bobince 的解决方案的缺点是创建一个按钮,该按钮可以 Tab-d 结束,但在其他方面无法使用。这会给键盘用户造成混乱。

另一种解决方案是使用鲜为人知的form 属性:

<form>
    <input name="data" value="Form data here">
    <input type="submit" name="do-secondary-action" form="form2" value="Do secondary action">
    <input type="submit" name="submit" value="Submit">
</form>

<form id="form2"></form>

这是standard HTML,但遗憾的是 Internet Explorer 不支持。

【讨论】:

规范似乎没有表明设置表单所有者会导致该按钮充当默认按钮,您确认了吗?似乎存在 owner 属性以解决嵌套的 HTML 表单。另外,如果多个按钮分配了相同的表单属性会怎样? IIRC 规范说默认按钮是表单拥有的 DOM 顺序中的第一个按钮。多个按钮仍然符合该规则 - 就提交表单而言,它们就好像它们是表单的一部分一样(因此第一个是默认设置)。 正确,但表单所有者隐含为当前表单。如果您不指定 form 属性,则拥有的表单隐含为按钮/输入的第一个父表单。在单一表单方案中,您的建议不起作用,因为每个提交按钮都假定相同的表单所有者。例如,您将无法让 enter 键提交该表单上 3 个按钮中的第 2 个。 查看codepen.io/shanplourde/pen/VLRrJw 的演示,确认表单所有者不是一个可行的解决方案,因为它最终会提交另一个表单,而不是包含按钮表单的 DOM。如果您强烈认为您的解决方案在某些方面是有效的,请随意分叉代码笔并对其进行修改。 呃,是的,它当然会提交所有者表单。我认为这很明显。不是问题,例如“删除”或“取消”操作,您可以使用隐藏输入来识别项目。

以上是关于HTML 表单上的多个提交按钮 - 将一个按钮指定为默认按钮 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

用两个提交按钮区分 HTML 表单上的提交按钮 [重复]

HTML 表单中的多个提交按钮

jQuery Validation - 一个 asp.net 表单上的多个提交按钮,不同的验证组?

php一个表单提交多个页面,怎样获取按钮提交过来的值

如何在具有 Ajax 的单个表单中使用多个提交按钮 [关闭]

提交表单上的阻止按钮