English 中文(简体)
jqueryUI datepicker fires input s blur before passing date, avoid/workaround?
原标题:

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?

最佳回答

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.

问题回答

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.





相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签