'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 |
