javascript - input默认值 - js阻止表单提交




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

Andrezj几乎被钉上了......但这是一个简单的跨浏览器解决方案。

采取这样的形式:

<form>
    <input/>
    <button type="submit" value="some non-default action"/>
    <button type="submit" value="another non-default action"/>
    <button type="submit" value="yet another non-default action"/>

    <button type="submit" value="default action"/>
</form>

并重构为:

<form>
    <input/>

    <button style="overflow: visible !important; height: 0 !important; width: 0 !important; margin: 0 !important; border: 0 !important; padding: 0 !important; display: block !important;" type="submit" value="default action"/>

    <button type="submit" value="some non-default action"/>
    <button type="submit" value="another non-default action"/>
    <button type="submit" value="yet another non-default action"/>
    <button type="submit" value="still another non-default action"/>

    <button type="submit" value="default action"/>
</form>

由于W3C规范指出多个提交按钮是有效的,但忽略了用户代理应该如何处理这些按钮的指导,因此浏览器制造商应该按照他们认为合适的方式实施。 我发现他们会提交表单中的第一个提交按钮,或者在当前拥有焦点的表单字段之后提交下一个提交按钮。

不幸的是,简单地添加一种显示风格:无; 将无法工作,因为W3C规范指出任何隐藏的元素都应该从用户交互中排除。 因此,请将其隐藏在明显的视线内!

以上是我最终投入生产的解决方案的一个例子。 按下Enter键会触发默认表单提交行为,如预期的那样,即使存在其他非默认值并且位于DOM中的默认提交按钮之前。 用于显式用户输入的鼠标/键盘交互附加功能,同时避免使用javascript处理程序。

注意:通过窗体标签不会显示任何视觉元素的焦点,但仍然会导致不可见按钮被选中。 为了避免这个问题,只需相应地设置tabindex属性并省略不可见提交按钮上的tabindex属性。 尽管将这些风格推广为重要,但它们应该防止任何框架或现有按钮样式干扰此修补程序。 另外,这些内联样式绝对是不好的形式,但我们在这里证明了概念......不写代码。

如果表单被提交但不是由任何特定的按钮,如

  • Enter键
  • 在JS中使用HTMLFormElement.submit()

一个浏览器应该如何确定使用多个提交按钮中的哪一个作为被按下的按钮?

这在两个层面上是重要的:

  • 调用附加到提交按钮的onclick事件处理程序
  • 将数据发送回Web服务器

迄今为止我的实验表明:

  • 当按Enter键时 ,Firefox,Opera和Safari使用表格中的第一个提交按钮
  • 当按Enter键时 ,IE根据我无法弄清的情况使用第一个提交按钮或者根本不使用
  • 所有这些浏览器根本没有使用JS提交

标准说什么?

如果它有帮助,这里是我的测试代码(PHP只与我的测试方法有关,而不是我的问题本身)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>

<body>

<h1>Get</h1>
<dl>
<?php foreach ($_GET as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>

<h1>Post</h1>
<dl>
<?php foreach ($_POST as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>

<form name="theForm" method="<?php echo isset($_GET['method']) ? $_GET['method'] : 'get'; ?>" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
    <input type="text" name="method" />
    <input type="submit" name="action" value="Button 1" onclick="alert('Button 1'); return true" />
    <input type="text" name="stuff" />
    <input type="submit" name="action" value="Button 2" onclick="alert('Button 2'); return true" />
    <input type="button" value="submit" onclick="document.theForm.submit();" />
</form>

</body></html>

HTML 4没有明确说明。 目前的HTML5工作草案规定,第一个提交按钮必须是默认的

form元素的默认按钮是树形次序中的第一个提交按钮 ,其表单所有者是该form元素。

如果用户代理支持让用户隐式提交表单(例如,在某些平台上点击“输入”键,而文本字段集中隐式提交表单),那么对于默认按钮具有定义的激活的表单行为必须使用户代理在该默认按钮运行合成点击激活步骤


从你的评论:

结果是,如果你有多个表单提交给同一个脚本,你不能依靠提交按钮来区分它们。

我在每个表单中放置一个<input type="hidden" value="form_name" />

如果使用javascript进行提交:将提交事件添加到表单中,请勿将事件单击到其按钮上。 Saavy用户不会经常触摸他们的鼠标。


奇怪的是,第一个按钮回到总是第一个按钮,不管是否可见,例如使用jquery show/hide() 。 添加属性.attr('disabled', 'disabled')防止完全接收Enter提交按钮。 例如,在记录对话框中调整插入/编辑+删除按钮的可见性时会出现问题。 我发现在插入前放置编辑的方式不那么简单

<button type="submit" name="action" value="update">Update</button>
<button type="submit" name="action" value="insert">Insert</button>
<button type="submit" name="action" value="delete">Delete</button>

并使用JavaScript代码:

$("#formId button[type='submit'][name='action'][value!='insert']").hide().attr('disabled', 'disabled');
$("#formId button[type='submit'][name='action'][value='insert']").show().removeAttr('disabled');

当您在一个表单中有多个提交按钮,并且用户按下ENTER键从文本字段提交表单时,此代码通过从按键事件调用表单上的提交事件来覆盖默认功能。 代码如下:

$('form input').keypress(function(e){

    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)){ $(e.target).closest('form').submit(); return false; }
    else return true;

});

