Distriggers pulsante sull’invio del modulo

Ho un pulsante che vorrei disabilitare quando il modulo viene inviato per impedire all’utente di inviare più volte.

Ho provato ingenuamente disabilitare il pulsante con javascript onclick, ma poi se una convalida lato client che fallisce il pulsante rimane disabilitato.

Come disabilitare il pulsante quando il modulo viene inviato correttamente non solo quando l’utente fa clic?

Questo è un modulo ASP.NET quindi mi piacerebbe collegarmi piacevolmente con il ciclo di vita della pagina di ajax di asp.net se ansible.

Fai un vortice:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Threading; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // Identify button as a "disabled-when-clicked" button... WebHelpers.DisableButtonOnClick( buttonTest, "showPleaseWait" ); } protected void buttonTest_Click( object sender, EventArgs e ) { // Emulate a server-side process to demo the disabled button during // postback. Thread.Sleep( 5000 ); } } using System; using System.Web; using System.Web.UI.WebControls; using System.Text; public class WebHelpers { // // Disable button with no secondary JavaScript function call. // public static void DisableButtonOnClick( Button ButtonControl ) { DisableButtonOnClick( ButtonControl, string.Empty ); } // // Disable button with a JavaScript function call. // public static void DisableButtonOnClick( Button ButtonControl, string ClientFunction ) { StringBuilder sb = new StringBuilder( 128 ); // If the page has ASP.NET validators on it, this code ensures the // page validates before continuing. sb.Append( "if ( typeof( Page_ClientValidate ) == 'function' ) { " ); sb.Append( "if ( ! Page_ClientValidate() ) { return false; } } " ); // Disable this button. sb.Append( "this.disabled = true;" ); // If a secondary JavaScript function has been provided, and if it can be found, // call it. Note the name of the JavaScript function to call should be passed without // parens. if ( ! String.IsNullOrEmpty( ClientFunction ) ) { sb.AppendFormat( "if ( typeof( {0} ) == 'function' ) {{ {0}() }};", ClientFunction ); } // GetPostBackEventReference() obtains a reference to a client-side script function // that causes the server to post back to the page (ie this causes the server-side part // of the "click" to be performsd). sb.Append( ButtonControl.Page.ClientScript.GetPostBackEventReference( ButtonControl ) + ";" ); // Add the JavaScript created a code to be executed when the button is clicked. ButtonControl.Attributes.Add( "onclick", sb.ToString() ); } } 

Non sono un grande fan di scrivere tutto quel javascript nel code-behind. Ecco come appare la mia soluzione finale.

Pulsante:

  

Javascript:

  

La seguente funzione è utile senza la parte disabilitante che tende ad essere inaffidabile. Basta usare “return check_submit ();” come parte del gestore onclick dei pulsanti di invio.

Ci dovrebbe anche essere un campo nascosto per contenere il valore iniziale form_submitted di 0;

  function check_submit (){ if (document.Form1.form_submitted.value == 1){ alert("Don't submit twice. Please wait."); return false; } else{ document.Form1.form_submitted.value = 1; return true; } return false; } 

Distriggers il pulsante alla fine del tuo gestore di invio. Se la convalida fallisce, dovrebbe restituire false prima.

Tuttavia, l’approccio di JavaScript non è qualcosa su cui possiamo fare affidamento, quindi dovresti avere qualcosa da rilevare anche sul server.

