Is it correct to implement a custom NgbDateParserFormatter to change the format of the input value on NgbInputDatepicker?

AngularMomentjsNg Bootstrap

Angular Problem Overview


I'm using the datepicker ([ng-boostrap][1]) 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") } 
	}
  ]
  
  ---
  
})

[1]: https://ng-bootstrap.github.io "ng-bootstrap"

Angular Solutions


Solution 1 - Angular

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 - Angular

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNelson Lopez CentenoView Question on Stackoverflow
Solution 1 - Angularpkozlowski.opensourceView Answer on Stackoverflow
Solution 2 - AngularAsif voraView Answer on Stackoverflow