Search code examples
angulartypescriptangular-reactive-formsng-bootstrap

How can I show a custom text in the input, when using ngbDatepicker?


I'm using ngbDatepicker in my reactiveForm, structured like this in my reservation.component.ts:

  myReactiveForm : MyReactiveForm = this.formBuilder.nonNullable.group({
    // SOME OTHER FORM GROUPS BEFORE...
    reservationDetails: this.formBuilder.nonNullable.group({
      guests: this.formBuilder.nonNullable.control(1, [ Validators.required, Validators.min(1) ]),
      reservationDate: this.formBuilder.nonNullable.control('', [ Validators.required ]),
      reservationTime: this.formBuilder.nonNullable.control('', [ Validators.required ]),
      notes: this.formBuilder.nonNullable.control('')
    })
  });

In my reservation.component.html, I show my datepicker with these lines of code:

<input 
  type="text" 
  ngbDatepicker 
  placeholder="{{ 'Pick a date' | translate }}"
  [minDate]="formDatepickerDate"
  #datepicker="ngbDatepicker" 
  (click)="datepicker.toggle()" 
  formControlName="reservationDate"
  readonly
>

Everything works fine, when I select a date from the datepicker, the input shows the selected date like this:

enter image description here

What I'm trying to do, is to format the date inside the datepicker. Instead of showing 2023-04-19, I'd like to show a string formatted like this --> "Wednesday, 19 April 2023". How can I achieve that?


Solution

  • To format the date inside the ngbDatepicker, you can use a custom NgbDateParserFormatter provider that implements the NgbDateParserFormatter interface. This interface provides methods to parse a string into a date and to format a date into a string.

    Here's an example of how to create a custom date formatter that formats dates in the format "Wednesday, 19 April 2023":

    import { Injectable } from '@angular/core';
    import { NgbDateParserFormatter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
    import { formatDate } from '@angular/common';
    
    @Injectable()
    export class CustomDateFormatter extends NgbDateParserFormatter {
      readonly DATE_FORMAT = 'EEEE, d MMMM y';
    
      parse(value: string): NgbDateStruct | null {
        // Not implemented for this example
        return null;
      }
    
      format(date: NgbDateStruct): string {
        if (!date) {
          return '';
        }
        return formatDate(new Date(date.year, date.month - 1, date.day), this.DATE_FORMAT, 'en-US');
      }
    }
    

    Now use it in your component like this:

    import { Component, OnInit } from '@angular/core';
    import { FormBuilder, Validators } from '@angular/forms';
    import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';
    import { CustomDateFormatter } from './custom-date-formatter';
    
    @Component({
      ...
      providers: [
        { provide: NgbDateParserFormatter, useClass: CustomDateFormatter }
      ]
    })
    export class YourComponent implements OnInit {
      // ...
      constructor(
        private formBuilder: FormBuilder
      ) { }
      // ...
    }
    

    Hope it helps! :)