'Conditionally show input field - Angular Reactive Forms

Problem: When trying to show input field for specific index of form list, both areas show instead of one at a time.

Clarification: I currently have a form that is implanted in an *ngFor. When looping each item in my list, I am able to disable certain form fields. However, there is a specific form field that I would like to hide/show for that specific index of the form based on that specific index's input values.

I would like to show this "test Reason" input if the current entered time of the item being logged is after the assigned "late" time.

I get the time entered from the ngxMatDatePicker

When I go to try to show only that specific index's "testReason" input, it enables the showing of all "testReason" inputs

TEMPLATE

 <div *ngIf="testList.length > 0">
    <div
      class="row"
      *ngFor="
        let test of testList;
        index as i;
        first as isFirst;
        last as isLast
      "
      [formGroup]="testFormGroup"
    >
      <!-- TEST -->
      <div class="row py-2 ms-3">
        <div class="col-2">
          <div class="row title">
            DUMMY DATA ORIGIN
          </div>
          <div class="row">{{ test.city  }}</div>
        </div>
        <div class="col-2">
          <div class="row title">
            {{
              isFirst
                ? "Pick Up Early"
                : isLast
                ? "Delivery Early"
                : "Intermediate Early"
            }}
          </div>
          <div class="row">
            {{ test.apptEarly | date: "MM/dd/yy HH:mm" }}
          </div>
        </div>
        <div class="col-2">
          <div class="row title">
            {{
              isFirst
                ? "Pick Up Late"
                : isLast
                ? "Delivery Late"
                : "Intermediate Late"
            }}
          </div>
          <div class="row">
            {{ test.apptLate | date: "MM/dd/yy HH:mm" }}
          </div>
        </div>
        <div class="col-2 float-left">
          <div class="row title anti-spacer">Arrived</div>
          <div
            class="row gx-1"
            *ngIf="!test.loggedArrival"
            style="margin-left: -10px"
          >
            <mat-form-field appearance="outline">
              <input
                matInput
                [ngxMatDatetimePicker]="picker"
                [formControl]="
                  testFormArr.controls[i]['controls']['arrivalTime']
                "
                [disabled]="
                  (i > 0 &&
                    testList[i - 1].loggedDepartureTime == null) ||
                  test.loggedArrival
                "
                class="form-field"
                (dateChange)="
                  testFieldInserted('arrivalTime', $event.value)
                "
              />
              <mat-datepicker-toggle
                matSuffix
                [for]="picker"
                [disabled]="
                  (i > 0 &&
                    testList[i - 1].loggedDeparture == null) ||
                  test.loggedArrival
                "
              >
                <mat-icon matDatepickerToggleIcon class="picker-icon">
                  calendar_today
                </mat-icon>
              </mat-datepicker-toggle>
              <ngx-mat-datetime-picker
                #picker
                [showSeconds]="false"
                [enableMeridian]
              >
                <ng-template>
                  <span>OK</span>
                </ng-template>
              </ngx-mat-datetime-picker>
            </mat-form-field>
          </div>
          <div class="row spacer" *ngIf="test.loggedArrival">
            {{ test.loggedArrival | date: "MM/dd/YY HH:mm" }}
          </div>
        </div>
        <div class="col-2">
          <div class="row title anti-spacer">Departure</div>
          <div
            class="row gx-1"
            *ngIf="!test.loggedDeparture"
            style="margin-left: -10px"
          >
            <mat-form-field appearance="outline">
              <input
                matInput
                [ngxMatDatetimePicker]="picker"
                [disabled]="
                  test.loggedDeparture ||
                  !test.loggedArrival
                "
                class="form-field"
                [formControl]="
                  testFormArr.controls[i]['controls']['departureTime']
                "
                (dateChange)="
                  testFieldInserted('departureTime', $event.value)
                "
              />
              <mat-datepicker-toggle
                matSuffix
                [for]="picker"
                [disabled]="
                  test.loggedDeparture ||
                  !test.loggedArrival
                "
              >
                <mat-icon matDatepickerToggleIcon class="picker-icon"
                  >calendar_today</mat-icon
                >
              </mat-datepicker-toggle>
              <ngx-mat-datetime-picker
                #picker
                [showSeconds]="false"
                [enableMeridian]
              >
                <ng-template>
                  <span>OK</span>
                </ng-template>
              </ngx-mat-datetime-picker>
            </mat-form-field>
          </div>
          <div class="row spacer" *ngIf="test.loggedDeparture">
            {{ test.loggedDeparture | date: "MM/dd/YY HH:mm" }}
          </div>
        </div>
        <div class="col-2">
          <div class="row title anti-spacer">Reason</div>
          <div class="row gx-1" style="margin-left: -10px">
            <mat-form-field appearance="outline">
              <input
                matInput
                class="form-field"
                placeholder="Choose Reason"
                [matAutocomplete]="testReason"
                [formControl]="
                  testFormArr.controls[i]['controls']['testReason']
                "
              />
              <mat-autocomplete #testReason="matAutocomplete">
                <mat-option
                  *ngFor="let test of testReason"
                  [value]="test.value"
                >
                  {{ test.name }}
                </mat-option>
              </mat-autocomplete>
            </mat-form-field>
          </div>
        </div>
      </div>
    </div>
  </div>

TS


    return this.formBuilder.group({

      arrivalTime: [''],

      departureTime: [''],

      testReason: [''],

    });

  }

  addFormControlItem() {

    this.testFormArr = this.testFormGroup.get('testFormArr') as FormArray;

    this.testFormArr.push(this.createFormControlField());

  }

  testFieldInserted(field: string, time: any): void {

    this.testCycleObject = {

      [field]: `${moment(test).format('YYYY-MM-DDTHH:mm:ss')}`,

    };

  }

  setTest() {

    this.testList = [];

    this.test.testTests.forEach((test, index) => {

      let testObject: TestObject = {

        city: test.city,

        state: test.state,

        apptEarly: test.appointmentEarly,

        apptLate: test.appointmentLate,

        arrivalTime:

          this.test.trackingTests &&

          this.test.trackingTests.length > 0 &&

          this.test.trackingTests.length > index

            ? this.test.trackingTests[index].arrivalTime

            : null,

        departureTime:

          this.test.trackingTests &&

          this.test.trackingTests.length > 0 &&

          this.test.trackingTests.length > index

            ? this.test.trackingTests[index].departureTime

            : null,

        actualArrivalTime: null,

        actualDepartureTime: null,

        lateReason: '',

      };

      this.testList.push(testObject);

      this.addFormControlItem();

    });

    this.validateButtons();

  }

  testReason = [

    {

      name: 'TEST REASON ONE',

      value: 'TEST REASON ONE',

    },

    {

      name: 'TEST REASON TWO',

      value: 'TEST REASON TWO',

    },

  ]; ```


Solution 1:[1]

You could try using *ngIf with your test[index] that you want to conditionally render.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Agent Smith