在表单提交时禁用按钮,但发布按钮值

时间:2022-11-19 15:54:16

I want to prevent multiple form submissions, but I need to have the value of the submit element posted back to the server (so that I know which button the user clicked on).

我希望避免多个表单提交,但我需要将submit元素的值返回给服务器(以便我知道用户单击的是哪个按钮)。

Most of the Internet Wisdom concerning suppression of multiple form submissions seems to involve disabling the submit button during form submission. This prevents the button from being clicked a second time, but also prevents its value from being posted.

大多数关于压制多个表单提交的互联网智慧似乎包括在提交表单时禁用提交按钮。这可以防止按钮再次被单击,但也可以防止它的值被发布。

I've found a few examples of JS code that hides the submit button(s), which allows their values to be posted. But those examples all replace the (now hidden) button with some sort of "processing..." message. I really want a solution that presents the user with a disabled button but still posts the button value.

我已经找到了几个隐藏submit按钮(s)的JS代码示例,该按钮允许发布它们的值。但是这些示例都用某种“处理…”消息替换(现在隐藏的)按钮。我确实需要一个解决方案,它向用户呈现一个禁用按钮,但仍然会发布按钮值。

I should add that I'd prefer a solution that works with standard HTML one would find in most forms. No magic IFrames, hidden fields, id or class names, etc. I want a JS function I can stash away in a library and reference from all of my existing forms to enable this new behavior.

我应该补充一点,我更喜欢在大多数表单中使用标准HTML的解决方案。没有神奇的iframe、隐藏字段、id或类名等。

(I have a solution, which I will post as an answer. But I had to ask the question to comply with the Zen of SO.)

我有一个解决方案,我将把它作为一个答案。但我必须问这个问题才能符合SO的精髓。

5 个解决方案

#1


6  

Here is (yet another) answer to the question of how to deal with preventing the user from clicking on the form submission button more than once. This solution makes it appear that the button has been disabled.

下面是如何防止用户多次单击表单提交按钮的问题的另一个答案。此解决方案使按钮看起来已被禁用。

Under the covers, it creates a disabled button to display to the user, and hides the actual button so that its value is posted. I also move the hidden button so that the extra element doesn't mess up CSS selectors.

在幕后,它创建一个禁用的按钮来显示给用户,并隐藏实际的按钮,以便其值被发布。我还移动了隐藏按钮,以便额外的元素不会打乱CSS选择器。

Also note the check for invalid form fields. If you omit this check, and form validation fails, then the user winds up with a form that wasn't posted (because client-side validation failed) but the buttons are disabled.

还要注意检查无效的表单字段。如果您省略了这个检查,并且表单验证失败,那么用户最终会得到一个没有发布的表单(因为客户端验证失败),但是按钮被禁用。

// Disables buttons when form is submitted
$('form').submit(function () {
    // Bail out if the form contains validation errors
    if ($.validator && !$(this).valid()) return;

    var form = $(this);
    $(this).find('input[type="submit"], button[type="submit"]').each(function (index) {
        // Create a disabled clone of the submit button
        $(this).clone(false).removeAttr('id').prop('disabled', true).insertBefore($(this));

        // Hide the actual submit button and move it to the beginning of the form
        $(this).hide();
        form.prepend($(this));
    });
});

#2


2  

Because you can submit a form other ways than simply clicking the submit button it's better to add a listener to the form's submit event rather than the click event on the submit button. This jQuery event listener should work on any form and prevent it from being submitted more than once.

因为您可以通过其他方式提交表单,而不只是单击submit按钮,所以最好向表单的submit事件添加侦听器,而不是在submit按钮上添加click事件。这个jQuery事件侦听器应该处理任何表单,并防止它被提交多次。

$('form').on('submit', function(e) {
    if (!$(this).data('submitted')) {
        $(this).data('submitted', true);
    }
    else {
        e.preventDefault();
    }
});

To make the form look disabled you could add some css that makes the form look disabled and then add the classname on form submission.

要使表单看起来是禁用的,您可以添加一些css,使表单看起来是禁用的,然后在表单提交中添加classname。

$('form').on('submit', function(e) {
    if (!$(this).data('submitted')) {
        $(this).data('submitted', true).addClass('disabled');
    }
    else {
        e.preventDefault();
    }
});

#3


1  

You can simulate disabled look behavior. E.g. if you have a button like this:

您可以模拟残疾人的外观行为。如果你有这样一个按钮:

<input id="btn" type="button" onclick="disableMe(this)" value="Submit" />

You can define CSS like this

你可以这样定义CSS

.disabled {
    backround-color:grey;
    color:darkgrey;
}

And JS like this

和JS这样

function disableMe(btn) {
    btn.className = "disabled";
    btn.onclick = function(){return false}
}

What will happen - on first click button will become grey (via applied CSS) and onclick event will change to "return false" for all the consecutive calls preventing future click actions. The button will appear and act as disabled, but will not be, so it will not prevent button submission.

会发生什么呢?第一次点击按钮会变成灰色(通过应用CSS),而onclick事件会对所有连续的调用更改为“返回false”,以防止以后的单击操作。该按钮将出现并作为禁用,但不会出现,因此它不会阻止按钮提交。

