Currently, I am working on customizing the appearance of dates in a form using Angular-Bootstrap's datepicker with NgbDateParserFormatter. The details can be found at here.
My goal is to display the date in the format of year-month-day in the form field and present it as day/month/year. To achieve this, I have implemented the following code in the component:
<...>
@Injectable()
export class CustomAdapter extends NgbDateAdapter<string> {
readonly DELIMITER = '-';
fromModel(value: string | null): NgbDateStruct | null {
console.log('fromModel start', value);
if (value) {
let date = value.split(this.DELIMITER);
return {
day: parseInt(date[0], 10),
month: parseInt(date[1], 10),
year: parseInt(date[2], 10)
};
}
return null;
}
toModel(date: NgbDateStruct | null): string | null {
console.log('toModel start', date);
let res: string = date ?
date.year + this.DELIMITER + (date.month + '').padStart(2, "0") + this.DELIMITER + (date.day + '').padStart(2, "0")
: null;
console.log('toModel end', res);
return res;
}
}
@Injectable()
export class CustomDateParserFormatter extends NgbDateParserFormatter {
readonly DELIMITER = '/';
parse(value: string): NgbDateStruct | null {
console.log('parser start', value);
if (value) {
let date = value.split(this.DELIMITER);
console.log('parser end', date);
return {
day: parseInt(date[0], 10),
month: parseInt(date[1], 10),
year: parseInt(date[2], 10)
};
}
return null;
}
format(date: NgbDateStruct | null): string {
console.log('formatter start', date);
let res: string = date ?
(date.day + '').padStart(2, "0") + this.DELIMITER + (date.month + '').padStart(2, "0") + this.DELIMITER + date.year
: null;
console.log('formatter end', res);
return res;
}
}
@Component({
<...>
providers: [
{ provide: NgbDateAdapter, useClass: CustomAdapter },
{ provide: NgbDateParserFormatter, useClass: CustomDateParserFormatter }
]
})
export class MyComponent implements OnInit {
myForm: FormGroup;
<...>
dpModel: any;
constructor(
<...>
private ngbCalendar: NgbCalendar,
private dateAdapter: NgbDateAdapter<string>
) {
this.myForm = this.formBuilder.group({
<...>
date: [''],
<...>
});
}
For template implementation:
<div class="form-group">
<label for="data" class="col-form-label">Date:</label>
<div class="input-group">
<input class="form-control" placeholder="dd/mm/yyyy"
name="data" [(ngModel)]="dpModel"
ngbDatepicker #d="ngbDatepicker" formControlName="data">
<div class="input-group-append">
<button class="btn btn-outline-secondary fa fa-calendar-alt" (click)="d.toggle()"></button>
</div>
</div>
</div>
After clicking on a date within the datepicker, these are the debug outputs from the code included:
toModel start NgbDate {year: 2020, month: 6, day: 18}
toModel end 2020-06-18
fromModel start 2020-06-18
formatter start null
formatter end null
toModel start null
toModel end null
fromModel start null
fromModel start 2020-06-18
In analyzing the output, there seems to be an issue where the component passes null to the formatter. Additionally, after selecting a date, a red line appears beneath the datepicker. I have experimented with different approaches like using myform.date instead of dpModel without success.
I am currently utilizing Angular 8 for this project.