ChatGPT解决这个技术问题 Extra ChatGPT

HTML 表单中的多个提交按钮

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

例子:

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

仅用于浮动:左

P
Peter Mortensen

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

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

.f { 浮动:对; } .clr { 明确:两者; }

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


请不要在不更改选项卡顺序的情况下执行此操作,以便点击选项卡按钮将在按钮出现在屏幕上时循环显示它们。
可悲的是,这仅在按钮彼此相对靠近时才有效。在更复杂的情况下,比如一个更大的页面,每个角落都有几个按钮,但都在一个单一的形式中,这根本无法管理。
P
Peter Mortensen

将之前的按钮类型更改为这样的按钮:

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

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

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

您在说什么 default 属性? 没有有效的“默认”属性:w3.org/html/wg/drafts/html/master/…(不在 HTML5、HTML 4.01 Transitional/Strict、XHTML 1.0 Strict 中)。而且我不明白为什么将输入类型从 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 属性,但仅限于 <track> 标记:developer.mozilla.org/en-US/docs/Web/HTML/Element/track
P
Peter Mortensen

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

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

当用户按下 Enter 并且 request 转到服务器时,您可以在包含表单 {3 的集合的服务器端代码上检查 submitButton 的值} 对。例如,在 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'”也会破坏您的网站功能。
P
Peter Mortensen

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

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


A
AliNajafZadeh

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

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

过滤结果

过滤结果 1 过滤结果 2 过滤结果 3
< /div>


P
Peter Mortensen

纯 HTML 无法做到这一点。你必须依靠 JavaScript 来实现这个技巧。

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

Form1 将具有上一个按钮。

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

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


P
Peter Mortensen

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

这里有两个页面提供了有关如何执行此操作的技术:12。基于这些,这里是一个使用示例(基于 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。在支持


K
Kenny Johnson

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

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


在决定将哪个按钮作为默认按钮时,将忽略 Tab 键顺序。根据 HTML 规范:A form element's default button is the first submit button in tree order whose form owner is that form element.
P
Peter Mortensen

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

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


P
Peter Mortensen

我第一次出现了这一点时,当我不喜欢/下一个我仍然喜欢它的简单性时,我想出了一个onclick()/javascript hack。它是这样的:

@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 并定义激活哪个按钮。您提供的代码是针对一个不同的问题,它已经有几个很好的解决方案,尽管您的也是一个不错的解决方案。您对原始问题有解决方案吗?
n
nikkypx

来自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>

P
Peter Mortensen

这是我尝试过的:

您需要确保为您的按钮指定不同的名称 编写一个 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();
}

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

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

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

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


T
Tylla
<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

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

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

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

P
Peter Mortensen

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

如果启用了 JavaScript(现在大多数情况下),那么所有提交按钮都会在通过 JavaScript (jQuery) 加载页面时“降级”为按钮。 “降级”按钮类型按钮上的单击事件也通过 JavaScript 处理。如果未启用 JavaScript,则表单将通过多个提交按钮提供给浏览器。在这种情况下,在表单中的文本字段上按 Enter 将使用第一个按钮而不是预期的默认按钮提交表单,但至少该表单仍然可用:您可以使用 prev 和 next 按钮提交。

工作示例:

< form action="http://httpbin.org/post" method="post"> 如果 JavaScript 被禁用,那么您可以使用 button1、button2 或 button3 提交表单。如果您在文本字段上按 Enter,则表单将使用第一个提交按钮提交。如果启用了 JavaScript,则不带“defaultSubmitButton”样式的提交类型按钮将转换为按钮类型按钮。如果您在文本字段上按 Enter,则表单将使用唯一的提交按钮(具有类 defaultSubmitButton 的按钮)提交。如果您单击表单中的任何其他按钮,则使用该按钮的值提交表单。

< input type="text" name="text2" >


P
Peter Mortensen

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

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


S
Stoppeye

一种可能比 CSS 浮动方法更现代的方法可能是使用 flexbox 和 flex 项目上的 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>

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


佚名

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

您不需要多个按钮、输入或提交来执行上一个/下一个操作,您只有一个输入类型=“提交”,只有一种形式。

在提交表单之前,整个表单中的值都存在。

用户可以完美地转到任何上一页和任何下一页来修改值。

使用 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>

P
Peter Mortensen

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

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

<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>

M
Motine

问题

一个表单可能有多个提交按钮。在任何输入中按返回时,浏览器将使用第一个提交按钮。但是,有时我们希望默认使用不同的/稍后的按钮。

选项

先添加一个隐藏的提交按钮,动作相同(☹️重复) 把想要的提交按钮先放在表单中,然后通过CSS移动到正确的地方(☹️可能不可行,可能会导致样式繁琐) 改变处理通过 JavaScript 输入的所有表单中的返回键(☹️ 需要 javascript)

没有一个选项是理想的,所以我们选择 3。因为大多数浏览器都启用了 JavaScript。

选择的解决方案

// 示例实现 document.addEventListener('DOMContentLoaded', (ev) => { for (const defaultSubmitInput of document.querySelectorAll('[data-default-submit]')) { for (const formInput of defaultSubmitInput.form.querySelectorAll( 'input')) { if (formInput.dataset.ignoreDefaultSubmit != undefined) { continue; } formInput.addEventListener('keypress', (ev) => { if (ev.keyCode == 13) { ev.preventDefault() ; defaultSubmitInput.click(); } }) } } });

当用鼠标单击按钮(希望通过触摸)时,它会记录 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 这样的属性不会为零,而是鼠标坐标。
什么是“自然密码”?
是的,回想起来,我本可以更清楚地表达这个答案。在这种情况下,自然代码是指用于表单未自动调用事件处理程序的实例的代码。用户主动单击(或点击)提交按钮的实例。
P
Peter Mortensen

使用您给出的示例:

<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 按钮。