pickadate.js icon indicating copy to clipboard operation
pickadate.js copied to clipboard

Picker opening when leaving / coming back to browser window

Open happypoulp opened this issue 11 years ago • 48 comments

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:

  1. Go on http://amsul.ca/pickadate.js/index.htm
  2. Click on the first picker input
  3. Click on a date to choose one (picker should close itself)
  4. Click out of browser window
  5. Click in the browser window (anywhere in the page)
  6. 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!

happypoulp avatar Jun 27 '13 15:06 happypoulp

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

brunogaspar avatar Jun 27 '13 15:06 brunogaspar

Thanks for the tip, I'll do that for now.

happypoulp avatar Jun 27 '13 15:06 happypoulp

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.

amsul avatar Jun 28 '13 20:06 amsul

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 avatar Jun 28 '13 20:06 brunogaspar

@brunogaspar, the solution works for me - thank you.

soaptray avatar Sep 12 '13 18:09 soaptray

Same, annoying thing.

Winni- avatar Jan 11 '14 11:01 Winni-

@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 avatar Feb 24 '14 09:02 darrenhaken

@darrenhaken, you’d have to add your own event hooks - there’s nothing within the API that compensates for it just yet..

amsul avatar Mar 05 '14 15:03 amsul

@amsul why not include @brunogaspar 's solution to the project's code.

onClose: function() {
    $('.datepicker').blur();
}

I consider this as a bug. :bug:

lijunle avatar Jul 23 '14 18:07 lijunle

@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 :)

amsul avatar Jul 30 '14 03:07 amsul

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 avatar Jul 30 '14 03:07 lijunle

@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 avatar Jul 30 '14 03:07 amsul

@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:

  1. Use TAB to loop over the input boxes.
  2. When datepicker input box is focused, input box show "press space or enter to show date picker".
  3. Then press space or enter, datepicker pops up.
  4. 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 avatar Jul 31 '14 11:07 lijunle

@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
})

amsul avatar Aug 23 '14 23:08 amsul

So any progress on this? It's been nearly 2 years for such an apparent bug

thanpolas avatar Feb 09 '15 08:02 thanpolas

I just did:

$picker.on 'close', ()->
  $(document.activeElement).blur()

To prevent the re-opening after switching tabs

RobertLowe avatar Feb 18 '15 05:02 RobertLowe

@RobertLowe working nice : )

Thanks

rroblik avatar Mar 02 '15 10:03 rroblik

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);
        }
    }
});

jpfortier avatar Mar 03 '15 14:03 jpfortier

@RobertLowe thanks, got this working with:

onClose: function(){
        $(document.activeElement).blur()
    }

totaskin avatar Mar 29 '15 10:03 totaskin

Yea thanks @RobertLowe. Your solution worked better than trying to target the right element via a class selector.

jambox avatar May 04 '15 21:05 jambox

@lijunle Where do i add the code you have suggested ? Thanks.

aravindsanker avatar Jun 13 '15 11:06 aravindsanker

@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.

lijunle avatar Jun 13 '15 12:06 lijunle

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();
}

davidchoo12 avatar Nov 25 '15 18:11 davidchoo12

@RobertLowe Thank you so much, best solution in the thread.

ShaheensWeb avatar Dec 11 '15 19:12 ShaheensWeb

Why isn't this documented?

benpolinsky avatar Feb 01 '16 19:02 benpolinsky

@jpfortier it's working, and only it, but only with first input. With second already not

sinneren avatar Apr 21 '16 12:04 sinneren

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();
    }
});

waheed1987 avatar May 02 '16 11:05 waheed1987

onClose: function(){
  $(document.activeElement).blur();
}

Works for me too. It appears to be a bug : should release the focus when the dialog is closing.

jtouzy avatar Sep 06 '16 21:09 jtouzy

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 avatar Nov 18 '16 21:11 adrianmihalko

@adrianmihalko I have same problem

dellert avatar Jan 30 '17 12:01 dellert