5

I'm using the PrimeNG components w/Angular 4 but I'm running into an issue - that is how do I display the calendar when my button is clicked?

See Plunker

@Component({
selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <button pButton type="button" (click)="openCalendar($event)" label="Open Calendar"></button>
      <br/><br/>
      <p-calendar #calendar [(ngModel)]="value"></p-calendar>
    </div>
  `,
})
export class App {
  name: string;
  value: Date;

  @ViewChild('calendar')
  calendar: any;

  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }

  openCalendar(event: any) {
    console.log(event);
  }
}

I have tried getting the template element reference using @ViewChild('calendar'). I have also tried applying focus using @ViewChild('calendar#inputfield') but that doesn't work.

Any idea how to click a button to programmatically open the calendar?

Antikhippe
  • 6,316
  • 2
  • 28
  • 43
chris
  • 51
  • 1
  • 5

3 Answers3

11

You can use showOverlay method on primeng calendar

openCalendar(event: any) {
  this.calendar.showOverlay(this.calendar.inputfieldViewChild.nativeElement);
  event.stopPropagation();
}

Modified Plunker

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • why does the calendar NOT show if i comment the stop propagation? – chris May 16 '17 at 21:27
  • 1
    Because click event is bubbling and calendar is subscribed to it https://github.com/primefaces/primeng/blob/v1.0.0-beta.20/components/calendar/calendar.ts#L260 – yurzui May 16 '17 at 21:35
  • where in the code is the calendar linked to the button ? because i have the same issue but with a label inside the calendar – Dany Y Jun 09 '17 at 06:51
  • @DanyY The Calender HTML Element is linked to the code via the `@ViewChild(...)` annotation and the corresponding name given in HTML (`#calendar`). The button calls `openCalendar(event: any)` function which has access to the calender via the ViewChild (`this.calendar`). – mentalo Feb 06 '19 at 10:53
4

Version 13 update, ivy means that calling subroutines will not update the component state, you have to force the ivy update.

I needed the ability to open on create so I added a variable in my calendar wrapper component. In my case there was a delay in creating the calendar so I had to put a pause in there...


  @Input()
  open = false;

  ngOnInit() {
    setTimeout(() => {
      if (this.open) {
        this.calendar.showOverlay();
        this.calendar.cd.detectChanges();
      }
    }, 10);
  }

  showDate() {
    if (!this.calendar.overlayVisible) {
      this.calendar.showOverlay();
      this.calendar.cd.detectChanges();
    }
  }
KenF
  • 544
  • 4
  • 14
0

The below code will work with the latest version of primeng (At the time this is posted)

In an HTML template

       <button pButton type="button" (click)="openCalendar($event)" label="Open Calendar"></button>
       <p-calendar
          #calendar
          [(ngModel)]="selectedDate"
          [readonlyInput]="true"
          (onSelect)="onSelectCal()"
          (onClose)="isEdit = false"
          appendTo="body"
        ></p-calendar>

In a .ts Controller

   import { Calendar } from "primeng/primeng";

   @ViewChild("calendar", { static: false }) private calendar: Calendar;

   openCalendar(event: any) {
     this.calendar.showOverlay();
     event.stopPropagation();
   }
Anup Bangale
  • 581
  • 7
  • 7