pickadate.js
pickadate.js copied to clipboard
Picker opening when leaving / coming back to browser window
First of all, Pickadate is just awesome (well built, great api, highly extensible, a pleasure to work with).
Thanks for it, I just discoverd it and I feel that it will become my only reference for date/time picker.
I did find a small issue that I think can be easily fixed:
Steps to reproduce:
- Go on http://amsul.ca/pickadate.js/index.htm
- Click on the first picker input
- Click on a date to choose one (picker should close itself)
- Click out of browser window
- Click in the browser window (anywhere in the page)
- BUG: The picker opens without the user clicking on it
Tested on Google Chrome Version 27.0.1453.110
I hope you have enough infos to fix, keep on the great work!
It's a focus/blur thing, i've done this to fix it
onClose: function() {
$('.datepicker').blur();
}
I've done this for both date and time pickers.. but yeah it's annoying
Thanks for the tip, I'll do that for now.
Once again, @brunogaspar, thanks for the quick tip.
The only shortcoming of this solution is that the users lose their tabindex flow – which can be especially annoying if the field falls within a long form.
The only solution off the top of my head is to watch the page visibility api. When the user focuses onto the page and the date input was the last focused element, trigger a picker.close(true)
to keep it closed with focus.
I noticed an issue, not sure if it is related to the snippet i posted, but if i press the enter key it opens the date/picker-picker, my workaround was to disable the enter key on forms that has date/time pickers, but i haven't done much testing to see what is the cause.
@brunogaspar, the solution works for me - thank you.
Same, annoying thing.
@amsul should we be aiming to add our own event hooks with the page visibility API or is this something that can be added to the API?
@darrenhaken, you’d have to add your own event hooks - there’s nothing within the API that compensates for it just yet..
@amsul why not include @brunogaspar 's solution to the project's code.
onClose: function() {
$('.datepicker').blur();
}
I consider this as a bug. :bug:
@lijunle because that’s not really great for accessibility. You lose keyboard focus from the input
field.
The right way to do it is by checking the page visibility and closing it with focus if needed.
I’ve marked this for release in v3.6. If someone wants to take a stab at it, please feel free to :)
Hi, @amsul . Thanks for your reply,
I do not get your meaning of
The right way to do it is by checking the page visibility and closing it with focus if needed.
Could you please explain more?
@lijunle yeah, in a comment above I wrote:
The only solution off the top of my head is to watch the page visibility api. When the user focuses onto the page and the date input was the last focused element, trigger a picker.close(true) to keep it closed with focus.
Here’s the page visibility API: https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API
@amsul
I don't think the datepicker should pop up once the input box is focus. Split the focus and date picker pop up to two stages is better:
- Use
TAB
to loop over the input boxes. - When datepicker input box is focused, input box show "press space or enter to show date picker".
- Then press
space
orenter
, datepicker pops up. - Press
esc
to close the pop up dialog, the return to point 2.
With this approach, there is no need to use visibility API. How do you think about this?
@lijunle that’s an interesting approach.
Although, I feel that it should only be split into two steps if there’s a way to enter data without the picker being opened.
That’s why the native date input on desktop splits it into a separate "dropdown" button, whereas on mobile it's a one tap action because it’s the only way to enter a value.
But regardless, using the current API, you can already achieve the mechanics you’re proposing by initializing like this:
$('#input').pickadate({
editable: true
})
..and then binding a focus event that does something like this:
$('#input').on('focus', function() {
// open the picker when enter/space is pressed
})
So any progress on this? It's been nearly 2 years for such an apparent bug
I just did:
$picker.on 'close', ()->
$(document.activeElement).blur()
To prevent the re-opening after switching tabs
@RobertLowe working nice : )
Thanks
I added a check onOpen to see if the target class is already present. Does the job well enough for my situation:
$input.pickadate({
onOpen: function () {
if ($input.hasClass('picker__input--target')) {
$input
.pickadate()
.pickadate('picker')
.close(true);
}
}
});
@RobertLowe thanks, got this working with:
onClose: function(){
$(document.activeElement).blur()
}
Yea thanks @RobertLowe. Your solution worked better than trying to target the right element via a class selector.
@lijunle Where do i add the code you have suggested ? Thanks.
@aravindsanker which suggestion do you refer to? The onClose
one, or this post? For the first one, add it to pickadate initialization option object. For the second one, I have not try to implement it.
I found out I have to blur the .picker div as well after I blurred the .datepicker div So my code is:
onClose: function(){
$('.datepicker').blur();
$('.picker').blur();
}
@RobertLowe Thank you so much, best solution in the thread.
Why isn't this documented?
@jpfortier it's working, and only it, but only with first input. With second already not
I have chosen this approach, maybe it helps
jQuery(window).blur(function() {
var $focused = jQuery(document.activeElement);
if ($focused.hasClass('picker__holder')) {
jQuery(document.activeElement).blur();
}
});
onClose: function(){
$(document.activeElement).blur();
}
Works for me too. It appears to be a bug : should release the focus when the dialog is closing.
Guys, I want to go to next field if I press TAB, but Datepicker is opening. I am already tried the blur method, but it's not working. Maybe because I am using date and time picker together?
$(document).ready(function()
{
var datepicker = $('#date').pickadate({
formatSubmit : 'yyyy-mm-dd',
hiddenSuffix: 'date_submit',
firstDay: 1,
container: '#outlet',
onSet: function(item) {
if ( 'select' in item ) setTimeout( timepicker.open, 0 )
}
}).pickadate('picker')
var timepicker = $('#time').pickatime({
min: [09,00],
max: [17,00],
format: 'HH:i',
formatSubmit: 'HH:i'+':00',
hiddenSuffix: 'time_submit',
container: '#outlet',
onRender: function() {
$('<button class="picker__button--clear">Vissza</button>').
on('click', function() {
timepicker.close()
datepicker.open()
}).prependTo( this.$root.find('.picker__box') )
},
onSet: function(item) {
if ( 'select' in item ) setTimeout( function() {
$datetime.
off('focus').
val( datepicker.get() + ' @ ' + timepicker.get() ).
focus().
on('focus', datepicker.open)
}, 0 )
}
}).pickatime('picker')
var $datetime = $('#tm').
on('focus', datepicker.open).
on('click', function(event) { event.stopPropagation(); datepicker.open() })
$('#form').on('keyup keypress', function(e) {
var code = e.keyCode || e.which;
if (code == 13) {
e.preventDefault();
return false;
}
});
// enter keyd
$("body").keypress(function(e) {
if(e.keyCode==13 && e.ctrlKey) {
$('#form').submit();
}
});
});
@adrianmihalko I have same problem