我使用的另一个解决方案是在表单中只有一个按钮,并假冒其他按钮。

这是一个例子:

<form>
  <label for="amount">Amount of items</label>
  <input id="amount" type="text" name="amount" />
  <span id="checkStock" class="buttonish">Check stock</span>
  <button type="submit" name="action" value="order">Place order</button>
</form>

然后,我将span元素设计为一个按钮。 JS侦听器观察该跨度,并在单击后执行所需的操作。

不一定适合所有情况,但至少这很容易做到。


我有一个带有11个提交按钮的表单,当用户按下回车键时,它总是使用第一个提交按钮。 我在其他地方看到,在表单上有多个提交按钮并不是一个好主意(不好的做法),最好的方法是将默认按钮作为表单上唯一的提交按钮。 其他按钮应该变成“TYPE = BUTTON”,并添加一个onClick事件,它在Javascript中调用你自己的提交例程。 像这样的东西: -

<SCRIPT Language="JavaScript">
function validform()
{
  // do whatever you need to validate the form, and return true or false accordingly
}

function mjsubmit()
{
  if (validform()) { document.form1.submit(); return true;}
  return false;
}
</SCRIPT>
<INPUT TYPE=BUTTON NAME="button1" VALUE="button1" onClick="document.form1.submitvalue='button1'; return mjsubmit();">
<INPUT TYPE=BUTTON NAME="button2" VALUE="button2" onClick="document.form1.submitvalue='button2'; return mjsubmit();">
<INPUT TYPE=SUBMIT NAME="button3" VALUE="button3" onClick="document.form1.submitvalue='button3'; return validform();">
<INPUT TYPE=BUTTON NAME="button4" VALUE="button4" onClick="document.form1.submitvalue='button4'; return mjsubmit();">

这里,button3是默认的,虽然你用其他按钮以编程方式提交表单,但mjsubmit例程会验证它们。 HTH。


我的食谱:

<form>
<input type=hidden name=action value=login><!-- the magic! -->

<input type=text name=email>
<input type=text name=password>

<input type=submit name=action value=login>
<input type=submit name=action value="forgot password">
</form>

如果没有按钮被点击,它将发送默认隐藏字段。

如果他们被点击,他们有偏好,并且它的价值被传递。


来自HTML 4规范

如果表单包含多个提交按钮,则只有激活的提交按钮成功。

这意味着给定多于1个提交按钮而没有激活(点击),没有一个应该成功。

我认为这是有道理的:想象一个包含多个提交按钮的巨大表单。 在顶部,有一个“删除此记录”按钮,然后有很多输入,底部有一个“更新此记录”按钮。 用户在表单底部的字段中按下Enter键时,不会怀疑他隐式地从顶部点击“删除此记录”。

因此,我认为使用第一个或任何其他按钮并不是一个好主意,用户不会定义(单击)一个按钮。 尽管如此,浏览器当然也在这样做。


现在可以使用flexbox来解决这个问题了:

HTML

<form>
    <h1>My Form</h1>
    <label for="text">Input:</label>
    <input type="text" name="text" id="text"/>

    <!-- Put the elements in reverse order -->
    <div class="form-actions">
        <button>Ok</button> <!-- our default action is first -->
        <button>Cancel</button>
    </div>
</form>

CSS

.form-actions {
    display: flex;
    flex-direction: row-reverse; /* reverse the elements inside */
}


使用弹性框,我们可以通过使用CSS规则来反转使用display: flex的容器中元素的顺序: flex-direction: row-reverse 。 这不需要CSS或隐藏的元素。 对于不支持flexbox的旧版浏览器,他们仍然可以获得可行的解决方案,但这些元素不会被颠倒过来。

演示
http://codepen.io/Godwin/pen/rLVKjm





standards