I'm using reactive forms in my Angular 2 webapp and I'm having troubles assigning the date to ngbDatepicker (ngbootstrap 1 alpha 6). My object has a date object such as:
var myObject = {date: new Date(1, 9, 2016)};
and in my reactive form, it is configured as follow:
input.form-control(name='date', ngbDatepicker, #date="ngbDatepicker", placeholder='jj.mm.aaaa', formControlName='date', type="text")
and I patch the form like this:
this.form.patchValue({myObject: myObject});
The problem is that ngbDatepicker
take the date with the following structure:
{day: DD, month: MM, year: YYYY}
I have found a workaround that does:
this.form.controls.myObject.controls.date.valueChanges
.map((value) => {
if(value) {
if (typeof value.getMonth === 'function') {
this.form.controls.myObject.patchValue({
date: {
day: value.getUTCDay(),
month: value.getUTCMonth(),
year: value.getUTCFullYear()
}
});
}
}
return value;
})
.subscribe((value) => {
});
And everything works as expected (the date gets updated whenever form gets patched) but it is way too verbose (18 lines of code) and my form has a dozen of dates!
So my question is can I achieve the same result with a much shorter solution?
There two important class to manage ngbDate. one it's for formatting the date: a DateParserFormater, and another to change the value you get/send from/to a ngb-datepicker: a DateAdapter. So, you can create a customDateAdapter and a customDateParserFormatter. But, don't worry about the names.
#Add Datepicker Bootstrap Component in ApplicationIn the component class, import NgbDatepicker , NgbCalendar and NgbDateStruct to use their methods to set, get or format Datepicker value. The ngbDatepicker is used as an attribute in an Input control with an icon button to toggle Datepicker popup.
I don't know if it might help you
ng-bootstrap: 1
angular: 2
bootstrap: 4
ngOnInit() {
const now = new Date();
const since = moment().subtract(14,'d').toDate();
this.model.fechaHasta = {year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate()};
this.model.fechaDesde = {year: since.getFullYear(), month: since.getMonth() + 1, day: since.getDate()};
}
HTML
<div class="input-group">
<input class="form-control" placeholder="yyyy-mm-dd"
name="fechaHasta" [(ngModel)]="model.fechaHasta" ngbDatepicker #d10="ngbDatepicker">
<div class="input-group-addon" (click)="d10.toggle()">
<img src="../../shared/img/calendar-icon.png" style="width: 1.2rem; height: 1rem; cursor: pointer;"/>
</div>
</div>
I've just found your question while looking for a solution to the same problem. What I've done is leveraged momentjs, which is a date/time manipulation library (http://momentjs.com), and I'm manipulating dates coming from the database via momentjs before patching them into the form and initializing the ngbDatepicker.
this.START_DATE
is the value from the database, and it comes as a string START_DATE : "2017-08-27"
var _savedStartDate = moment(this.START_DATE).toObject();
var _savedStartDateObject = {day:0,month:0,year:0};
_savedStartDateObject.day = _savedStartDate.date;
_savedStartDateObject.month = _savedStartDate.months;
_savedStartDateObject.year = _savedStartDate.years;
this.form.patchValue({
START_DATE: _savedStartDateObject
})
This is more verbose than it needs to be, you could create the object and assign the attributes in one line, but this is much more readable.
Basically create a moment date object by passing the date as a string into the moment() function, and then call the toObject function on the result, which gives you an object like this: {years: 2017, months: 7, date: 27, hours: 0, minutes: 0, seconds: 0, milliseconds: 0}
Then create an empty object in the format ngbDatepicker
wants to see it {day:0,month:0,year:0}
, and map the appropriate attributes from the moment object into the ngbDatepicker
object, then call this.formpatchValue
and pass in the newly created object with the appropriate format.
The relevant momentjs docs are here http://momentjs.com/docs/#/displaying/as-object/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With