se la convalida ha esito positivo, disabilitare il pulsante. se non lo è, allora non farlo.

 function validate(form) { // perform validation here if (isValid) { form.mySubmitButton.disabled = true; return true; } else { return false; } } 
...

Imposta la visibilità sul pulsante su “nessuno”;

 btnSubmit.Attributes("onClick") = document.getElementById('btnName').style.display = 'none'; 

Non solo impedisce la doppia presentazione, ma è un chiaro indicatore per l’utente che non si desidera che il pulsante venga premuto più di una volta.

Non sono sicuro se questo sarà d’aiuto, ma c’è un evento sul modulo. Puoi utilizzare questo evento ogni volta che il modulo viene inviato (da qualsiasi pulsante o controllo). Per riferimento: http://www.htmlcodetutorial.com/forms/_FORM_onSubmit.html

Una soluzione sarà quella di impostare un campo nascosto quando si fa clic sul pulsante, con il numero 1.

Sul pulsante click handler la prima cosa è controllare quel numero se si tratta di qualcosa di diverso da 1, basta uscire dalla funzione.

Potresti anche essere in grado di sfruttare l’evento javascript onsubmit () disponibile nei moduli. Questo evento si triggers quando il modulo è effettivamente inviato e non deve essere intercettato fino a quando non viene completata la convalida.

Questo è un metodo più semplice ma simile di quello suggerito da rp :

 function submit(button) { Page_ClientValidate(); if(Page_IsValid) { button.disabled = true; } }  

Nota che l’approccio di rp raddoppierà il tuo modulo se stai usando i pulsanti con UseSubmitBehavior="false" .

Io uso la seguente variazione del codice di rp:

 public static void DisableButtonOnClick(Button button, string clientFunction) { // If the page has ASP.NET validators on it, this code ensures the // page validates before continuing. string script = "if (typeof(Page_ClientValidate) == 'function') { " + "if (!Page_ClientValidate()) { return false; } } "; // disable the button script += "this.disabled = true; "; // If a secondary JavaScript function has been provided, and if it can be found, call it. // Note the name of the JavaScript function to call should be passed without parens. if (!string.IsNullOrEmpty(clientFunction)) script += string.Format("if (typeof({0}) == 'function') {{ {0}() }} ", clientFunction); // only need to post back if button is using submit behaviour if (button.UseSubmitBehavior) script += button.Page.GetPostBackEventReference(button) + "; "; button.Attributes.Add("onclick", script); } 

Il modo corretto (per quanto riguarda la semplicità di utilizzo, almeno) sarebbe quello di disabilitare il pulsante utilizzando l’attributo OnClientClick, eseguire la convalida sul lato client e quindi utilizzare il risultato di ciò per continuare o ritriggersre il pulsante.

Ovviamente, dovresti anche scrivere codice lato server per questo, dato che non puoi fare affidamento sulla convalida che viene eseguita anche a causa di una mancanza, o di una particolare implementazione, di JavaScript. Tuttavia, se si fa affidamento sul server che controlla lo stato abilitato / disabilitato del pulsante, in pratica non è ansible bloccare l’invio del modulo più volte. Per questo motivo è necessario disporre di una sorta di logica per rilevare più richieste dallo stesso utente in un breve periodo di tempo (ad esempio valori identici della stessa sessione).

una delle mie soluzioni è la seguente:

aggiungi lo script nel page_load del tuo file aspx

  HtmlGenericControl includeMyJava = new HtmlGenericControl("script"); includeMyJava.Attributes.Add("type", "text/javascript"); includeMyJava.InnerHtml = "\nfunction dsbButton(button) {"; includeMyJava.InnerHtml += "\nPage_ClientValidate();"; includeMyJava.InnerHtml += "\nif(Page_IsValid)"; includeMyJava.InnerHtml += "\n{"; includeMyJava.InnerHtml += "\nbutton.disabled = true;"; includeMyJava.InnerHtml += "}"; includeMyJava.InnerHtml += "\n}"; this.Page.Header.Controls.Add(includeMyJava); 

e quindi imposta i parametri del tuo pulsante aspx come segue:

  

Nota che “onClientClick” aiuta a disabilitare il pulsante e “UseSubmitBehaviour” disabilita il tradizionale comportamento di invio della pagina e consente a asp.net di visualizzare il comportamento di invio sullo script dell’utente.

in bocca al lupo

-Waqas Aslam

Ho appena sentito parlare della proprietà “DisableOnSubmit” di un , in questo modo:

  

Quando viene eseguito il rendering, l’attributo onclick del pulsante è simile al seguente:

 onclick="this.disabled=true; setTimeout('enableBack()', 3000); WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions('yourControlsName', '', true, '', '', false, true)) 

E la funzione javascript “enableBack ()” ha il seguente aspetto:

 function enableBack() { document.getElementById('yourControlsName').disabled=false; } 

Quindi, quando si fa clic sul pulsante, diventa disabilitato per 3 secondi. Se il modulo invia correttamente, non si vede più ritriggersre il pulsante. Se, tuttavia, nessun validatore fallisce, il pulsante viene ritriggersto dopo 3 secondi.

Tutto ciò semplicemente impostando un attributo sul pulsante: non è necessario scrivere a mano il codice javascript.

Pertanto, la semplice distriggerszione del pulsante tramite javascript non è un’opzione compatibile con più browser. Chrome non invierà il modulo se utilizzi semplicemente OnClientClick="this.disabled=true;"
Di seguito è riportata una soluzione che ho testato su Firefox 9, Internet Explorer 9 e Chrome 16:

  

Quindi registra “disableButton” con l’evento click del pulsante di invio del modulo, in un modo:

  

Vale la pena notare che questo aggira il problema della distriggerszione del pulsante se la convalida del lato client fallisce. Inoltre non richiede l’elaborazione lato server.

Basandosi sulla risposta di @ rp., L’ho modificata per invocare la funzione personalizzata e inviare e disabilitare in caso di successo o “stop” in caso di errore:

 public static void DisableButtonOnClick(Button ButtonControl, string ClientFunction) { StringBuilder sb = new StringBuilder(128); if (!String.IsNullOrEmpty(ClientFunction)) { sb.AppendFormat("if (typeof({0}) == 'function') {{ if ({0}()) {{ {1}; this.disabled=true; return true; }} else {{ return false; }} }};", ClientFunction, ButtonControl.Page.ClientScript.GetPostBackEventReference(ButtonControl, null)); } else { sb.Append("return true;"); } ButtonControl.Attributes.Add("onclick", sb.ToString()); }