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?
Je ne peux pas utiliser de contrôles tiers.
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.
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.
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.
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...'; }"
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
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));
}
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 :)
† La plupart des autres solutions que j'ai vues ont les mêmes limitations
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>
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
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
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.
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();
}