how to check in angular if ngmodel or forms are dirty or has input using form fields but not using formgroup.
I wanted to check if 5 of the inputs fields has value or dirty I want to show like a message but how do we check if for example 5 fields from DealFields or ngModel dealDispositionFormFields are dirty or has inputs ? Thank you .
#tscode
class DealDispositionFormFields {
dealName:string;
summary:string;
dealDispositionType: string;
terminationPayment:number;
effectiveDate: string;
totalBrokerCommission: number;
effectiveDateString: string;
dealId: number;
}
@Component({
selector: 'app-deal-idle-disposition',
templateUrl: './deal-idle-disposition.component.html',
styleUrls: ['./deal-idle-disposition.component.css']
})
export class DealIdleDispositionComponent implements OnInit {
ngOnInit(): void {
this.dealDispositionFormFields = new DealDispositionFormFields();
}
checkIf5FieldsAreDirty() {
...
}
#html code
<div id="deal-form-container" *ngIf="isEditing">
<div id="deal-form-wizard-top" *ngIf="dealDispositionFormFields.dealDispositionType === 'Buyout'">
<mat-form-field appearance="fill">
<mat-label>Deal Name</mat-label>
<input
matInput
[(ngModel)]="dealDispositionFormFields.dealName"
[required]="isExistingDeal">
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Summary of Deal</mat-label>
<textarea
matInput
class="resize-none"
[(ngModel)]="dealDispositionFormFields.summary"
[rows]="5"
[required]="isExistingDeal">
</textarea>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Termination Payment</mat-label>
<input
matInput
(keyup) = "computeBuyout()"
mask="separator.0"
thousandSeparator=","
[allowNegativeNumbers]="false"
[(ngModel)]="dealDispositionFormFields.terminationPayment"
[required]="isExistingDeal">
<span matPrefix *ngIf="dealDispositionFormFields.terminationPayment">$</span>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Effective Date</mat-label>
<input matInput
(dateChange)="computeBuyout()"
[matDatepicker]="effectiveDate"
[(ngModel)]="dealDispositionFormFields.effectiveDate"
[required]="isExistingDeal">
<mat-datepicker-toggle matSuffix [for]="effectiveDate"></mat-datepicker-toggle>
<mat-datepicker #effectiveDate></mat-datepicker>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Total Broker Commission</mat-label>
<input
matInput
(keyup) = "computeBuyout()"
mask="separator.0"
thousandSeparator=","
[allowNegativeNumbers]="false"
[(ngModel)]="dealDispositionFormFields.totalBrokerCommission"
[required]="isExistingDeal">
<span matPrefix *ngIf="dealDispositionFormFields.totalBrokerCommission">$</span>
</mat-form-field>
</div>
</div>
CodePudding user response:
You should use angular's Reactive Forms
. It has all the functionality you could want/need for form validation, plus it is easier to use.
Here is the official guide to using reactive forms: https://angular.io/guide/reactive-forms
in your component, you can create a FormGroup with controls like this:
@Component({
selector: 'app-deal-idle-disposition',
templateUrl: './deal-idle-disposition.component.html',
styleUrls: ['./deal-idle-disposition.component.css']
})
export MyComponent implements OnInit {
myForm: FormGroup;
constructor() {
// create the form
this.myForm = new FormGroup({
name: new FormControl('', [Validators.required]),
age: new FormControl(0, [Validators.required, Validators.min(18)])
});
}
}
According to the API docs (https://angular.io/api/forms/FormControl), the FormControl class extends AbstractControl
, which has the dirty
flag field/property. You can check a control's state like so:
const nameControl = this.myForm.get('name'); // or this.myForm.controls['name'];
if (nameControl.dirty) {
// ...
}
And you can listen to changes to the value of the control, similar to ngModel:
nameControl.valueChanges.subscribe((newValue) => {
// ...
});
Also you can listen to the status changes of the control, similar to ngModel:
nameControl.statusChanges.subscribe((newStatus) => {
// ...
});
Check out the official guide and the API docs; Angular does a great job on documenting their framework.
CodePudding user response:
ngModel has dirty property as mentioned in this answer
what you can do is use the change
or ngModelChange
events on each input
for example in your code it will be like
HTML
<mat-form-field appearance="fill">
<mat-label>Deal Name</mat-label>
<input
matInput
[(ngModel)]="dealDispositionFormFields.dealName"
[required]="isExistingDeal"
(change)="checkIfDirty()">
</mat-form-field>
TS
checkIfDirty() {
let countDirtyValues = 0;
Object.values(this.dealDispositionFormFields).map(value => {
if (value) {
countDirtyValues = 1;
}
});
if (countDirtyValues >= 5) {
// do something here
}
}
or if you want to find another solution. ngmodel
is actually an instance of formControl
, which in that case i would opt to create a reactive form as discribed in the angular documentation for formControl here that can also be done without the need of a formGroup