Ajax page method call during form validation
-
Hi, I have a registration form which consists of, amongst others, an email field. When the user enters their email address, the onChange event is fired and a server side page method is called which checks the email address and returns a boolean value. This works fine when invoked from the onChange event of the textbox. The problem occurs when the submit button is clicked; the submit button invokes the Javascript validation function and posts back if the form is valid, however, because the email validation involves an AJAX server side call, the function isn't waiting for the response and so causes the form to be submitted regardless of the email validation result. I hope I have explained this adequately but if not I have included a cut down version of my page:
var pageIsValid; var emailAddressMessage; function ValidateForm() { pageIsValid = true; PageMethods.EmailAddressIsValid(document.getElementById('<%= txtNewMemberEmailAddress.ClientID %>').value, ValidateEmailAddressSuccess, ValidateEmailAddressFailed); // other validation calls have been left out if (pageIsValid == false) { alert('Some information is either missing or invalid. Hover your mouse over the red crosses for more information'); } return pageIsValid; } function ValidateEmailAddressSuccess(result) { if (result == false) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; emailAddressMessage = 'The email address you have entered is already in use'; pageIsValid = false; } else { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/tick.png"; emailAddressMessage = 'This field is valid'; } } function ValidateEmailAddressFailed(result) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; alert(result.get\_message()); }
If anyone could suggest a better way of doing this it would be appreciated. Thanks Jay
-
Hi, I have a registration form which consists of, amongst others, an email field. When the user enters their email address, the onChange event is fired and a server side page method is called which checks the email address and returns a boolean value. This works fine when invoked from the onChange event of the textbox. The problem occurs when the submit button is clicked; the submit button invokes the Javascript validation function and posts back if the form is valid, however, because the email validation involves an AJAX server side call, the function isn't waiting for the response and so causes the form to be submitted regardless of the email validation result. I hope I have explained this adequately but if not I have included a cut down version of my page:
var pageIsValid; var emailAddressMessage; function ValidateForm() { pageIsValid = true; PageMethods.EmailAddressIsValid(document.getElementById('<%= txtNewMemberEmailAddress.ClientID %>').value, ValidateEmailAddressSuccess, ValidateEmailAddressFailed); // other validation calls have been left out if (pageIsValid == false) { alert('Some information is either missing or invalid. Hover your mouse over the red crosses for more information'); } return pageIsValid; } function ValidateEmailAddressSuccess(result) { if (result == false) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; emailAddressMessage = 'The email address you have entered is already in use'; pageIsValid = false; } else { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/tick.png"; emailAddressMessage = 'This field is valid'; } } function ValidateEmailAddressFailed(result) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; alert(result.get\_message()); }
If anyone could suggest a better way of doing this it would be appreciated. Thanks Jay
You could try taking the "A" out of "AJAX". Add the script below, and then change your
PageMethods.EmailAddressIsValid
call toSyncPageMethods.EmailAddressIsValid
.Type.registerNamespace("System.Net");
System.Net.XMLHttpSyncExecutor = function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }
System.Net.XMLHttpSyncExecutor.initializeBase(this);
};System.Net.XMLHttpSyncExecutor.prototype =
{
executeRequest: function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }var webRequest = this.get\_webRequest(); if (this.\_started) { throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, "executeRequest")); } if (null === webRequest) { throw Error.invalidOperation(Sys.Res.nullWebRequest); } var body = webRequest.get\_body(); var headers = webRequest.get\_headers(); this.\_xmlHttpRequest = new XMLHttpRequest(); this.\_xmlHttpRequest.onreadystatechange = this.\_onReadyStateChange; var verb = this.\_webRequest.get\_httpVerb(); this.\_xmlHttpRequest.open(verb, this.\_webRequest.getResolvedUrl(), false); if (headers) { for (var header in headers) { var val = headers\[header\]; if (typeof(val) !== "function") { this.\_xmlHttpRequest.setRequestHeader(header, val); } } } if ("post" === verb.toLowerCase()) { if (null === headers || !headers\["Content-Type"\]) { this.\_xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); } if (!body) { body = ""; } } this.\_xmlHttpRequest.send(body); if (null !== this.\_xmlHttpRequest) { // Firefox doesn't raise "onreadystatechange" events for sync requests: this.\_responseAvailable = true; webRequest.completed(Sys.EventArgs.Empty); this.\_xmlHttpRequest.onreadystatechange = Function.emptyMethod; this.\_xmlHttpRequest = null; }
}
};System.Net.XMLHttpSyncExecutor.registerClass("System.Net.XMLHttpSyncExecutor", Sys.Net.XMLHttpExecutor);
System.Net.WebServiceSyncProxy = function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }
Syst -
You could try taking the "A" out of "AJAX". Add the script below, and then change your
PageMethods.EmailAddressIsValid
call toSyncPageMethods.EmailAddressIsValid
.Type.registerNamespace("System.Net");
System.Net.XMLHttpSyncExecutor = function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }
System.Net.XMLHttpSyncExecutor.initializeBase(this);
};System.Net.XMLHttpSyncExecutor.prototype =
{
executeRequest: function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }var webRequest = this.get\_webRequest(); if (this.\_started) { throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, "executeRequest")); } if (null === webRequest) { throw Error.invalidOperation(Sys.Res.nullWebRequest); } var body = webRequest.get\_body(); var headers = webRequest.get\_headers(); this.\_xmlHttpRequest = new XMLHttpRequest(); this.\_xmlHttpRequest.onreadystatechange = this.\_onReadyStateChange; var verb = this.\_webRequest.get\_httpVerb(); this.\_xmlHttpRequest.open(verb, this.\_webRequest.getResolvedUrl(), false); if (headers) { for (var header in headers) { var val = headers\[header\]; if (typeof(val) !== "function") { this.\_xmlHttpRequest.setRequestHeader(header, val); } } } if ("post" === verb.toLowerCase()) { if (null === headers || !headers\["Content-Type"\]) { this.\_xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); } if (!body) { body = ""; } } this.\_xmlHttpRequest.send(body); if (null !== this.\_xmlHttpRequest) { // Firefox doesn't raise "onreadystatechange" events for sync requests: this.\_responseAvailable = true; webRequest.completed(Sys.EventArgs.Empty); this.\_xmlHttpRequest.onreadystatechange = Function.emptyMethod; this.\_xmlHttpRequest = null; }
}
};System.Net.XMLHttpSyncExecutor.registerClass("System.Net.XMLHttpSyncExecutor", Sys.Net.XMLHttpExecutor);
System.Net.WebServiceSyncProxy = function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }
SystWOW! You've either put a lot of thought into this answer or you've tackled this problem before! Either way thanks for the response, I will try this later today and let you know how it goes. Thanks again Jay
-
You could try taking the "A" out of "AJAX". Add the script below, and then change your
PageMethods.EmailAddressIsValid
call toSyncPageMethods.EmailAddressIsValid
.Type.registerNamespace("System.Net");
System.Net.XMLHttpSyncExecutor = function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }
System.Net.XMLHttpSyncExecutor.initializeBase(this);
};System.Net.XMLHttpSyncExecutor.prototype =
{
executeRequest: function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }var webRequest = this.get\_webRequest(); if (this.\_started) { throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, "executeRequest")); } if (null === webRequest) { throw Error.invalidOperation(Sys.Res.nullWebRequest); } var body = webRequest.get\_body(); var headers = webRequest.get\_headers(); this.\_xmlHttpRequest = new XMLHttpRequest(); this.\_xmlHttpRequest.onreadystatechange = this.\_onReadyStateChange; var verb = this.\_webRequest.get\_httpVerb(); this.\_xmlHttpRequest.open(verb, this.\_webRequest.getResolvedUrl(), false); if (headers) { for (var header in headers) { var val = headers\[header\]; if (typeof(val) !== "function") { this.\_xmlHttpRequest.setRequestHeader(header, val); } } } if ("post" === verb.toLowerCase()) { if (null === headers || !headers\["Content-Type"\]) { this.\_xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); } if (!body) { body = ""; } } this.\_xmlHttpRequest.send(body); if (null !== this.\_xmlHttpRequest) { // Firefox doesn't raise "onreadystatechange" events for sync requests: this.\_responseAvailable = true; webRequest.completed(Sys.EventArgs.Empty); this.\_xmlHttpRequest.onreadystatechange = Function.emptyMethod; this.\_xmlHttpRequest = null; }
}
};System.Net.XMLHttpSyncExecutor.registerClass("System.Net.XMLHttpSyncExecutor", Sys.Net.XMLHttpExecutor);
System.Net.WebServiceSyncProxy = function()
{
if (arguments.length !== 0) { throw Error.parameterCount(); }
SystThat looks like it will only work with .Net on the client side (i.e. on Windows), and probably only in IE. Edit: also, synchronous HTTP requests lock the browser process (i.e. at least the page you're looking at) until it returns, which can potentially be the TCP timeout time. They're a pretty bad idea.
-
Hi, I have a registration form which consists of, amongst others, an email field. When the user enters their email address, the onChange event is fired and a server side page method is called which checks the email address and returns a boolean value. This works fine when invoked from the onChange event of the textbox. The problem occurs when the submit button is clicked; the submit button invokes the Javascript validation function and posts back if the form is valid, however, because the email validation involves an AJAX server side call, the function isn't waiting for the response and so causes the form to be submitted regardless of the email validation result. I hope I have explained this adequately but if not I have included a cut down version of my page:
var pageIsValid; var emailAddressMessage; function ValidateForm() { pageIsValid = true; PageMethods.EmailAddressIsValid(document.getElementById('<%= txtNewMemberEmailAddress.ClientID %>').value, ValidateEmailAddressSuccess, ValidateEmailAddressFailed); // other validation calls have been left out if (pageIsValid == false) { alert('Some information is either missing or invalid. Hover your mouse over the red crosses for more information'); } return pageIsValid; } function ValidateEmailAddressSuccess(result) { if (result == false) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; emailAddressMessage = 'The email address you have entered is already in use'; pageIsValid = false; } else { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/tick.png"; emailAddressMessage = 'This field is valid'; } } function ValidateEmailAddressFailed(result) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; alert(result.get\_message()); }
If anyone could suggest a better way of doing this it would be appreciated. Thanks Jay
You need to add an extra step to your submission process, if you want AJAX validation before submitting. At the moment your workflow looks like Press button -> client validation -> post to server ... as a synchronous process. You need to do Press button -> client validation -> send AJAX validation request (...) receive AJAX response -> post to server The (...) is an asynchronous wait with an event handler set. As for all AJAX queries you need to handle long delays and dropped connections gracefully. Do you actually need this? I would think that people would expect a 'Submit' button to submit a postback, and for it to return them to the form after a postback with server-side validation errors would be acceptable. You will always have to do the server side validation anyway, so this is purely a user convenience feature.
-
You need to add an extra step to your submission process, if you want AJAX validation before submitting. At the moment your workflow looks like Press button -> client validation -> post to server ... as a synchronous process. You need to do Press button -> client validation -> send AJAX validation request (...) receive AJAX response -> post to server The (...) is an asynchronous wait with an event handler set. As for all AJAX queries you need to handle long delays and dropped connections gracefully. Do you actually need this? I would think that people would expect a 'Submit' button to submit a postback, and for it to return them to the form after a postback with server-side validation errors would be acceptable. You will always have to do the server side validation anyway, so this is purely a user convenience feature.
You're right actually, I probably don't need this feature. I have implemented server side validation which will ensure that invalid data doesn't get saved, so I suppose the post back is only a minor inconvenience to the user. There will still be the inline validation so the likelihood is that the user will correct their errors before submitting anyway (or maybe not!). Thanks a lot :) Jay
-
That looks like it will only work with .Net on the client side (i.e. on Windows), and probably only in IE. Edit: also, synchronous HTTP requests lock the browser process (i.e. at least the page you're looking at) until it returns, which can potentially be the TCP timeout time. They're a pretty bad idea.
BobJanova wrote:
That looks like it will only work with .Net on the client side (i.e. on Windows), and probably only in IE.
Nope. It works in Firefox, Chrome and Opera here. It's using the built-in XmlHttp object, which was added to all browsers several years ago.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Hi, I have a registration form which consists of, amongst others, an email field. When the user enters their email address, the onChange event is fired and a server side page method is called which checks the email address and returns a boolean value. This works fine when invoked from the onChange event of the textbox. The problem occurs when the submit button is clicked; the submit button invokes the Javascript validation function and posts back if the form is valid, however, because the email validation involves an AJAX server side call, the function isn't waiting for the response and so causes the form to be submitted regardless of the email validation result. I hope I have explained this adequately but if not I have included a cut down version of my page:
var pageIsValid; var emailAddressMessage; function ValidateForm() { pageIsValid = true; PageMethods.EmailAddressIsValid(document.getElementById('<%= txtNewMemberEmailAddress.ClientID %>').value, ValidateEmailAddressSuccess, ValidateEmailAddressFailed); // other validation calls have been left out if (pageIsValid == false) { alert('Some information is either missing or invalid. Hover your mouse over the red crosses for more information'); } return pageIsValid; } function ValidateEmailAddressSuccess(result) { if (result == false) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; emailAddressMessage = 'The email address you have entered is already in use'; pageIsValid = false; } else { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/tick.png"; emailAddressMessage = 'This field is valid'; } } function ValidateEmailAddressFailed(result) { document.getElementById('<%= imgNewMemberEmailAddress.ClientID %>').src = "/Images/cross.png"; alert(result.get\_message()); }
If anyone could suggest a better way of doing this it would be appreciated. Thanks Jay
wow that got complicated submit button > client script- if valid postback So I would just add the onClientClick="return validate_Form();" And write a simple function first in javascript/jquery test if the fields are empty test the field data regex the email address, if validation completes, then return true to fire the postback Then you can get fancy, and add an ajax call to check for duplicate email address, I would use onblurr for that, so it only fires once, and if a duplicate exist, focus the email field again.