Reputation: 83
I want to show or hide form field when mat-select is changed. The following code I used to do a show or hide the process. But it shows an error:
Cannot read property 'valueFieldType' of undefined.
1).html file
<mat-form-field style="width: 30%">
<mat-select formControlName="evaluationRuleField" placeholder="Select Field" [value]="evaluationRuleField" id="evaluationRuleField" name="evaluationRuleField">
<mat-option *ngFor="let evaluationRuleField of evaluationRuleFields" [value]="evaluationRuleField">{{ evaluationRuleField.viewValue }}</mat-option>
</mat-select>
</mat-form-field>
<!--Start Dynamically Change Field-->
<mat-form-field class="example-full-width" style="width: 30%" *ngIf = "evaluationRuleField.valueFieldType == 'text'">
<input matInput formControlName="evaluationRuleValue" placeholder="Value" [ngModel]="evaluationRuleValue" id="evaluationRuleValue" name="evaluationRuleValue" required>
</mat-form-field>
<mat-form-field class="example-full-width" style="width: 30%" *ngIf = "evaluationRuleField.valueFieldType == 'dropdwon'">
<mat-select formControlName="evaluationRuleField" placeholder="Select Field" [(value)]="ruleValueFields" id="evaluationRuleField" name="evaluationRuleField" (change)="getValue()">
<mat-option *ngFor="let ruleValueField of ruleValueFields" [value]="ruleValueField.value">{{ ruleValueField.viewValue }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="example-full-width" style="width: 30%" *ngIf = "evaluationRuleField.valueFieldType == 'multiselect'">
<mat-select placeholder="Toppings" formControlName="evaluationRuleField" multiple>
<mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
<!--Start Dynamically Change Field-->
2).ts file
private fieldArray: Array<any> = [{evaluationRuleField:"",condition:"condition",value:"value"}];
evaluationRuleFields = [
{value:"field_1",valueFieldType:'text',viewValue:"Field 1"},
{value:"field_2",valueFieldType:'dropdown',viewValue:"Field 2"},
{value:"field_3",valueFieldType:'text',viewValue:"Field 3"},
{value:"field_4",valueFieldType:'multiselect',viewValue:"Field 4"},
{value:"field_5",valueFieldType:'dropdown',viewValue:"Field 5"}
] {value:"field_3",valueFieldType:'text',viewValue:"Field 3"},
{value:"field_4",valueFieldType:'multiselect',viewValue:"Field 4"},
{value:"field_5",valueFieldType:'dropdown',viewValue:"Field 5"}
]
Upvotes: 3
Views: 22034
Reputation: 10697
Try below code:
HTML Code:
<mat-form-field>
<mat-select [(value)]="selected" formControlName="evaluationRuleField" id="evaluationRuleField" placeholder="Select value" name="evaluationRuleField">
<mat-option *ngFor="let evaluationRuleField of evaluationRuleFields" [value]="evaluationRuleField">
{{evaluationRuleField.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
{{selected}} // the selected value
Your Conditions:
<div *ngIf="selected">
<mat-form-field class="example-full-width" style="width: 30%" *ngIf="selected.valueFieldType === 'text'">
<input matInput formControlName="evaluationRuleValue" placeholder="Value" [ngModel]="evaluationRuleValue" id="evaluationRuleValue"
name="evaluationRuleValue" required>
</mat-form-field>
<mat-form-field class="example-full-width" style="width: 30%" *ngIf="selected.valueFieldType ==='dropdown'">
<mat-select formControlName="evaluationRuleField" placeholder="Select Field" [(value)]="ruleValueFields" id="evaluationRuleField"
name="evaluationRuleField">
<mat-option *ngFor="let ruleValueField of ruleValueFields" [value]="ruleValueField.value">{{ ruleValueField.viewValue }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="example-full-width" style="width: 30%" *ngIf="selected.valueFieldType == 'multiselect'">
<mat-select placeholder="Toppings" multiple>
<mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
{{selected | json}}
</div>
TS:
public selected: any; // which returns an array of selected value objects incase single select then returns an object
And the reason behind the undefined
because when the variable is intialized then it don't have a property like valueFeildType
Ex StackBlitz Demo:
https://stackblitz.com/edit/angular-dscav5?file=app%2Fselect-value-binding-example.html
Upvotes: 6
Reputation: 2110
You need to use ngModel so as to get the value to validate. Whatever you define in value="", will be assigned to model on selection.
Replace this :
<mat-select formControlName="evaluationRuleField" placeholder="Select Field"
[value]="evaluationRuleField" id="evaluationRuleField"
name="evaluationRuleField">
<mat-option *ngFor="let evaluationRuleField of
evaluationRuleFields" [value]="evaluationRuleField">{{
evaluationRuleField.viewValue }}</mat-option>
</mat-select>
With :
<mat-select formControlName="evaluationRuleField" placeholder="Select Field"
([ngModel])="ev"
id="evaluationRuleField"
name="evaluationRuleField">
<mat-option *ngFor="let evaluationRuleField of
evaluationRuleFields" [value]="evaluationRuleField.valueFieldType">{{
evaluationRuleField.viewValue }}</mat-option>
</mat-select>
and Then use it like :
*ngIf = "ev == yourvalue"
Upvotes: 0