Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Thomas,</p> <p>You need to cater for the inherent asynchronicity of ajax, in other words you need to wait until a response to the ajax request has arrived before deciding what to do.</p> <p><a href="http://api.jquery.com/category/deferred-object/" rel="nofollow">jQuery's Deferreds</a> (and promises) allow us to write simple code but Deferreds tend to blow you mind at first, at least very slightly.</p> <p>There's no unique way in which to use Deferreds for a problem like this but here's one.</p> <pre><code>$(document).ready(function() { $('#submit_pw_ch').on('click', function() { var form = this.form; //the form containing the submit button and the fields . //`alertArr` is an array to which messages will be added. var alertArr = ["Please correct the following errors:"]; //`addAlert` will be called from a `Deferred.resolveWith(this, ...)` statement. //The context, `this`, is unused. function addAlert(index, txt) { alertArr[index] = txt; } //`compositeAction` will be called from a promise.done() statement. function compositeAction() { //first filter out null messages (ie. validation successes) from alertArr. var message = $.map(alertArr, function(txt, i){ return txt || null; }); if(message.length &gt; 1) { //then alert the complete message with line breaks alert(message.join("\n")); } else { //submit the form to change the password //or another ajax call as required form.submit(); } } // Invoke ajax validators and assign returned promises. // An index is passed, so the text messages can be displayed in a logical order, // regardless of the order in which the validation promises are resolved. //If we didn't care about the order of the messages then the code would be slighly simpler. var vUsr = valUsr(0), vPwd = valPwd(1), sPwd = samePwd(2); //All validations adopt a similar pattern regardless of whether ajax is involved or not. //Here, we establish what is to be done when the promise are resolved, or //what is to be done immediately if the promise are alrady resolved. vUsr.done(addAlert); vPwd.done(addAlert); sPwd.done(addAlert); //At this stage, `addAlert` will contain entries for successful as well as unsuccessful validations. Successful entries will be filtered out by `compositeAction` //Establish what is to be done when all three promises are resolved. $.when(vUsr, vPwd, sPwd).done(compositeAction); //Return false unconditionally return false; }); function valUsr(index) { var messages = { validated: '',//important - this message must be an empty string - do not change notValidated: '- Your current username and password are invalid.', ajaxError: '- Validation error: username and password.' }; //Create a Deferred object, which will be resolved in response to several different outcomes. var def = $.Deferred(); $.ajax({ type: "post", url: "queries/confirm_user.php?&lt;?=time()?&gt;", data: { 'un': $('#uNameInput').val(), 'pw': $('#uPwdInput').val() }, dataType: "json", success: function (returnedData) { if (returnedData == 'true') { def.resolveWith(this, [index, messages.validated]); } else { def.resolveWith(this, [index, messages.notValidated]); } }, error: function() { def.resolveWith(this, [index, messages.ajaxError]); } }); return def.promise();//Return a promise derived from the as yet unresolved Deferred. } function samePwd(index) { var pw1 = $('#uPwdInput').val(); var pw2 = $('#uPwdInput2').val(); var errMessage = (pw1 === pw2) ? '' : '-The confirmation of your new password does not match the previous entry'; var def = $.Deferred();//Create a Deferred object, which will be resolved immediately def.resolveWith(this, [index, errMessage]); return def.promise();//Return a promise derived from the already resolved Deferred. } }); </code></pre> <p><code>valPwd()</code> will be of the same format as either <code>valUsr()</code> or <code>samePwd()</code>, depending on whether ajax is involved or not.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload