How can you update ngModel in Angular and mark the form as dirty or invalid programmatically?

My form is connected to a model as shown below

In the component file:

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 dirty</div>
<div *ngIf="testForm.touched">testForm touched</div>

I am looking for a way to programmatically mark the form as touched or dirty. How can I achieve this?

Please note: Although in this example a button is used to update the model, it could also be updated through other means like a callback from an asynchronous web API request.

Answer №1

Solution:

//In this code snippet, we have the root app component in Angular.

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

Answer №2

Why not consider utilizing Reactive forms like 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 dirty</div>
<div *ngIf="testForm.touched">testForm touched</div>

You can use the markAsDirty() method within your function based on specific conditions.

updateMyTextModel(): void {
    this.myTextModel = "updated model value";
    if ( // some condition ) {
        this.testForm.markAsDirty();
    }
}

To mark individual form controls as dirty or touched, you can do the following:

this.testForm.get('myText').markAsDirty();
this.testForm.get('myText').markAsTouched();

Answer №3

Here is a suggested solution:

@ViewChild('exampleForm') exampleForm;


updateTextModel(): void {
    this.textModel = "new value for model";
    this.form.example.markAsDirty();
}

Answer №4

When utilizing the NgForm form reference in this manner -

@ViewChild('viewChildForm') public viewChildForm: NgForm;
and attempting to change the form programmatically in the .ts file:

  • To mark the form as invalid:

    this.viewChildForm.form.setErrors({ 'invalid': true });
    .

  • To mark the form as valid:

    this.viewChildForm.form.setErrors(null);

Answer №5

To iterate through all input fields within a form and set them as touched or dirty, you can use the following code:

onSubmit(formName)
{
    let inputArray = formName.form.controls;
    for(let key in inputArray)
    {
        inputArray[key].markAsTouched();
        inputArray[key].markAsDirty();
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The issue with NGX-Bootstrap/Angular Pagination arises when attempting to adjust the maxSize input while the screen view (width) is being altered

Currently, I am utilizing the Pagination component from Valor Software (click here to access). I am interested in adjusting the maxSize input dynamically based on changes in screen width. For reference, please see this example: Click to view example. It ...

How to access elements by their class name in Angular

Recently, I encountered a situation with this specific span element: <span *ngFor="let list of lists[0].question; let i = index" id="word{{ i }}" (click)="changestyle($event)" class="highlight"> {{ list}} < ...

Implementing method overrides in TypeScript class objects inherited from JavaScript function-based classes

I am facing a challenge with overriding an object method defined in a JavaScript (ES5) function-based class: var JSClass = function() { this.start = function() { console.log('JSClass.start()'); } } When I call the start() method, it pri ...

Having trouble resolving the npm ERR with @angular-devkit/[email protected]? Found the solution to fixing it by checking out @angular/[email protected] instead

When I try to update the local Angular CLI version, I keep encountering an error with this command: npm uninstall --save-dev angular-cli. (following instructions from this source) npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ER ...

Utilizing the adapter design pattern in Angular with TypeScript for enhancing a reactive form implementation

I've been struggling to understand how to implement the adapter pattern in Angular6. Despite reading numerous articles and tutorials, I still can't quite grasp the concept. Could someone provide some insights on this topic? Essentially, I have a ...

Incorporating the id attribute into the FormControl element or its parent in Angular 7

I'm attempting to assign an id attribute to the first invalid form control upon form submission using Angular reactive forms. Here is my current component code: onSubmit() { if (this.form.invalid) { this.scrollToError(); } else { ...

The flag will never turn true; it's stuck in the false position

Currently, I am in the process of developing a custom hook to store data on a server. To mimic the server call, I have implemented a simple setTimeout function that changes the value of the data creation flag to true after 2 seconds. I have a specific fun ...

It seems like the recent upgrade to yarn 2 has caused issues with typescript types, whereas the installation of the same project with yarn 1 was

Recently, I've been attempting to update a typescript monorepo to utilize yarn 2, but I've encountered an issue where typescript is struggling to recognize certain react props. This functionality was working fine in yarn 1.x, leading me to believ ...

The ngFor directive encounters issues when placed within a quotation mark or when used within a Bootstrap Tooltip Tag

.HTML File : I encountered an error saying, "Identifier 'mg' is not defined." However, {{mgr[0].value}} works <button type="button" class="btn btn-secondary" data-toggle="tooltip" data-placement="bottom" ...

What methods can be used to avoid getting distracted by input?

Is there a way to prevent the input field in angular-material2 from gaining focus when clicking on a visibility button? To see an example of how it works, visit: material.angular.io Image before pressing the button: https://i.stack.imgur.com/5SmKv.png ...

Perpetually launching "npm start" on the server

I have been attempting to deploy an angular2 test application on a server. It is functioning well on my local machine using the command NPM start as indicated in my package.json file: "start": "concurrent \"npm run tsc:w\" \"npm run lite&bs ...

Utilizing getters and setters with v-model in a class-based component: A step-by-step guide

Transitioning from an angular background to vuejs has been challenging for me as a newbie. I've encountered issues while trying to bind setter/getter in v-model for an input field. Interestingly, when I directly bind it to a variable, everything works ...

Steps to integrating an interface with several anonymous functions in typescript

I'm currently working on implementing the interface outlined below in typescript interface A{ (message: string, callback: CustomCallBackFunction): void; (message: string, meta: any, callback: CustomCallBackFunction): void; (message: string, ...m ...

Creating tests in JestJs for React components that utilize Context Provider and Hooks

As a newcomer to front-end development, I am currently working on authentication with Okta-React. To pass logged-in user information across multiple components, I'm utilizing React context with hooks. While this approach works well, I encountered an i ...

Using Ionic 4 and Angular 7 to make straightforward remote HTTP requests with Cross-Origin Resource

I'm still navigating my way through ionic and angular, trying to understand how to send a basic HTTP request to a remote server without dealing with CORS. My initial attempt involved the following code snippet: this.httpClient.get<MyObj>("/api" ...

"Encountered an error: Unable to interpret URL from (URL).vercel.app/api/getMessages" while deploying Next.js 13 using TypeScript on Vercel

Hello to all members of the StackOverflow Community: I am encountering an error message stating "TypeError: Failed to parse URL from next-chat-lenx51hr5-gregory-buffard.vercel.app/api/getMessages" while attempting to build my Next.js 13 application using T ...

Having trouble applying [formControl] to a set of radio buttons in Angular2

Currently, I am encountering an issue with a list of groups of radio buttons in Angular2. My objective is to bind the value of each group of radio buttons using [formControl]. However, when implementing this, the radio buttons seem to lose their normal mut ...

What is the best way to create an optional object parameter in Typescript?

I'm working on a function that looks like this: const func = (arg1: string, { objArg = true }:{ objArg: string }) => { // some code } Is it possible to make the second parameter (an object) optional? ...

Customizing the design of the datepicker in Angular and then passing the formatted date to a

I need to send a date to the node for storage, but I am receiving it in this format 2022-04-26T18:30:00.000Z. I want to change it to 26-04-2022 Angular HTML Code <mat-form-field color="accent" appearance="fill"> <mat-label&g ...

What is the process for setting the value of a TextField based on a Dropdown Selection?

I have a question regarding the code snippet below. I am wondering how to set the value of a specific TextField based on the selected item in a Dropdown component named ChildComponent. import * as React from "react"; import ChildComponent from './Ope ...