views:

59

answers:

3

Hi,

I'm trying to do the following: I've got a form that is validated with the jQuery Validation Plugin. There is a field which has a couple of rules:

            var validator = $("#myForm").validate({ 
                rules: {
                    emailForRequest: { 
                        required: true, 
                        email: true,
                        remote: "'emailcheck.php"
                    } 
                } ,
...

Now, when one of the rules is broken, more precisely the remote rule, I want to trigger some extra code. So, if the remote rule returns an error and it's error label appears next to the emailForRequest field, I need a callback that does some other things in the background.

In short: can I see which rule triggers the error, see it code-wise I mean, and attach the execution of an extra function to it?


EDIT Ok, thanks to Liam's answer and a better read of the manual I came to this:

        rules: {
            emailForRequest: { 
                required: true, 
                email: true,
                remote: {
                    url: "'emailcheck.php" ,
                    type: "post" ,
                    complete: function(data){
                        if( data.responseText != "true" ) {
                            alert("Sorry mate, this email address was registered but never activated!");
                        }
                    }
                }
            } 
        } , ...

But one problem remains. the emailcheck.php script can return 3 different results one of which is true and the other 2 are language dependent. So I would like to sent a json object as the response with a var for the error type (the same in all languages) and a var with the message (translated). So, In my complete function I can then do a check on the error type and respond according to that. Easy enough, except it will screw up the validation standard error that's supposed to appear next to my field and I haven't found a solution for that yet.

+1  A: 

Now i've had proper time to go through manual, try this

var validator = $("#myForm").validate({ 
            rules: 
               {
                emailForRequest: 
                { 
                    required: true, 
                    email: true,
                    remote: "emailcheck.php"
                }
            },
            messages:
            {
              emailForRequest:
               {
                remote: jQuery.format("{0}")
               }
            }

       });
Liam Bailey
Weird, your answered was gone for a sec, and now I can access it again. See the edit of my original question to see what I've got so far.
Peter
I have edited my answer, that should do the trick. If you return true of false from your php it will show default message, but if you return a string it will show the string.
Liam Bailey
Hey Liam, returning the error string never was a problem, it's the default behaviour of the validator. The problem was that somewhere in the process I needed to recognize, code-wise, which error was thrown without depending on the string, as the string itself is variable per language. Anyway, thanks for thinking with me. I found a solution which I'll pour into an answer in a minute.
Peter
+1  A: 

jquery.validate.js - line 941:

success: function(response) {
    validator.settings.messages[element.name].remote = previous.originalMessage;
    var valid = response === true;
    if ( valid ) {
    ....

I think you could quite easily insert your own function here. You have both the response and the element name available, so targeting an element with a particular name would be fairly easy. If you don't want to modify the script itself (i.e. it's being loaded from the CDN server) you could write your own remote validation rule based on the original one.

Other than that, AFAIK, there is no built-in function/method that would return the name of the rule which didn't validate.

UPDATE

A workaround for finding both the rule and the element that triggered it would be to handle it all in the errorPlacement function:

...
},
errorPlacement: function(error, element) {
    error.insertBefore(element); // default positioning

    if ((error == 'your error message') && (element.attr('id') == 'your_targets_id')) {
        // your function 
    }
},
...

Hope this helps.

FreekOne
Hey FreekOne, thanks for the input. I'm very close to a solution based on Liam's earliers (and disappeared?) answer and close to what you suggest but in a different spot. Check the edit of my original question.
Peter
Please see my updated answer. You would basically identify the rule by the error message, and the element by its ID. I haven't tested it, but it should work.
FreekOne
Cheers mate! But I have a problem here, I can't use error == 'your error message' because I don't know the error message (it's language dependent and changeable by our customers). But it's another most interesting trajectory!
Peter
You're not making this any easier :D How about adding a prefix server-side, just for this rule ? Something like 'remote_The rest of your error message' and then in the `errorPlacement` function you would check for that prefix ? If it is found, you would know which rule triggered it, strip he prefix, output the error message and then run your function.
FreekOne
Of course, you would then have to move the actual error placement line below your custom check so you can output the un-prefixed error message.
FreekOne
Very, very close FreekOne, and the comment that eventually led me to finding an answer. If I add a normal prefix, I don't have a clue of where and when to strip it, or from what to strip it. I've been unable to trace down exactly what happens and is used where in the validation script. However, a "hidden" prefix is a workable, though not ver clean, solution. So thank you very much for putting me on the right track and check out my answer below.
Peter
A: 

Thanks to FreekOne and his idea of a prefix I came to a workable solution. I do say workable, as I'm not very happy with the cleanness of it. As I don't know exactly what happens where in the validator and tinkering around with the dataFilter and success functionality of the ajax call disrupted the normal working of the validator, I came to the following solution with a "hidden" prefix:

var validator = $("#myForm").validate({ 
                rules: {
                    emailForRequest: { 
                        required: true, 
                        email: true,
                        remote: {
                            url: "emailcheck.php" ,
                            type: "post" ,
                            complete: function(data){
                                if( data.responseText != true ) {
                                    if( data.responseText.search(/validationErrorTag/) > 0 &&
                                        data.responseText.search(/inactive/) > 0 ) {
                                         inactiveFunctionality();
                                    }
                                }
                            }
                        }
                    } 
                } ,...

While the emailcheck.php returns a json encoded true if everything checks out or json encoded error message like

<span class="validationErrorTag">inactive</span>This address is not yet activated.

Finally, I have an entry in my css file to make sure that the prefix doesn't show up:

.validationErrorTag {
    display: none;
}

Like I said, it works and I'm going to use it for now, but working with hidden html prefixes to recognize the error message seems a little crude to me. So, if anybody knows a better solution, please let me know.

Peter