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

bug(datepicker): regression with #3371 #3483

Closed
terencehonles opened this issue Nov 22, 2019 · 3 comments · Fixed by #3539
Closed

bug(datepicker): regression with #3371 #3483

terencehonles opened this issue Nov 22, 2019 · 3 comments · Fixed by #3539

Comments

@terencehonles
Copy link
Contributor

Bug description:

I'm opening this as it's own issue so it doesn't get lost. The issue #3317 and its associated PR #3371 caused what probably should be considered a regression. The scenario is with the following code:

<input #picker ngbDatepicker (focus)="picker.open()" />

you will never be able to close the datepicker because closing it will call focus which will then in turn open it.

This was also reported by @chumbalum and @zm3d3ni who provided the stackblitz https://stackblitz.com/edit/angular-phaczz as a more complete example of what should continue to work.

There are some comments on #3317 and suggestions for a possible solution.

@maxokorokov
Copy link
Member

Thanks for opening the dedicated issue for this.

In this case I'm sorry for breaking your code, but the default behaviour should be refocusing previously focused element, so the focus won't get lost by default (other components like dropdown work this way in both bootstrap and ng-bootstrap). And we've decided to not rollback this change.

We just couldn't foresee all use cases of how people open datepicker. And we're not very fond of doing it on focus, because what's the point of having an <input> at the first place...

As a workaround I could suggest you doing this (quick, but not very beautiful):

https://stackblitz.com/edit/angular-vxjijx?file=src/app/app.component.html

<!-- Better create a `shouldStayClosed = false;` in the component, not the template though. Just for illustrative purposes -->
<input #d="ngbDatepicker"
    (click)="d.open()"
    (focus)="!d['_shouldStayClosed'] && d.open(); d['_shouldStayClosed'] = d.isOpen()"
>

But I agree that in 5.2.0 we should add something like [refocus]="false" to fix this in a better way. So I'll keep this open.

@benouat
Copy link
Member

benouat commented Dec 20, 2019

I would suggest a cleaner workaround than Max' one 😄

dontOpen = false;
  
closeDatepicker(datepicker) {
  this.dontOpen = true;
  datepicker.close();
  setTimeout(() => {
    this.dontOpen = false;
  }, 100); // <-- fine tune this
}
<input #datepicker="ngbDatepicker"
  class="form-control"
  formControlName="date"
  ngbDatepicker
  (click)="datepicker.open()"
  (focus)="!dontOpen && datepicker.open()"
  (dateSelect)="closeDatepicker()"
  (closed)="closeDatepicker();"
  placeholder="yyyy-mm-dd">

@maxokorokov
Copy link
Member

maxokorokov commented Dec 20, 2019

@benouat You probably missed the comment line in my example →

<!-- Better create a `shouldStayClosed = false;` in the component, not the template though. Just for illustrative purposes -->

You don't need any timeouts here, just the dontOpen = false will do instead of d['_shouldStayClosed']. So :

https://stackblitz.com/edit/angular-mgtynf?file=src/app/app.component.html

dontClose = false;
<input #d="ngbDatepicker"
    (click)="d.open()"
    (focus)="!dontClose && d.open(); dontClose = d.isOpen()"
>

maxokorokov added a commit to maxokorokov/ng-bootstrap that referenced this issue Jan 9, 2020
'restoreFocus' will define re-focusing strategy when closing the input datepicker

Fixes ng-bootstrap#3483
maxokorokov added a commit to maxokorokov/ng-bootstrap that referenced this issue Jan 9, 2020
'restoreFocus' will define re-focusing strategy when closing the input datepicker.

```ts
@input() restoreFocus: true | string | HTMLElement; // defaults to true
```

By default it re-focuses element focused at the moment of datepicker opening.
Otherwise accepts either selector or element reference.

Fixes ng-bootstrap#3483
maxokorokov added a commit to maxokorokov/ng-bootstrap that referenced this issue Jan 10, 2020
'restoreFocus' will define re-focusing strategy when closing the input datepicker.

```ts
@input() restoreFocus: true | string | HTMLElement; // defaults to true
```

By default it re-focuses element focused at the moment of datepicker opening.
Otherwise accepts either selector or element reference.

Fixes ng-bootstrap#3483
maxokorokov added a commit to maxokorokov/ng-bootstrap that referenced this issue Jan 10, 2020
'restoreFocus' will define re-focusing strategy when closing the input datepicker.

```ts
@input() restoreFocus: true | string | HTMLElement; // defaults to true
```

By default it re-focuses element focused at the moment of datepicker opening.
Otherwise accepts either selector or element reference.

Fixes ng-bootstrap#3483
maxokorokov added a commit to maxokorokov/ng-bootstrap that referenced this issue Jan 10, 2020
…t datepicker.

```ts
@input() restoreFocus: true | string | HTMLElement; // defaults to true
```

By default it re-focuses element focused at the moment of datepicker opening.
Otherwise accepts either selector or element reference.

Fixes ng-bootstrap#3483
maxokorokov added a commit that referenced this issue Jan 10, 2020
restoreFocus input will define re-focusing strategy when closing the input datepicker.

```
@input() restoreFocus: true | string | HTMLElement; // defaults to true
```

By default it re-focuses element focused at the moment of datepicker opening.
Otherwise accepts either selector or element reference.

Fixes #3483
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants