skip to Main Content

I have a screen where the input fields gets populated dynamically based on the API response. Each input field has a set of buttons associated with it. I want to show the buttons only when the field is dirty.

Below is a screenshot of the form –

form

I’m using simple ngModel to view & change the values. As the fieds doesn’t have any complex validations I’m not looking to use reactive form approach. When a user types on a field it’s corresponding button set should appear. On click of either the button the field should again get marked as pristine.

Below is my code of populating the template –

<h5 class="mb-4">Report Configuration</h5>
<div class="form-group row" *ngFor="let config of reportConfig">
  <label class="col-sm-12 col-md-4 col-form-label">{{config.title}} <span
      class="text-danger">*</span></label>
  <div class="col-sm-12 col-md-6 col-lg-6">
    <input type="text" [class.is-invalid]="false" [id]="config.propertyKey" [(ngModel)]="config.propertyValue" class="form-control" />
    <!-- On typing the field should be marked dirty & buttons should appear -->
  </div>
  <div class="col-sm-12 col-md-2 col-lg-2 pl-0">
    <mat-icon class="mr-2" (click)="should mark the field pristine">check_small</mat-icon>
    <mat-icon color="warn" (click)="should mark the field pristine">close_small</mat-icon>
  </div>
</div>

Is this can be achieved using ngModel or I need to use FormArray only to acheive this?

3

Answers


  1. Just try adding this in your ngModel in html

    (change)="checkDirty(value)"
    

    and this code in your ts file

    checkDirty(value) {
     if (value.dirty) {
      //your code on here
     }
    }
    

    As for explanation, the ngModel supports dirty property in it, and in each value change it will check if the input is dirty or not

    Login or Signup to reply.
  2. A ngModel Inherited from AbstractControlDirective, so you can access to his properties valid, touched or dirty. To do it use a template reference variable (the "#nameID" in the code below)

    <div *ngFor="let config of reportConfig">
        <input name="name" #nameID="ngModel" [(ngModel)]="config .name"/> 
        <button *ngIf="nameID.dirty">undo</button>
    
        <pre>
        {{nameID.control.dirty}} or {{nameID.dirty}}
        {{nameID.control.touched}} or {{nameID.touched}}
        {{nameID.control.valid}} or {{nameID.valid}}
        </pre>
    </div>
    

    Rememeber that a template reference variable has his own "scope" under a ngFor, so you have no problem to use it.

    Login or Signup to reply.
  3. You can set a template reference variable with the # mark:

    <input #variable="ngModel" type="text" [class.is-invalid]="false" [id]="config.propertyKey" [(ngModel)]="config.propertyValue" class="form-control" />
    

    after that, you can change the pristine property with markAsPristine() function call:

    <mat-icon class="mr-2" (click)="variable.markAsPristine()">check_small</mat-icon>
    

    Check this example in the official documentation: https://angular.io/guide/forms#show-and-hide-validation-error-messages

    Note: Reactive forms are not only for form validation, they give you access to the form values, while the template-driven form does not.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search