Today I was working on a maintenance Web page that triggers a SQL Server stored procedure. This stored procedure can either run quite quickly, or it can take in excess of seven minutes to finish. So in order to let the user know that the process is executing in the background I added a small floating div to the page with a message encouraging patience that the code is still running and I disabled the submit button so the form could not be submitted more than once.
The floating div/submit button disabling is triggered on click of the submit button using the OnClientClick attribute. However on the page I also have some RequiredFieldValidator and RegularExpressionValidator controls.
As I found out, the OnClientClick JavaScript function is called before the JavaScript for the validation controls happens, which caused a problem if the validation failed since the div would still appear stating that the process is running and the submit button would be disabled preventing further actions.
To correct this I found that using a JavaScript only ASP.NET CustomValidator control was very useful since I could place it at the end of the list of validation controls and ASP.NET will execute the control validation in the order that the controls are placed on the page.
So by placing the ASP.NET CustomValidator control after the page’s other validation controls I was able to call a custom JavaScript function to read the state of the error messages of the other validation controls and thus control if the message div was shown as well as to control disabling the submit button.
I’m providing an example of the control and the JavaScript below. A gotcha to remember is to set the ValidateEmptyText attribute to true and to remember to set args.IsValid to the correct boolean value in the custom JavaScript.
<script language="javascript" type="text/javascript"> function CheckDiscountAmount(sender, args) { if (RequiredFieldValidatortbToDate.style.display == 'inline') { var divRunningQuery = document.getElementById('divRunningQuery'); var btnInitiateProcess = document.getElementById('btnInitiateProcess'); if (divRunningQuery.style.display == 'inline') { btnInitiateProcess.style.display = 'inline'; divRunningQuery.style.display = 'none'; args.IsValid = false; return; } } else { args.IsValid = true; return; } } </script> <asp:CustomValidator ControlToValidate="tbToDate" ValidateEmptyText="true" ID="CustomValidator1" ClientValidationFunction="CheckDiscountAmount" runat="server" ErrorMessage="" ValidationGroup="grpPrimarySave" ></asp:CustomValidator>