0

I have a ngbdatePicker shared component for popup and trying to use it in one of the components, but open/close (toggle) is not working.

I tried using NgbDatepicker and NgbInputDatepicker, but same issue. I'm trying to open/close the popup when pressing a button. Also if I use the "Range selection in a popup" example directly from ng-bootstrap, it works as expected. But the problem is from shared component (parent) to other components.

The error is:

ERROR TypeError: this.dateInputPicker.toggle is not a function
    at DatePickerComponent.toggle (date-picker.component.ts:58:24)

Code snippet:

Shared Component HTML:

<div class="icon-small" *ngIf="!simpleDatePicker">
    <form class="row row-cols-sm-auto">
        <div class="col-12">
            <div class="dp-hidden position-absolute">
                <div class="input-group">
                    <input
                        id="dp1"
                        name="datepicker"
                        class="form-control"
                        ngbDatepicker
                        #dp1
                        [autoClose]="'outside'"
                        (dateSelect)="onDateSelection($event)"
                        [displayMonths]="2"
                        outsideDays="hidden"
                        [startDate]="fromDate!"
                    />
                </div>
            </div>
        </div>
    </form>
</div>

Shared component ts:

@Component({
  selector: 'app-date-picker',
  templateUrl: './date-picker.component.html',
  styleUrls: ['./date-picker.component.css']
})

export class DatePickerComponent implements OnInit {

...
@ViewChild('dp1') dateInputPicker: NgbInputDatepicker;
...
...
toggle(event) {
  console.log(event.dp1); //logs as undefined
  this.dateInputPicker.toggle(); //Errors as this.dateInputPicker.toggle is not a function
  
}

Popup component HTML:

<form class="row row-cols-sm-auto">
    <div class="col-12">
        <div class="dp-hidden position-absolute">
            <div class="input-group">
                <app-date-picker
                    name="datepicker"
                    class="form-control"
                    ngbDatepicker
                    #dp1
                    [simpleDatePicker]="false"
                    [autoClose]="'outside'"
                    (dateSelect)="onDateSelection($event)"
                    [displayMonths]="2"
                    [dayTemplate]="t"
                    outsideDays="hidden"
                    [weekdays]="false"
                    [startDate]="fromDate!"
                    tabindex="-1"></app-date-picker>
                <ng-template #t let-date let-focused="focused">
                    <span
                        class="custom-day"
                        [class.focused]="focused"
                        [class.range]="isRange(date)"
                        [class.faded]="isHovered(date) || isInside(date)"
                        (mouseenter)="hoveredDate = date"
                        (mouseleave)="hoveredDate = null"
                    >
                        {{ date.day }}
                    </span>
                </ng-template>
            </div>
        </div>
        <div class="input-group">
            <input
                #dpFromDate
                class="form-control"
                placeholder="yyyy-mm-dd"
                name="dpFromDate"
                [value]="formatter.format(fromDate)"
                (input)="fromDate = validateInput(fromDate, dpFromDate.value)"
            />
            <button class="btn btn-outline-secondary bi bi-calendar3 (click)="dp1.toggle($event)" type="button"></button>
        </div>
    </div>
Harry
  • 546
  • 6
  • 22
  • 50

1 Answers1

0

this.dateInputPicker is an instance of ElementRef assigning the type as NgbInputDatepicker will not work.

  • Add ngbDatepicker directive to the input element (#dp1)
  • Assign the template ref as NgbInputDatepicker
  • When the toggle method is called, use the dp1 template ref to toggle the popup

Shared Component HTML:

<input
  id="dp1"
  name="datepicker"
  class="form-control"
  ngbDatepicker
  #dp1="ngbDatepicker"
  [autoClose]="'outside'"
  (dateSelect)="onDateSelection($event)"
  [displayMonths]="2"
  outsideDays="hidden"
  [startDate]="fromDate!"
/>

Shared component ts:

@ViewChild('dp1') dp1: NgbInputDatepicker;

toggle() {
  this.dp1.toggle();
}
Mr. Stash
  • 2,940
  • 3
  • 10
  • 24
  • Excellent. It works! 2 minor issues: 1) the popup used to allow to pick a range of dates, but now only able to pick a single date instead of range and 2) validateInput(fromDate, dpFromDate.value). dpFromDate is ngInputDatePicker (used to be input) and doesnt have ".value". Is there a way to convert ngInputDatePicker to string or pass nginputDatePicker and validate it correctly? Please advise. Thanks so much – Harry Dec 20 '22 at 20:43
  • Awesome!. Almost there. The only remaining issue is, when I pick a date, it does not set to the input text boxes (dpFromDate and dpToDate) and to the
     tags. I think the values (fromDate and toDate) are not passing through to the shared component methods. Can you please advise onthis. Thanks
    – Harry Dec 21 '22 at 14:33
  • 1
    I made some minor changes and fixed the remaining issues. Thanks so much Mr. Stash. I will mark your answer as correct. Thanks again – Harry Dec 21 '22 at 15:33
  • you can update the answer with your changes, if you want – Mr. Stash Dec 21 '22 at 15:35