Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date Picker not unfocusing correctly #770

Closed
isaachinman opened this issue Sep 22, 2015 · 9 comments
Closed

Date Picker not unfocusing correctly #770

isaachinman opened this issue Sep 22, 2015 · 9 comments

Comments

@isaachinman
Copy link

Hi there, there's a major issue with your implementation of pickadate. It does not unfocus correctly. Go to your own docs, open the Date Picker by clicking, click outside of the form (or click 'Close) to close the form. Now open a new tab, to go it, and come back to the original tab. The Date Picker will reopen itself.

This does not happen if you click on something else on the page after closing the Date Picker - so clearly it's not unfocusing correctly.

@isaachinman
Copy link
Author

Well for anyone looking for a fix, I came up with a quick CSS fix:

.picker__holder {
  pointer-events: none;
}
.picker__wrap {
  pointer-events: auto;
}

@max1011
Copy link

max1011 commented Oct 4, 2015

@isaachinman i came up with a working solution, i have the code u need to add, of course it's all written by me so it took a few hours to figure this thing out, it's a hack to make it work, i didn't actually change their code, i am sorry i didn't explain this code enough with comments , but give it a try , this worked for me, this is the codepen

$(function() {
  // change this to your own
  var $datePicker = $('.datepicker')
  var $input = $datePicker.pickadate()

  // Use the picker object directly.
  var picker = $input.pickadate('picker');
  var times = 0;
  var prevActiveElement;
  var original = $datePicker.get(0);

  $(window).on("blur", function(e) {
    prevActiveElement = document.activeElement.classList.contains('picker__holder') ? original : null;
  }).on("focus", function(e) {
    var theOrg = document.activeElement.classList.contains('picker__holder') ? original : null;
    console.log();
    if (theOrg == prevActiveElement && times > 0 && picker.get('open') == false) {
      // force close ASAP
      requestAnimationFrame(function() {
        picker.close();
      });
    }
    times=1;
  });

  $('input').on('focus', function(e) {
    prevActiveElement = document.activeElement.classList.contains('picker__holder') ? original : null;
  })
  picker.on('close',function() {
    prevActiveElement = null;
  })
});

@nightire
Copy link

@max1011 I've tried very similar thing (in a ember component), but I'm not use a times to tracking, actually I'm not sure why you use a times? I tried with your implementation, but it fails at the first time tab switching. After remove the times tracking, all is well.

@max1011
Copy link

max1011 commented Oct 23, 2015

@nightire it was for debugging initially but i didn't remove after i was done cause it will not harm anything, but if it causes a problem for you then remove it

@tomsseisums
Copy link

I went with a basic blur solution.

If you do not care about Tab support, you can simply add an onClose handler for corresponding picker where you blur the $holder (input):

$('input.datepicker').pickadate({
    onClose : function()
    {
        this.$holder.blur();
    }
});

Though, if you do care about Tab, then you can store blurrable elements and blur them only if the window is blurred:

var $blurWithWindow = $();

$(window).on('blur', function()
{
    $blurWithWindow.blur();
});

$('input.datepicker').pickadate({
    onStart : function()
    {
        $blurWithWindow = $blurWithWindow.add(this.$holder);
    }
});

While the other solution will break Tab support after the window has been changed, it still was sufficent fix for me.


And a little derivative from the solution provided by @max1011.

Again, utilizing the onStart function to provide contextual, multipurpose, dynamic use.

// Introduce global variables to store references to.
// We use an empty jQuery element here for consistency, 
// so that even if it is empty, jQuery methods do not fail 
// due to null variable.
var $lastFocusedPickerElement = $();
var lastFocusedPicker = null;

// Bind blur function to window.
$(window).on({
    focus : function()
    {
        if ($lastFocusedPickerElement.is(document.activeElement) 
            && lastFocusedPicker.get('open') == false)
        {
            // A setTimeout with no delay will be put at the end of JS task queue:
            // http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful#comment14183689_779785
            setTimeout(function()
            {
                lastFocusedPicker.close();
            });
        }
    }
});

// The picker itself.
$('input.timepicker').pickatime(
{
    onStart : function()
    {
        var picker = this;

        this.$holder.on('focus', function(e)
        {
            $lastFocusedPickerElement = $(this);
            lastFocusedPicker = picker;
        });
    }
});

@imaia
Copy link

imaia commented Nov 27, 2015

Hey isaachinman, your fix seems to work here. Thanks!

@ShaheensWeb
Copy link

isaachinman, thanks a lot elegant solution.

@sebastiansulinski
Copy link

Thanks @isaachinman - I thought it was just me going mad :)

@amsul
Copy link
Owner

amsul commented Sep 28, 2016

Let's please keep conversations where they've already been started (with a simple search): #160

@amsul amsul closed this as completed Sep 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants