views:

366

answers:

2

I have some validation on a text input bound to its blur event. I have a datepicker on this field (the version from jqueryUI), so when you click the field, datepicker shows up, then you click a date and it populates the date into the field as datepicker does. However, right before the date is entered it seems the input field gets its blur fired for some reason. It looks like focus goes away from the input before the date gets populated. So my validation gets fired right at the point when the user selects a date, before the date actually makes its way into the field, when it shouldn't. It should be running after the date gets put in. Does anyone know why the blur is is happening at that point or how to work around it?

+3  A: 

When the user clicks outside the input field (to choose a date), the input field will blur. There's no way around that. So, instead of triggering the validation on blur, use the datepicker's onSelect callback.

$('.selector').datepicker({
    onSelect: function(dateText) { /* validation here */ }
});

If you want to keep your onblur-events, you could postpone validation to allow for the datepicker to fill out the field before the validation fires, like this:

$('#myform input').blur(function () {
    setTimeout(function () { /* validation here */ }, 1);
});

Using setTimeout to handle concurrency-issues may look like a hack, but due to JavaScripts single-threaded nature, it works quite nicely. John Resig of jQuery-fame talks about it in this blogpost.

Magnar
Hmm this may work. I'd have to make a way around registering the validation to the blur for datepicker'ed fields, as my validation blur event handlers are registered to all text fields in onload, but feasible.
perrierism
I added a different approach that may suit your needs better.
Magnar
Sweet. Thanks for all your help. Agree, with one thread setTimeout is for exactly this
perrierism
A: 

Magnars answer above is very good. Just to give some more info for progeny here is also an approach that works well with validation frameworks that do validation on blur. I'm actually unbinding the blur event that was set up by the validation on document.ready/pageload (pretty common pattern for validation), and then putting it back in the onclose datepicker option. The datepicker close event apparently happens after datepicker has passed the info into the field, so it's ok for the blur validation to run at that point. This way I don't have to do anything special for the field in the validation code itself. Either approach is probably applicable to whatever anyone else is doing if they come across this.

$('#datefield').datepicker(
{beforeShow: function(input) {
                             $(input).unbind('blur');
             },
 onClose: function(dateText, inst) {
                             $(this).validationEngine();this.focus();this.blur() }
});

(In my framework '.validationEngine()' is what registers the validation handlers)

perrierism