Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

You can try this :

$(".date-pick").datepicker({
...
onSelect: function() {
this.focus();
},
onClose: function() {
this.blur();
}
...

I found the only way to consistently get both the keyboard and the picker select events working was with the following code:

 $(".date-picker")
            .datepicker("option", "onSelect", function (dateText, inst) {
                // User Method
            })
            .change(function () {
                // User Method
            });

The problem with using just the blur event is that (when selecting) the datepicker fires the blur event on the input before the the value has been passed to it.

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)

Bumping this thread because I had some difficulty with the accepted solution.

I found it easiest to trigger 'change' event when datepicker's 'onClose' event fires. This ensures that the input element's change event always fires:

$('#my_element').datepicker({
    onClose: function() {
        $(this).trigger('change');
    }
});

This may seem silly because it will fire at times when nothing has been changed. However, it works more reliably than datepicker's 'onSelect' and helped me to avoid problems with focusout or blur events firing before the datepicker events.

Create your custom event in jquery and bind it to textbox . After that trigger the event on onClose event of datepicker. By that if you move out of the textbox then custom event will get fired.

$("inputText").bind('CustomEventName',function(){//your validate method code});

and in the Datepicker

$("#inputText").datePicker({onClose:function(){ $(this).trigger('CustomEventName')});

I had the same problem as you, and Magnar's answer helped but did not completely answer the problem.

You have identified the underlying cause. The action of the user interacting with the calendar removes focus from the input field. This (in the case of jquery unobtrusive validation) will cause the onBlur event to fire, triggering the validation of that input field. At this point the value is still the previous value, until the user selects something.

Hence, building on Magnar's answer he states that you need to re-validate the input field onChange of the calendar. The most obvious way is to call $("form").valid(), however this validates the entire form.

A better way is to just validate the input field connected to the date picker, and you can trigger that by doing this:

$('#myform input').blur(function () {
    var that = this;
    setTimeout(function () {
        $(that).trigger("focus").trigger("blur");
    }, 100);
});

Now only your input field is validated, because you've faked the user clicking in and out of the input field.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top