#4


0  

Here's a couple options:

1. You could create hidden inputs and dynamically change the value of it before the form is submitted either onClick or onHover of the said button:

2. You could create an hidden iframe which is the target of the said form. Once the submit button is click, you could cancel the submit event, grab all of the data and send it programatically through the iframe instead.

这里有几个选项:1。您可以创建隐藏的输入,并在表单提交之前动态地更改它的值。您可以创建一个隐藏的iframe,它是上述窗体的目标。单击submit按钮后,您可以取消submit事件,获取所有数据并通过iframe以编程方式发送它。

#5


0  

I wanted to stop the user from causing multiple form submissions by double clicking the submit button or hitting the enter key twice. I like this solution, because it doesn't require a hidden form field or hiding the submit button.

我想通过双击submit按钮或单击两次enter键来阻止用户产生多个表单提交。我喜欢这个解决方案,因为它不需要隐藏表单字段或隐藏submit按钮。

The two key points are:

这两个要点是:

  1. Return true/false instead of using e.preventDefault() and form.submit(), because form.submit() doesn't know which button was clicked and therefore, can't pass the button name/value.

    返回true/false而不是使用e.preventDefault()和form.submit(),因为form.submit()不知道单击了哪个按钮,因此不能传递按钮名/值。

  2. Disable the button with pointer-events: none; instead of disabled="disabled", because the disabled attribute won't send the button name/value. I believe pointer-events: none; is not supported by Internet Explorer 10 or below.

    使用指针事件禁用按钮:无;而不是disabled="disabled",因为禁用属性不会发送按钮名/值。我相信pointer-events:没有;不受Internet Explorer 10或以下的支持。

javascript/jquery code:

javascript / jquery代码:

var form_selector = 'form',
    button_selector = 'button, input[type=submit], input[type=button], input[type=reset]',
    deactivated_classname = 'state-submitting',
    deactivated_class = '.'+'state-submitting';

// Capture the submit event so it will handle both the 
// enter key and clicking the submit button.
$(document).on('submit', form_selector, function(e) {
  var form = e.target,
      buttons = $( form ).find( button_selector );

  // Returns, because the form is already being submitted by a previous attempt.
  if( $( form ).find( deactivated_class ).length > 0  ) return false;

  disableButtons( buttons );

  // Safari (version 11) bugfix: Safari needs a timeout or it won't 
  // show the deactivated styles.
  setTimeout(function() {
    // Must use return true, because using form.submit(), won't pass the button value.
    return true;
  }, 50 );
});

function disableButtons( buttons ) {
  // Disables all buttons in the form.
  $( buttons ).each(function( index, elem ) {
    $( elem ).addClass( deactivated_classname );
  });
}

For AJAX forms, you will want to re-enable the buttons after the response is returned.

对于AJAX表单,您将希望在返回响应后重新启用按钮。

$( document ).on( 'ajax:complete', form_selector, function(e) {
  var form = e.target,
      buttons = $( form ).find( button_selector );

  enableButtons( buttons );
});

function enableButtons( buttons ) {
  $( buttons ).each(function( index, elem ) {
    $( elem ).removeClass( deactivated_classname );
  });
}

CSS:

CSS:

// The button is disabled while it is submitting.
.state-submitting {   
  // Turns off hover and click events. Not supported in IE 10 and below.
  pointer-events: none;
  opacity: 0.5;
}

#1


6  

Here is (yet another) answer to the question of how to deal with preventing the user from clicking on the form submission button more than once. This solution makes it appear that the button has been disabled.

下面是如何防止用户多次单击表单提交按钮的问题的另一个答案。此解决方案使按钮看起来已被禁用。

Under the covers, it creates a disabled button to display to the user, and hides the actual button so that its value is posted. I also move the hidden button so that the extra element doesn't mess up CSS selectors.

在幕后,它创建一个禁用的按钮来显示给用户,并隐藏实际的按钮,以便其值被发布。我还移动了隐藏按钮,以便额外的元素不会打乱CSS选择器。

Also note the check for invalid form fields. If you omit this check, and form validation fails, then the user winds up with a form that wasn't posted (because client-side validation failed) but the buttons are disabled.

还要注意检查无效的表单字段。如果您省略了这个检查,并且表单验证失败,那么用户最终会得到一个没有发布的表单(因为客户端验证失败),但是按钮被禁用。

// Disables buttons when form is submitted
$('form').submit(function () {
    // Bail out if the form contains validation errors
    if ($.validator && !$(this).valid()) return;

    var form = $(this);
    $(this).find('input[type="submit"], button[type="submit"]').each(function (index) {
        // Create a disabled clone of the submit button
        $(this).clone(false).removeAttr('id').prop('disabled', true).insertBefore($(this));

        // Hide the actual submit button and move it to the beginning of the form
        $(this).hide();
        form.prepend($(this));
    });
});

#2


2  

Because you can submit a form other ways than simply clicking the submit button it's better to add a listener to the form's submit event rather than the click event on the submit button. This jQuery event listener should work on any form and prevent it from being submitted more than once.

