I'm using the jQuery Validation plugin along with the qTip2 plugin to display the errors.
I've setup two jsFiddles to demonstrate a curious problem I'm having. The first two fields are "required", the third & fourth fields are "optional" while the third field is validating a phone number.
When I fill out the optional phone number field, I'm still validating the phone number even if it's not required. However, if the user puts in an invalid number (gets an error), changes their mind and backspaces the phone number field, the error message should go away.
It's working as expected here (Validation plugin with standard errors (no qTip2)):
jsFiddle #1: http://jsfiddle.net/avJ54/2/
The problem is that it does not work while using qTip2 to display the errors:
jsFiddle #2: http://jsfiddle.net/WKryu/3/
On the element, the error
class is correctly removed and replaced with the valid
class but apparently the success
handler does not fire. However, qTip2 depends on the success
handler to fire in order to destroy any error bubbles.
Two things will force the success
handler to fire and clear out this error.
1) Hitting the submit button.
2) Filling out a "required" field and losing its focus.
So the issue is: I can't seem to get qTip2 to remove the error bubble immediately on optional fields when they're blanked out, similar to how it works in the first jsFiddle.
Since the success
handler only seems to fire when losing focus of "required" fields, is there a way to get it to fire when losing focus of any field? This would solve the issue most easily.
Edit: I put an alert()
on the success handler and it only fires when you lose focus of any field that is validated. The weird part is that despite my phone
method, the success handler only fires when you lose focus after a valid phone number is entered. However, technically, when the field is blanked out and the default value is displayed, it's also a "valid" field, yet success
does not fire. In other words, when blanking out the field and losing focus, the class immediately changes to .valid
but the success
handler never fires. This is what most perplexes me and for what I'm seeking an explanation.
Perhaps my assumption about the but I cannot yet decipher what I need to do in order to get this all working properly.success
handler not firing is wrong,
A clue?: Simply removing the default field value gets it working...
jsFiddle #3: http://jsfiddle.net/BwNLs/
However, that's not really what I want (I need the default field values as part of my design). Clearly, toggling the default field values is not a problem in jsFiddle #1... it only becomes a problem when introducing qTip2.
It's some combination of using qTip2 along with the default field values causing all these headaches. Hopefully, one of you can see where I am blind.
Through much experimentation, here is what I've learned so far (besides desperately wishing there was more detailed documentation available):
1) The success
handler fires right after losing focus of a field that was just validated with a specific exception: I think it's a timing issue... the default value is put back at the same time the plugin is doing the validation.
2) The success
handler fires at the same exact instances in both jsFiddle cases 1 & 2 above. The difference is that the error messages in the first test case are toggled between display:none
and display:inline
internally by the plugin. However, in the second test case, the qTip message bubbles are toggled via the errorPlacement:
and success:
handlers.
3) The valid
and error
classes are toggled identically in both cases. In the second test case, it seems that despite a class toggling from error
to valid
, it does not necessarily mean that success
will fire. It seems that although the class is valid
, having a default value put back into the field somehow prevents success
from firing. Why?
Workaround (temporary?):
I added the onfocusout
handler to .validate
like this:
onfocusout: function(element) {
$(element).valid();
$(element).filter('.valid').qtip('destroy');
},
onfocusout
is normally a boolean (as per the docs), so putting a function in there destroys the normal functionality when you lose focus. I had to invoke valid()
on the first line to replace the normal onfocusout
functionality that is lost. (what I don't understand is how the documentation fails to mention that you can replace a boolean with a function). (EDIT: I took a peak inside the plugin and despite the docs, onfocusout
is not a boolean, it's a function. I noticed quite a few things in there either completely missing from, or opposed to, the official documentation) 1
Then since I cannot rely on the success
handler to fire when focus is lost, I've added a line that destroys the qTip bubble if the class says the field is valid
.
The only thing about my workaround is that it slightly changes the normal behavior. Normally, when you first load the page you can tab between the "required" fields without any error messages until you hit the submit button which then lights up all empty required fields. After installing my workaround, simply tabbing to & from an empty field lights up that one error message.
I love the Validation plugin. I just wish there was a dependable way to manually duplicate any default functionality. It seems that every time I manually use a method, there are mysterious unexplained side effects to the other default behaviors.
I'll expand upon this answer as my time permits.
EDIT 2:
1 Clarification on onkeyup:
, onfocusout:
, and possibly many of the other options: These options default to true
("on") according to the documentation, but they're really backed up by internal functions. In other words, you can set these options to false
within your .validate()
setup, but you cannot set them to true
without breaking the plugin.