title: jQuery Validation: Custom validator with AJAX
body: <p>OK, I give up. After trying endless permutations of inline functions, callbacks, return parameters, I still cannot get this to behave how I want. Any help would be appreciated.</p>
  
  <p>Current status: everything works except the 'checkEmail' error message. The javascript popups convey the proper messages to the user, but the field will not show any error message, whether true or false is returned by the handlers.</p>
  
  <p>The desired outcome is that if the JSON payload from the AJAX call is anything other than a 200, to pop a Javascript alert and highlight the field as invalid with the appropriate error message.  Currently, it pops the alerts, but doesn't mark the field as invalid.</p>
  
  <p>(Sorry, this is jQuery 1.7 + jquery.validation plugin)</p>
  
  <h2>JSON responses:</h2>
  
  <p>Our JSON response payloads look like this:</p>
  
  <pre><code>{"message": "Email is not in use.", "code": 200, "email": "test-39485787@mailinator.com"}
  </code></pre>
  
  <p>or</p>
  
  <pre><code>{"message": "Duplicate email address detected", "code": 401}
  </code></pre>
  
  <h2>The code</h2>
  
  <pre><code>&lt;html&gt;
  
  &lt;head&gt;
  &lt;script&gt;
  
  // You'd think this should be false, but no
  // Also it apparently needs to be a quoted 
  // string: http://stackoverflow.com/a/11496502/814669
  var checkEmailStatus = "true";
  
  // Success Handling
  checkEmailSuccess = function(data, textStatus, jqXHR) {
      checkEmailStatus = "true";
      switch (data.code) {
          case 200:
              checkEmailStatus = "false"; // Nothing set here matters
              return false; // Return valued from here don't matter
          case 401:
              alert("Sorry, our system has detected that an account with this email address already exists.");
              break;
          case undefined:
              alert("An undefined error occurred.");
              break;
          default:
              alert("An undefined error occurred.");
              break;
      }
      return checkEmailStatus;
  };
  
  
  // Error Handling
  checkEmailError = function(jqXHR, textStatus, errorThrown) {
      if (jqXHR.status == 404) {
          alert("Could not find the API Server (404). We apologize for the inconvenience.");
      } else {
          alert("Terrible things have happened" + textStatus);
      }
      return false;
  };
  
  
  // The Validator
  jQuery.validator.addMethod("checkEmail", function(value, element) {
  
      $.ajax({
          type: "POST",
          cache: "false",
          async: "false",
          url: "/json/checkEmail",
          dataType: "json",
          data: {
              email: function() {
                  return $("email").val();
              }
          },
          success: checkEmailSuccess,
          error: checkEmailError
      });
  
      // Seems checkEmailStatus value never gets changed:
      return checkEmailStatus;
  
  }, "Email Address Problem");
  
  
  // The Binding
  $(document).ready(function(){
      $('#MyForm').validate({
          onfocusout: false,
          onkeyup: false,
          rules: {
              "email": {
                  required: true,
                  minlength: 2,
                  maxlength: 42,
                  email: true,
                  checkEmail: true
              }
          }
      });
  });
  
  &lt;/script&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
  
      &lt;!-- the Form --&gt;
      &lt;form id="MyForm"&gt;
          &lt;input type="text" name="email"/&gt;
          &lt;input type="submit" name="submit"/&gt;
      &lt;/form&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>