web-dev-qa-db-fra.com

Comment empêcher les utilisateurs de cliquer deux fois sur un bouton?

J'ai une ancienne application de formulaires Web ASP.NET (.NET 2.0) dont le processus prend environ 30 secondes à s'exécuter lorsqu'un clic est effectué sur un bouton. Je dois empêcher que le bouton ne soit cliqué deux fois. Cela empêchera la publication à deux reprises, ce qui provoque la duplication de données dans une base de données.

J'ai essayé d'ajouter;

OnClientClick="this.disabled='true';"

pour essayer de désactiver le bouton en JavaScript. Cependant, bien que le bouton soit désactivé, la publication pour le bouton ne fonctionne pas.

Désactiver le bouton pour éviter les soumissions multiples est l’idéal pour cette application. Comment puis-je faire ceci?

MODIFIER

Je ne peux pas utiliser de contrôles tiers.

44
Richard

Vous devez retourner true après OnClientClick:

OnClientClick="this.disabled='true';return true;"

Tous les clics côté client doivent retourner la valeur true pour que la publication continue, c'est un moyen de fournir une validation côté client lors de l'appui sur des boutons.

23
Mantorok

Si vous désactivez simplement le bouton, ASP.NET ne publiera pas le formulaire. Vous souhaitez également gérer la validation côté client. Voici ma solution: 

<asp:Button runat="server" ID="btnSave" 
   Text="Save" OnClick="btnSave_Click" 
   OnClientClick="if (!Page_ClientValidate()){ return false; } this.disabled = true; this.value = 'Saving...';" 
   UseSubmitBehavior="false" />

Voir le post de @Dave Ward pour une description de UseSubmitBehavior.

Si vous avez plusieurs groupes de validation, vous devrez améliorer cette solution pour cela. 

76
Rory

Vous devez également définir la propriété UseSubmitBehavior du bouton sur false .

Les navigateurs Web n'incluent pas les éléments désactivés dans les données POST d'un formulaire, même s'il s'agit du bouton qui a déclenché la soumission du formulaire. Malheureusement, la conception de page unique ASP.NET WebForms repose sur cette information pour savoir quel contrôle déclenche PostBack et quel gestionnaire d'événements à exécuter (par exemple, Button1.On_Click).

Le passage à UseSubmitBehavior="false" injecte une __doPostBack('Button1', '') dans le gestionnaire onclick côté client pour résoudre ce problème. Ensuite, même si vous désactivez le bouton, le paramètre __doPostBack permet à ASP.NET de savoir quel contrôle déclenche PostBack et quels événements déclencher côté serveur.

15
Dave Ward

La plupart des solutions proposées ci-dessus qui suggèrent de désactiver ne fonctionneront pas car vous n'obtiendrez pas de PostBack. C'est la solution de travail la plus simple et la plus propre que j'ai jamais vue:

OnClientClick="if(this.value === 'Saving...') { return false; } else { this.value = 'Saving...'; }"
10
Mike Socha III

Pour contourner tous les problèmes de validation et de groupe de validation, j'ai trouvé qu'il était plus simple d'utiliser l'événement window.onbeforeunload, comme ceci.

<script type = "text/javascript">
function DisableButton() {
    document.getElementById("<%=Button1.ClientID %>").disabled = true;
}
window.onbeforeunload = DisableButton;
</script>

Le script ci-dessus désactive le bouton ASP.Net dès que la page est prête à effectuer un postback, y compris la validation, ou le formulaire ASP.Net est soumis.

Désactive le bouton ASP.Net après avoir cliqué pour empêcher le double-clic

8
wezzix

J'ajoute généralement cette méthode à ma page de base pour la réutilisation. 

Ce code gère également les validations

/// <summary>
///  Avoid multiple submit
/// </summary>
/// <param name="button">The button.</param>
/// <param name="text">text displayed on button</param>
public void AvoidMultipleSubmit(Button button,string text="wait..." )
{
    Page.ClientScript.RegisterOnSubmitStatement(GetType(), "ServerForm", "if(this.submitted) return false; this.submitted = true;");
    button.Attributes.Add("onclick", string.Format("if(typeof(Page_ClientValidate)=='function' && !Page_ClientValidate()){{return true;}}this.value='{1}';this.disabled=true;{0}",
        ClientScript.GetPostBackEventReference(button, string.Empty),text));
}
2
giammin

J'ai trouvé ce lien très utile pour résoudre ce problème Désactivez le bouton ASP.Net après avoir cliqué pour éviter de double-cliquer sur .

J'espère que ça peut aider :)

2
Ahmed Elbatt

