56

I'm using the datepicker (ng-boostrap) in a popup and I would like to change the date format to dd-mm-yyyy.

It seems that it can be solved by implementing a new NgbDateParserFormatter to replace the default NgbDateISOParserFormatter.

But I was wondering if there is another way.

UPDATE:

A small implementation of NgbDateParserFormatter using Moment.js (tested with version 1.0.0-alpha.14 of ng-bootstrap):

import {NgbDateParserFormatter, NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
import * as moment from 'moment';

export class NgbDateMomentParserFormatter extends NgbDateParserFormatter {
    constructor(private momentFormat: string) {
        super();
    };
    format(date: NgbDateStruct): string {
        if (date === null) {
            return '';
        }
        let d = moment({ year: date.year, 
                         month: date.month - 1, 
                         date: date.day });
        return d.isValid() ? d.format(this.momentFormat) : '';
    }

    parse(value: string): NgbDateStruct {
        if (!value) {
            return null;
        }
        let d = moment(value, this.momentFormat);
        return d.isValid() ? { year: d.year(), 
                               month: d.month() + 1, 
                               day: d.date() } : null;
    }
}

And in a module, you include the provider using a factory to indicate the date format as a parameter:

---

@NgModule({

  ---

  providers: [
    { 
      provide: NgbDateParserFormatter, 
      useFactory: () => { return new NgbDateMomentParserFormatter("DD-MM-YYYY") } 
    }
  ]

  ---

})
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129

2 Answers2

23

As of today implementing a custom NgbDateParserFormatter is the best way to go. So yes, it is a correct way.

In the future we might have a more sophisticated implementation of the NgbDateParserFormatter where you will be able to just pass a desired format (ex. yyyy-MM-dd). Adding this feature will depend on user's interest.

You might also check some more background info in https://github.com/ng-bootstrap/ng-bootstrap/issues/754#issuecomment-247767027

pkozlowski.opensource
  • 117,202
  • 60
  • 326
  • 286
  • I am also wondering how I can change the formate on the dates, would it be possible to add a simple example of how to implement the `NgbDateParserFormatter` without moment.js I simply want to be able to reformat the date. – Daimz Nov 16 '16 at 00:23
  • 3
    @pkozlowski.opensource How should this answer be changed if we are using AOT compilation? I have tried `export function NgbDateMomentParserFormatterFactory() { return new NgbDateMomentParserFormatter("DD-MM-YYYY"); }` and `providers: [ { provide: NgbDateParserFormatter, useFactory: NgbDateMomentParserFormatterFactory }]` but that doesn't seem to apply the changes. – murk003 Jan 23 '17 at 14:50
  • 2
    Do not use a factory when using AOT Compiler. Try this example:https://gist.github.com/nrobinaubertin/61ff1c3db355c74f4e56f485b566ab22 – sgotre Jul 12 '17 at 20:01
  • Although it works on a clean project, it didn't work for my fairly big app (lots of modules importing each others...) with Ng5 and AoT compilation (JiT works but it's not an option for me). Is there an other way to do that ? – HaneTV Sep 06 '18 at 07:17
1

Create custom parser formatter.

import { NgbDateParserFormatter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
import { Injectable } from '@angular/core';

@Injectable()
export class NgbDateCustomParserFormatter extends NgbDateParserFormatter {

  format(date: NgbDateStruct): string {
    return date ? `${isNumber(date.day) ? padNumber(date.day) : ''}-${isNumber(date.month) ? padNumber(date.month) : ''}-${date.year}` : '';
  }
}

Set the provider for the custom parser formatter in the @NgModule.

providers: [
    {provide: NgbDateParserFormatter, useClass: NgbDateCustomParserFormatter}
]

As described in the api

Asif vora
  • 3,163
  • 3
  • 15
  • 31