Try to set custom validation message with jQuery Remote

Your code...

$('#username').rules("add", {
    onfocusout: false,
    onkeyup: false,
    required: true,
    email: true,                    
    remote: { ... },
    messages: { ... },
    success: function (label) { ... }
});

The problem here is that onfocusout, onkeyup and success are not "rules". Only individual "rules" and the messages option can be placed inside of the .rules('add') method.

$('#username').rules("add", {
    required: true,
    email: true,                    
    remote: { ... },
    messages: { 
        remote: "custom remote message"
    }
});

See documentation for .rules() method: http://jqueryvalidation.org/rules

onfocusout, onkeyup and success are "options" that only go inside of the .validate() method, which is only attached to the <form> element.

As far as a "custom" message for remote: As per the docs, this error message is automatically going to be the message returned from your server... there is no special setup.


EDIT as per comments and updated OP:

Your code:

$('#form').validate({
        onfocusout: false,
        onkeyup: false,
        onclick: false,
        success: function (){
            $('#username').addClass('input-validation-confirmation');
        }
});

You stated, "Still, with updated code (see above) I never see the success event."

You've disabled all the events on this form. The only event left for triggering validation on this field is when the submit button is clicked. Exactly when do you expect to "see" success fire off?

DEMO: http://jsfiddle.net/xMhvT/

In other words, submit is the only event left to trigger a validation test when you've disabled all the other events.


EDIT based on another OP update:

"I now understand I was expecting a success event at the wrong time. I need an event that is fired once validation has completed (not submitted). Is there any such event?"

success is not an "event". An "event" is a click, blur, keyup, etc. (onkeyup, onfocusout and onclick are options that control the events for this plugin)

success is a "callback function". A "callback function" is what happens upon the event.

• If you need a "callback function" that fires every time a field passes validation, then you can use success.

• If you need a "callback function" that fires when the form passes validation, then you can use submitHandler. However, this is also when the form is submitted.

• If you want to "test" the entire form or a single field to see if it's valid without submitting the form, you can use the .valid() "method".

$('#username').valid();  // for one field

// or

$('#form').valid();  // for the whole form

// you can also...

if ($('#form').valid()) {
   //do something if form is valid
}

This method will fire the test (show the message) and return a boolean value.

DEMO: http://jsfiddle.net/xMhvT/1/

See: http://jqueryvalidation.org/valid/


I am late to answer this question but I think it may help others:

in your php just need to add the following

if($rows_matched==1){
          echo (json_encode(false));
        }
        else{
          echo (json_encode(true));
        }

and in your js code write the followiing: $(function(){

$('#product_add').validate({
rules:{
  product_sku:{
    remote:{
      url:'check.php',
      type:'POST'
    }
  }
},
messages:{
  product_sku:{
    remote:'already in database'
  }
}
});

});


Use the remote, dataFilter and messages parameters like this:

var message = 'Default error message';

$('form').validate({
    rules: {
        element1: {
            remote: {
                url: '/check',
                type: 'post',
                cache: false,
                dataType: 'json',
                data: {
                    element2: function() {
                        return $('.element2').val();
                    }
                },
                dataFilter: function(response) {
                    response = $.parseJSON(response);

                    if (response.status === 'success') return true;
                    else {
                        message = response.error.message;
                        return false;
                    }
                }
            }
        }
    },
    messages: {
        element1: {
            remote: function(){ return message; }
        }
    }
});