Avantages

  • Fonctionne hors de la boîte pour tous les boutons
    • Même les boutons qui n'ont pas déclenché l'envoi seront désactivés.
    • LinkButtons sera également désactivé.
  • Fonctionne avec UpdatePanels (c'est-à-dire postbacks partiels et asynchrones)
  • Fonctionne pour les publications complètes
  • Ne désactive pas les boutons lorsque la validation empêche la publication
  • Une pression sur un bouton, une pression sur la touche Entrée et les événements AutoPostBack entraînent la désactivation des boutons.

Limites

† La plupart des autres solutions que j'ai vues ont les mêmes limitations

  • S'appuie sur jQuery
  • Ne fonctionne que pour les formulaires ASP
  • Si l'utilisateur clique sur le bouton d'annulation du navigateur après la soumission, il ne pourra plus soumettre de nouvelle et risque de se perdre.
  • Il reste d'autres moyens par lesquels un utilisateur peut initier une publication:
    • Soumettre en utilisant la touche Entrée
    • Événements Autopostback

Code

Placez simplement cet extrait au bas de votre code HTML avant la balise de fermeture </body>.

<script type="text/javascript">
    jQuery(function ($) {

        /*
         * Prevent Double Submit
         * ---------------------
         * Disables submit buttons during form submission and asp async postbacks
         */

        // class name assigned to disabled :submit elements
        var disabledClass = 'asp-postback-disable';

        // selector for buttons and other elements that may cause a postback
        var submittableSelector = [
            'a[href^="javascript:__doPostBack"]',
            ':submit'
        ].join(",");

        // returns false; used to prevent event bubbling
        function returnFalse() { return false; }

        // logs errors
        function error(ex) {
            if (typeof console === 'object' && console.error != null) {
                console.error('Prevent Double Submit Error:', ex);
            }
        }

        // disables :submit elements
        function disableSubmit() {
            try {
                $(submittableSelector, 'form')
                    .addClass(disabledClass)
                    .on('click.asp-postback-disable', returnFalse);
            }
            catch (ex) { error(ex); }
        }

        // enables :submit elements
        function enableSubmit() {
            try {
                $('.asp-postback-disable,' + submittableSelector, 'form')
                    .removeClass(disabledClass)
                    .off('click.asp-postback-disable', returnFalse);
            }
            catch (ex) { error(ex); }
        }

        // Handle async postbacks
        if (typeof Sys === 'object') {
            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_beginRequest(function (s, e) { disableSubmit(); });
            prm.add_endRequest(function (s, e) { enableSubmit(); });
        }
        else {
            error('Sys is undefined.');
        }

        // Handle navigation (eg, Full postback)
        $(window).bind('beforeunload', function (e) {
            disableSubmit();
        });

    });
</script>

<style type="text/css">
    .asp-postback-disable { opacity: 0.25; }
</style>
1
sparebytes

A partir d'un fichier aspx.cs, vous pouvez ajouter le script pour résoudre ce problème (c'est la seule solution qui a fonctionné pour moi et a été fournie par: wexxix)

//Declaring the string to hold the script
string doubleClickScript = @"<script type='text/javascript'>
                                    function DisableButton() {
                                    document.getElementById('YOURBUTTONID').disabled = true;
                                }
                                window.onbeforeunload = DisableButton;
                                </script>";
//Injecting the script to the aspx page.        
ClientScript.RegisterStartupScript(this.GetType(), "DoubleClickScript", doubleClickScript);

Évidemment, vous pouvez simplement ajouter le script à la page, je viens de l'utiliser comme ça puisque je viens d'avoir accès au code client C # . Merci

0
Ernest

Une chose que vous pouvez faire est, après avoir cliqué dessus, de le masquer du côté client et d'afficher des images du chargeur.

Ou si c'est une forme ou quelque chose que vous pouvez ajouter recaptcha

0
Mahesh KP

Après avoir cherché pendant un moment, je suis venu avec cette solution.

$('form').submit(function () {
    $('input[type=submit][data-loading]').addClass('disabled');

    if ($(this).data('submitted') == true) {
        $('input[type=submit][data-loading]').attr('disabled', 'disabled');
        return false;
    }

    $(this).data('submitted', true);
});

Le problème avec la solution UseDefaultBehavior est que la touche Entrée arrête de ne pas soumettre le formulaire qui est utilisé beaucoup. Je suppose qu'un pourcentage considérable d'utilisateurs essaient d'entrer au lieu de cliquer.

0
Fabio Milheiro

Vous pouvez aussi un peu "bidouiller" en créant un bouton côté client avec le même style, en masquant le bouton "original" côté serveur et en utilisant javascript pour désactiver le bouton HTML/appeler le bouton original.

Dans la publication suivante, il annulera automatiquement votre modification sur le bouton côté client :). 

<asp:Button ID="btnSubmitQuote" class="btn btn-red btn-block" runat="server" Text="Submit Quote" style="display:none;" OnClick="btnSubmitQuote_Click" UseSubmitBehavior="false" />

<button id="btnSubmitQuoteClient"  class="btn btn-red btn-block" onclick ="disableBtn(this);">Submit Quote</button>
<script type="text/javascript">
 function disableBtn(t) {
    t.setAttribute('disabled', 'disabled');
    var btn = document.getElementById('<%=btnSubmitQuote.ClientID %>');
    btn.click();
  }

0
ManNguyenIO