I am using PrimeNG Calendar control in an Angular Reactive Forms application. In my application I have a form with a calendar control inside a Primefaces dialog.
When an invalid date value is typed into the calendar control I programmatically update the value of the control to a predefined rollback date value when the dialog is closed so that when it is shown again the form is in a valid state.
However, I have found that updating the value of the calendar control programmatically does not consistently update the UI with the new value.
I am using a FormGroup and have tried both setValue and patchValue. I have also tried using setValue and patchValue on the calendar control explicitly and also the reset method of formGroup. The problem still occurs.
Just wondering if anybody can advise on where I am going wrong in the code?
I have created a plunker at http://plnkr.co/edit/xc4ygZ?p=info , to illustrate an example. The code for the angular component and template is included below....
import {
Component
} from '@angular/core';
import {
FormBuilder
} from '@angular/forms';
import {
FormGroup
} from '@angular/forms';
import {
OnInit
} from '@angular/core';
import {
Validators
} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: 'app/app.template.html'
})
export class AppComponent {
birthDate: Date;
form: FormGroup;
formErrors = {
'setdate': '',
};
validationMessages = {
'setdate': {
'required': 'Set date is required.',
'invalidDate': 'Invalid Date.'
},
};
constructor(private fb: FormBuilder) {
this.birthDate = new Date();
}
ngOnInit(): void {
this.buildForm();
}
onSubmit(): void {
}
setSetDate(): void {
let today = new Date();
this.form.patchValue({
setdate: today
});
}
private buildForm(): void {
this.form = this.fb.group({
setdate: [this.birthDate, [Validators.required]]
});
this.form.valueChanges
.subscribe(data => this.onValueChanged(data));
//this.onValueChanged();
}
private onValueChanged(data ? : any): void {
let _self = this;
if (!this.form) {
return;
}
const form = this.form;
console.log("onValueChanged()");
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + '\n';
}
}
}
}
}
<p> Enter a date that is invalid, e.g. edf. Then try clicking the button to programmatically reset the date</p>
<p> The UI for the calendar control does not consistently update with the new date. </p>
<form autocomplete="off" [formGroup]="form" novalidate (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="setdate" class="control-label col-xs-4">Set Date</label>
<div>
<p-calendar #theDate id="setdate" formControlName="setdate" showTime="true" hourFormat="24" dateFormat="dd-mm-yy" [showIcon]="true" placeholder="Set Date" required>
</p-calendar>
<p>SetDate Value :: {{ theDate.value }}</p>
<p>SetDate Valid :: {{ this.form.controls['setdate'].valid }}</p>
<p>SetDate Errors :: {{ this.form.controls['setdate'].errors | json }}</p>
</div>
<div *ngIf="formErrors.setdate" class="alert alert-danger">
{{ formErrors.setdate }}
</div>
</div>
<button type="button" class="btn" (click)="setSetDate()">Test SetDate</button>
</form>
I had two things that were causing Reactive Forms and PrimeNG to not behave together.
I was using this.myForm.reset()
which was wiping out necessary data on PrimeNG components.
Solution
I reset the values using this.myForm.patchValue({myFormControlName: 'my reset value'})
.
Of course you could use this.myForm.setValue()
if you prefer.
On my calendar I had done what Yaroslav Admin describes here. Essentially I wasn't passing a date object. I was passing a unix time stamp as number type.
Solution
Instead of:
const time = 1562162176;
this.form.controls.calendarField.setValue(time)
do this:
const time = new Date(1562162176);
this.form.controls.calendarField.setValue(time)
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