因为您可以通过其他方式提交表单,而不只是单击submit按钮,所以最好向表单的submit事件添加侦听器,而不是在submit按钮上添加click事件。这个jQuery事件侦听器应该处理任何表单,并防止它被提交多次。

$('form').on('submit', function(e) {
    if (!$(this).data('submitted')) {
        $(this).data('submitted', true);
    }
    else {
        e.preventDefault();
    }
});

To make the form look disabled you could add some css that makes the form look disabled and then add the classname on form submission.

要使表单看起来是禁用的,您可以添加一些css,使表单看起来是禁用的,然后在表单提交中添加classname。

$('form').on('submit', function(e) {
    if (!$(this).data('submitted')) {
        $(this).data('submitted', true).addClass('disabled');
    }
    else {
        e.preventDefault();
    }
});

#3


1  

You can simulate disabled look behavior. E.g. if you have a button like this:

您可以模拟残疾人的外观行为。如果你有这样一个按钮:

<input id="btn" type="button" onclick="disableMe(this)" value="Submit" />

You can define CSS like this

你可以这样定义CSS

.disabled {
    backround-color:grey;
    color:darkgrey;
}

And JS like this

和JS这样

function disableMe(btn) {
    btn.className = "disabled";
    btn.onclick = function(){return false}
}

What will happen - on first click button will become grey (via applied CSS) and onclick event will change to "return false" for all the consecutive calls preventing future click actions. The button will appear and act as disabled, but will not be, so it will not prevent button submission.

会发生什么呢?第一次点击按钮会变成灰色(通过应用CSS),而onclick事件会对所有连续的调用更改为“返回false”,以防止以后的单击操作。该按钮将出现并作为禁用,但不会出现,因此它不会阻止按钮提交。

#4


0  

Here's a couple options:

1. You could create hidden inputs and dynamically change the value of it before the form is submitted either onClick or onHover of the said button:

2. You could create an hidden iframe which is the target of the said form. Once the submit button is click, you could cancel the submit event, grab all of the data and send it programatically through the iframe instead.

这里有几个选项:1。您可以创建隐藏的输入,并在表单提交之前动态地更改它的值。您可以创建一个隐藏的iframe,它是上述窗体的目标。单击submit按钮后,您可以取消submit事件,获取所有数据并通过iframe以编程方式发送它。

#5


0  

I wanted to stop the user from causing multiple form submissions by double clicking the submit button or hitting the enter key twice. I like this solution, because it doesn't require a hidden form field or hiding the submit button.

我想通过双击submit按钮或单击两次enter键来阻止用户产生多个表单提交。我喜欢这个解决方案,因为它不需要隐藏表单字段或隐藏submit按钮。

The two key points are:

这两个要点是:

  1. Return true/false instead of using e.preventDefault() and form.submit(), because form.submit() doesn't know which button was clicked and therefore, can't pass the button name/value.

    返回true/false而不是使用e.preventDefault()和form.submit(),因为form.submit()不知道单击了哪个按钮,因此不能传递按钮名/值。

  2. Disable the button with pointer-events: none; instead of disabled="disabled", because the disabled attribute won't send the button name/value. I believe pointer-events: none; is not supported by Internet Explorer 10 or below.

    使用指针事件禁用按钮:无;而不是disabled="disabled",因为禁用属性不会发送按钮名/值。我相信pointer-events:没有;不受Internet Explorer 10或以下的支持。

javascript/jquery code:

javascript / jquery代码:

var form_selector = 'form',
    button_selector = 'button, input[type=submit], input[type=button], input[type=reset]',
    deactivated_classname = 'state-submitting',
    deactivated_class = '.'+'state-submitting';

// Capture the submit event so it will handle both the 
// enter key and clicking the submit button.
$(document).on('submit', form_selector, function(e) {
  var form = e.target,
      buttons = $( form ).find( button_selector );

  // Returns, because the form is already being submitted by a previous attempt.
  if( $( form ).find( deactivated_class ).length > 0  ) return false;

  disableButtons( buttons );

  // Safari (version 11) bugfix: Safari needs a timeout or it won't 
  // show the deactivated styles.
  setTimeout(function() {
    // Must use return true, because using form.submit(), won't pass the button value.
    return true;
  }, 50 );
});

function disableButtons( buttons ) {
  // Disables all buttons in the form.
  $( buttons ).each(function( index, elem ) {
    $( elem ).addClass( deactivated_classname );
  });
}

For AJAX forms, you will want to re-enable the buttons after the response is returned.

对于AJAX表单,您将希望在返回响应后重新启用按钮。

$( document ).on( 'ajax:complete', form_selector, function(e) {
  var form = e.target,
      buttons = $( form ).find( button_selector );

  enableButtons( buttons );
});

function enableButtons( buttons ) {
  $( buttons ).each(function( index, elem ) {
    $( elem ).removeClass( deactivated_classname );
  });
}

CSS:

CSS:

// The button is disabled while it is submitting.
.state-submitting {   
  // Turns off hover and click events. Not supported in IE 10 and below.
  pointer-events: none;
  opacity: 0.5;
}