Is it correct to implement a custom NgbDateParserFormatter to change the format of the input value on NgbInputDatepicker?
Solution 1
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
Solution 2
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
Nelson Lopez Centeno
Updated on July 22, 2022Comments
-
Nelson Lopez Centeno almost 2 years
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 defaultNgbDateISOParserFormatter
.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") } } ] --- })
-
David over 7 yearsBe aware - moment expects to have zero indexed months. Your code fails on every day of december.
-
Nelson Lopez Centeno over 7 yearsThanks @David, I fixed the code. When I posted the code, NgbDateStruct was using zero indexed months too, but that changed later.
-
Mohan Ram about 7 years@Nelson I tried your approach. I have added providers in the core module of my application to change date format of my date picker component. Its not working. Help me out.
-
Nelson Lopez Centeno about 7 years@MohanRam Could you share your code?
-
HammerNL over 6 yearsNote that, in a more recent Angular 4 version, useFactory on providers no longer exists. Use: useValue: new NgbDateMomentParserFormatter("DD-MM-YYYY") instead
-
Alejandro about 4 yearsas of today, this still works with @HammerNL's fix. Thanks!
-
Gustavo Amaro almost 4 yearsYour update content worked perfectly for me! Thanks!
-
-
Daimz over 7 yearsI 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. -
murk003 about 7 years@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"); }
andproviders: [ { provide: NgbDateParserFormatter, useFactory: NgbDateMomentParserFormatterFactory }]
but that doesn't seem to apply the changes. -
sgotre almost 7 yearsDo not use a factory when using AOT Compiler. Try this example:gist.github.com/nrobinaubertin/61ff1c3db355c74f4e56f485b566ab22
-
HaneTV over 5 yearsAlthough 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 ?