I have a form and an underlying model like this
From component
myTextModel: string;
updateMyTextModel(): void {
this.myTextModel = "updated model value";
//todo- set form dirty (or invalid or touched) here
}
Html template
<form #testForm="ngForm" id="testForm">
<input type="text" id="myText" [(ngModel)]="myTextModel" name="myText" #myText="ngModel">
</form>
<button (click)="updateMyTextModel()">Update myTextModel</button>
<div *ngIf="testForm.dirty">testForm diry</div>
<div *ngIf="testForm.touched">testForm touched</div>
How do I set the form touched or dirty from code?
Note: In this example i use a button to trigger the model change, but i also might update the model in other ways, such as in a callback from an web api async request.
You should use the markAsDirty method, like this: control. markAsDirty(); This will also mark all direct ancestors as dirty to maintain the model.
If we use two way binding syntax for ngModel the value will be updated. So the default (ngModelChange) function will update the value of ngModel property. i.e., user.Name . And the second (ngModelChange) will be triggered printing the user name value in the console.
When the user changes the value in the watched field, the control is marked as "dirty" When the user blurs the form control element, the control is marked as "touched"
Solution:
//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { Component, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<form #testForm="ngForm" id="testForm">
<input type="text" id="myText" [(ngModel)]="myTextModel" name="myText" #myText="ngModel">
</form>
<button (click)="updateMyTextModel()">Update myTextModel</button>
<div *ngIf="testForm.dirty">testForm diry</div>
<div *ngIf="testForm.touched">testForm touched</div>
`,
})
export class App {
@ViewChild('testForm') test: any;
updateMyTextModel(){
this.test.control.markAsTouched();
this.test.control.markAsDirty();
}
constructor() {
console.log(this.test);
}
}
@NgModule({
imports: [ BrowserModule,FormsModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
Plunkr working:
https://plnkr.co/edit/YthHCEp6iTfGPVcNr0JF?p=preview
Why not use Reactive forms (FormGroup
),
let testForm = new FormGroup({
myText: new FormControl('initial value')
})
<form [formGroup]="testForm">
<input type="text" formControlName="myText">
</form>
<button (click)="updateMyTextModel()">Update myTextModel</button>
<div *ngIf="testForm.dirty">testForm diry</div>
<div *ngIf="testForm.touched">testForm touched</div>
In your function, you can use markAsDirty()
based on whatever condition you want.
updateMyTextModel(): void {
this.myTextModel = "updated model value";
if ( // some condition ) {
this.testForm.markAsDirty();
}
}
To set individual form controls as dirty/touched, you can use
this.testForm.get('myText').markAsDirty();
this.testForm.get('myText').markAsTouched();
This should work:
@ViewChild('testForm') testForm;
updateMyTextModel(): void {
this.myTextModel = "updated model value";
this.myForm.form.markAsDirty();
}
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