Conditional formatting of Reactive Form Control based on control value

Issue

This is a question about formatting text based on formControl in an applications in which the formControls are built using FormBuilder and arrays of formControls.

It requires accessing the current value of a formControl and changing the format of another element based on that formControl value.

I have a page in an app that is an inventory tracking form built in Ionic/Angular/Reactive.

enter image description here

The content comes from a database subscription.

You can see in the form that when the Should Have is less than Actually Have the format of the item changes from red to green.

This format is set using *ngIf in the template file (See Arrows <——):

  <form [formGroup]="inventoryForm" (ngSubmit)="onSubmit()">
    <div formArrayName="ident">
      <ion-item *ngFor="let item of inventoryElements; let i = index;">
        <ion-grid>
          <ion-row>
            <ion-col *ngIf="item.current < item.par" style="color: red">
              <strong>{{item.name}}</strong></ion-col           <----------
            >
            <ion-col *ngIf="item.current >= item.par" style="color: green"
              ><strong>{{item.name}}</strong></ion-col          <----------
            >
            <ion-col>{{item.par}} {{item.units}}</ion-col>
            <ion-col>
              <input size="1"
                     style="text-align: right;"
                     id="ident-{{ i }}"
                     type="text"
                     [formControlName]="i" />
              {{item.units}}
            </ion-col>
          </ion-row>
        </ion-grid>
      </ion-item>
    </div>
  </form>

(Note: I should probably update the two *ngIfs to an *ngIf-else-template, but that’s not the question here.)

Of course, the color is set when the form is loaded. If a user updates the Actually Have the color does not change. Making the color change as the formControl value changes is the question here.

The form control array is built in ngOnInit():

  ngOnInit() {
    this.inventoryCollection = this.afs.collection('inventory', (ref) => {
      this.query = ref;
      this.query = this.query.orderBy('category');
      return this.query;
    });

    this.inventoryInfo = this.inventoryCollection.snapshotChanges();

    this.inventoryInfo.subscribe((actionArray) => {

      // this map takes the firestore document name and makes it the ID
      this.inventoryElements = actionArray.map((item) => ({
        id: item.payload.doc.id,
        ...item.payload.doc.data(),
        expanded: false,
      }));
      //======================= Here is where the control array is built ==================
      this.ident.clear();
      actionArray.forEach(item => {
        this.ident.push(this.fb.control(item.payload.doc.data().current));
      });
      //==========================================================
    });

  }

(Note: I’m sure that my clear-the array and rebuild it as the subscription emits new values is not efficient. Happy to have suggestions there, but that’s not the core question.)

What I have tried to do without success is to change the *ngIf() for the item colors using a formControl.get() function. But I cannot get the proper syntax. Here’s what I tried:

<ion-col *ngIf="inventoryForm.get('0').value < item.par" style="color: red">

The ‘0’ is there just to grab one value as I was troubleshooting. Obviously this would change as we iterate over the inventoryElements.

** THE QUESTION: What is the proper way to access the values of the controls in the formArray for the purpose of the comparison in the *ngIf()? **

Solution

@Eliseo had the correct answer. the concept was to bind the [style.color] for the text to a comparison. Take special note of the + prior to the parameter to make the string into a number that could be compared.

Answered By – Paul Mullen

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published