Ok so for those that are still fighting with a means of a synchronous client-side validation solution. I finally got the solution working. I was reluctant to experiment with jQuery, but wish I would have days ago.
What I was trying to accomplish was a textbox autocomplete that would pass the username to the database and begin returning data specific for that user. Then to prevent any input in the textbox other than from the permitted autocomplete list, I used the CustomValidator with jQuery. What this did is take the final input string along with the username and passed it to the database. If the database returned a record with the matching string, the selection was valid; if not, the selection is marked as invalid.
I fought for so long with this, I wanted to give others an 'as complete as possible' guide. For those that have not used jQuery, neither had I prior to this and that portion took the least amount of time to come up with this solution. I hope this helps someone out there.
Here is exactly what I did:
Downloaded the jQuery script and placed it in my scripts folder. Added a reference to the jQuery in my MasterPage.Master header section. Modified the ScriptManager (in the body) to EnablePageMethods.
<script type="text/javascript" src="/scripts/jquery-1.4.2.js"></script> <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"> </asp:ScriptManager>
Added the JavaScript just inside my content place holder in TextBoxAutoFill.aspx.
<script type="text/javascript"> function pmValidateGLAccount(oSrc, args) { $.ajax({ type: "POST", async: false, url: "TextBoxAutoFill.aspx/ValidateGLAccountAccess", data: "{ GLAccountNum: " + "'" + args.Value + "' }", contentType: "application/json; charset=utf-8", dataType: "json", success: function (response) { args.IsValid = response.d; } }); }; </script>
Created my TextBox, AutoCompleteExtender and CustomValidator
<asp:TextBox TabIndex="1" autocomplete="off" ID="TextBox1" runat="server" Width="250px" ValidationGroup="vg_test"></asp:TextBox> <asp:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server" EnableCaching="true" CompletionSetCount="10" ShowOnlycurrentWordInCompletionListItem="true" CompletionInterval="500" CompletionListCssClass="AJAXAutosuggestTextBox" DelimiterCharacters="" Enabled="True" ServiceMethod="GetAccountNumbers" TargetControlID="TextBox1" MinimumPrefixLength="4" > </asp:AutoCompleteExtender> <asp:CustomValidator ID="CustomValidator1" runat="server" ControlToValidate="TextBox1" ValidationGroup="vg_test" ClientValidationFunction="pmValidateGLAccount" ErrorMessage="Error: Please enter an account number from the list" Display="Dynamic"></asp:CustomValidator>
Added the WebMethod for my AutoCompleteExtender (This is in the TestBoxAutoFill.aspx.cs file)
[System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethod()] public static List<string> GetAccountNumbers(string prefixText, int count) { string CurUser = HttpContext.Current.User.Identity.Name.ToString(); string CurUserRemoveDomain = string.Empty; int i = CurUser.IndexOf("\\"); if (i != -1) { CurUserRemoveDomain = CurUser.ToLower().Replace(Resources.AppSettings.ActiveDirectoryDomain.ToString().ToLower() + "\\", ""); CurUser = CurUserRemoveDomain; } using (SqlConnection conn = new SqlConnection()) { conn.ConnectionString = ConfigurationManager.ConnectionStrings["CustDBConn"].ConnectionString; using (SqlCommand cmd = new SqlCommand("SP_PCard_Get_AutoCompleteAccountNumbers", conn)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@RecCount", count); cmd.Parameters.AddWithValue("@SearchString", prefixText); cmd.Parameters.AddWithValue("@UserName", CurUser); cmd.Connection = conn; conn.Open(); List<string> AccountNumbers = new List<string>(); using (SqlDataReader sdr = cmd.ExecuteReader()) { while (sdr.Read()) { AccountNumbers.Add(sdr["ACTNUMST"].ToString()); } } conn.Close(); return AccountNumbers; } } }
Added the WebMethod for validation (This is in the TestBoxAutoFill.aspx.cs file)
[System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethod()] public static bool ValidateGLAccountAccess(string GLAccountNum) { string RetValue = string.Empty; string CurUser = HttpContext.Current.User.Identity.Name.ToString(); string CurUserRemoveDomain = string.Empty; int i = CurUser.IndexOf("\\"); if (i != -1) { CurUserRemoveDomain = CurUser.ToLower().Replace(Resources.AppSettings.ActiveDirectoryDomain.ToString().ToLower() + "\\", ""); CurUser = CurUserRemoveDomain; } using (SqlConnection conn = new SqlConnection()) { conn.ConnectionString = ConfigurationManager.ConnectionStrings["CustDBConn"].ConnectionString; using (SqlCommand cmd = new SqlCommand("SP_PCard_Get_SelectedGLAcountNumber", conn)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@SearchString", GLAccountNum); cmd.Parameters.AddWithValue("@UserName", CurUser); cmd.Connection = conn; conn.Open(); RetValue = (string)cmd.ExecuteScalar(); conn.Close(); } } Boolean myVarBool = false; if (RetValue == GLAccountNum) { myVarBool = true; } return myVarBool; }