2

Useful references:

The question:

  1. Why is the jQuery.validation "documentation" so obtuse, with a serious lack of even basic examples?

  2. The real question:

I have a custom validator that does an AJAX call. That call can return various values which will require different error messages. I can't seem to discern how to get the error message to be varied based on the responses. Some code:

<html>
<head>
<script>
// Set error value variable default & scope
var checkEmailErrorMessage = "API Error";

// AJAX Failure Error
checkEmailError = function(jqXHR, textStatus, errorThrown) {
    if (jqXHR.status == 404) {
        alert("Could not find the API Server (404)");
    } else {
        alert("Some horrifying error occurred: " + textStatus);
    }
    return false;
};

// AJAX Success Handler
checkEmailResponse = function(data, code, jqXHR) {
    switch (data.code) {
        case 200:
            return true;
        case 401:
            checkEmailErrorMessage = "Duplicate Email";
            alert("Sorry, our system has detected that an account with this email address already exists");
            break;
        case 403:
            checkEmailErrorMessage = "Invalid Email";
            alert("Sorry, our system has detected that this email is forbidden");
            break
        case undefined:
            alert("An undefined error occurred.");
            break;
        default:
            alert("A horrible error occurred.");
            break;
    }
    return false;
};

// The Custom 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: checkEmailResponse,
        error: checkEmailError
    });

}, checkEmailErrorMessage);

// The Validator Settings
form_validation_settings = {
    onkeyup: false,
    rules: {
        "email": {
            required: true,
            minlength: 2,
            maxlength: 42,
            email: true,
            checkEmail: true
        }
    }
};

// The Binding
$(document).ready(function(){
    $('#MyForm').validate(form_validation_settings);
});

</script>
</head>

<body>

    <!-- the Form -->
    <form id="MyForm">
        <input type="text" name="email"/>
        <input type="submit" name="submit"/>
    </form>

</body>
</html>

No matter what, the error message is "API Error". The Validation docs state:

messages: Can be a function created by "jQuery.validator.format(value)".

But how would I rig this up? Any functions I would call would need to be results of the AJAX call.

Any ideas are appreciated. Thanks in advance!

Community
  • 1
  • 1
Spanky
  • 5,608
  • 10
  • 39
  • 45

2 Answers2

0

You have two options:

  • Remote works by requiring you to return a JSON string that is 'true'. You can return the full error message as a quoted string from your AJAX call:

pseudo code:

  print '"'.messages[code].'"';
  • Return the error code, and then have a dataFilter on your ajax call that converts that to the message you want:

somewhere else you have setup a messages array like so:

 var messages = ['Code 0 error message','Code 1 error message', etc ];

       //in your validate rules
       remote: {
            url: 'foo.php',
            dataFilter: function (data, type) {
                return '"' + messages[data] + '"';
            },
            type: 'post'
        }    

Working examples for option 1, option 2

Ryley
  • 21,046
  • 2
  • 67
  • 81
  • Thanks for these examples. FWIW, I'd given up on using 'remote' because of the true/false thing, it seemed to me I would get the control I needed just handling the AJAX myself. – Spanky Jun 07 '13 at 17:29
  • 1
    You'll find a whole new raft of problems trying to integrate your own AJAX calls with Validate :) – Ryley Jun 07 '13 at 21:24
  • it's true. More than a raft, an entire ship. – Spanky Jun 07 '13 at 21:52
  • It looks like it's going to have to come down to some kind of dataFilter thing. After I get it working, I'll give @ryley the checkmark. – Spanky Jun 07 '13 at 23:16
0

Just ran into this same problem and didn't see an answer that worked for what I was trying to do but I was able to figure out how to do the needful. Anyone faint of heart please avert your eyes now.

I wanted to do was to give more detailed info about exactly why the field was being rejected so that the user wouldn't be guessing what the input should look like. The validator needed to check hostnames and the regex is pretty complex (BTW, did you know that "0.256.1" is a valid hostname?!)

Anyways, here's how I was able to create more detailed error messages:

// helperfunctions.js
function validhostname(value) {
  if(value.length > 254) {
    return {pass: false, str: "hostname too long (" + value.length + ")." }
  }
  if(/[^a-zA-Z0-9\-_\.]/.test(value)) {
    return { pass: false, str: "No special characters besides '-' or '_'." }
  }
  ...
  return { pass: true,  str: "valid hostname." };
}

// clientfunctions.js
var hostnameval = {};

jQuery.validator.addMethod(
  "hostname", 
  function(value, element) {
    hostnameval = validhostname(value);
    return this.optional(element) || hostnameval.pass;
  },
  function() {
    var ret = hostnameval.str || "Invalid hostname.";
    hostnameval = {};
    return ret;
  }
);

So far "message" has never been called prior to "method" returning so I've yet to see the "Invalid hostname." string displayed. I wish that there was a less hacky way of doing this and would be delighted to be shown that there is.

Community
  • 1
  • 1
keithpjolley
  • 2,089
  • 1
  • 17
  • 20