Datepicker Popup – Close when outside is clicked/touched

Bug description:

Datepicker popup does not close when an area outside of the popup/textbox is clicked/touched. Perhaps an optional true/false setting could be introduced to allow for this functionality.

Link to minimally-working plunker that reproduces the issue:

Datepicker popup on examples page

Version of Angular, ng-bootstrap, and Bootstrap:

Angular: 2.0.0 final

ng-bootstrap: 1.0.0-alpha.5

Bootstrap: 4.0.0-alpha.4

13 thoughts on “Datepicker Popup – Close when outside is clicked/touched

  1. What is the current status of this? As I see there is already commit, waiting to be included in release. Any reasons why is it not already included?

  2. @Asharma86 @pkozlowski-opensource
    #1623 is not the solution. Cause click other controllers in DOM should have the datePicker closed, too. Which #1623 ‘s solution does not, right?

    I changed it to

        && !this._eref.nativeElement.querySelector('.input-group-addon').contains( {
          let self = this;

    but this is ugly.
    since the feature is the most basic feature for a datePicker,
    I really appreciate the master branch with the feature coming soon.

  3. Hi all,
    I tried this work around and it works well
    (click)=”d.toggle();$event.stopPropagation();” (document:click)=”d.close()”

  4. I was facing the same issue, as solution i write following code that worked for me without any use case failure and error, the code is given below,

    @HostListener(‘document:click’, [‘$event’])
    closeDatepickerOnclick(event) {
    if ( !== null && !== ‘NGB-DATEPICKER’) {

    Description : listen to the document click event and check that targeted offset parent element is not null and as well as its tag name is not equals to ‘NGB-DATEPICKER’ because outside click of datepicker you always get different offsetParent name than ‘NGB-DATEPICKER’ .

    Hope this helps someone.

  5. Here’s kind of working solution (based on
    The thing is it’ll only work with one toggle button. I suppose it’s possible to implement a service to connect all directives so they can be aware of other bindings.

    import { ComponentRef, Directive, ElementRef, HostListener, Input } from '@angular/core';
    import { NgbDatepicker, NgbInputDatepicker } from '@ng-bootstrap/ng-bootstrap';
      selector: '[datepickerToggle]',
    export class DatepickerToggleDirective {
      // tslint:disable-next-line no-input-rename
      @Input('datepickerToggle') inputDatepicker: NgbInputDatepicker;
      @Input() closeDatepickerOnClick: boolean = true;
      constructor(private _elementRef: ElementRef) {}
      public toggle() {
        if (this.inputDatepicker.isOpen() && this.closeDatepickerOnClick) {
        } else {
      @HostListener('document:click', ['$event'])
      public closeOnOutsideEvent($event: MouseEvent) {
        if (this.inputDatepicker.isOpen()) {
          if (!this.isTargettingToggleButton($event) && this.shouldCloseOnOutsideEvent($event)) {
      private isTargettingToggleButton($event: MouseEvent): boolean {
        return this._elementRef.nativeElement.contains($;
      private shouldCloseOnOutsideEvent($event: MouseEvent): boolean {
        const inputDatepickerElRef: ElementRef = (this.inputDatepicker as any)._elRef;
        const datepickerCmpRef: ComponentRef<NgbDatepicker> = (this.inputDatepicker as any)._cRef;
        if (inputDatepickerElRef != null && datepickerCmpRef != null) {
          let popupClick = false;
          const inputClick = inputDatepickerElRef.nativeElement.contains($;
          if (this.inputDatepicker.isOpen() && datepickerCmpRef.location.nativeElement.contains($ {
            popupClick = true;
          return !inputClick && !popupClick;
        } else {
          return false;


    <div class="input-group">
      <div class="input-group-append">

    Add [closeDatepickerOnClick]="false" if you don’t want to close datepicker on second click.

  6. Probably not the best solution out there, but I managed to do it like this. I have several datepickers on that view, so I need to add the (document:click) on each one. @gpteamcs solution was almost perfect for me, but I could not use the arrows inside the datepicker without it closing, so I needed to refine it a bit more.

    <input style="background-color: white;" class="form-control" placeholder="YYYY-MM-DD" name="date" [(ngModel)]="date" ngbDatepicker #eToggle="ngbDatepicker" (click)="eToggle.toggle(); sToggle.close();$event.stopPropagation()" (document:click)="decideClosure($event, eToggle)" readonly>

    decideClosure(event, datepicker) { const path = => p.localName); if (!path.includes('ngb-datepicker')) { datepicker.close(); } }