I'm having a dynamic form with cascading dropdowns. When the page loads, I assign the values to the controls, but the selectionchange event isn't triggered.
HTML:
<div formArrayName="userDataAttributes" *ngFor="let other of userForm.get('userDataAttributes')['controls']; let i = index" class="form-group">
<div [formGroupName]="i">
{{i + 1}}.
<mat-form-field>
<mat-select matInput placeholder="Select Data Attribute" formControlName="dataAttributeId" matNativeControl (selectionChange)="refreshUserDataAttributeValuesByAttrId($event.value, i);">
<mat-option *ngFor="let attr of List1" [value]="attr.dataAttributeId">{{attr.dataAttributeName}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select matInput multiple formControlName="dataAttributeValues" matNativeControl>
<mat-option *ngFor="let attr of List2[i]" [value]="attr.dataAttributeValueId">{{attr.dataAttributeValue}}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
Typescript:
refreshUserDataAttributeValuesByAttrId(attributeId: number, index: number) {
if (attributeId && attributeId > 0) {
this.List2[index] = this.List1?.filter(a => a.dataAttributeId === attributeId) ?? [];
}
else {
this.List2[index]= [];
}
}
addUserDataAttributes(dataAttributeId: number, dataAttributeValues: any ): FormGroup{
return this.formBuilder.group({
dataAttributeId: [dataAttributeId],
dataAttributeValues: [dataAttributeValues]
});
}
bindValuesToDynamicForm(){
array: any=[{
dataAttributeId: 1,
dataAttributeValues: "4,5"},
{
dataAttributeId: 2,
dataAttributeValues: "2,3"}]
array.forEach((x,i)=>{ (<FormArray>this.userForm.get('userDataAttributes')).push(this.addUserDataAttributes(x.dataAttributeId, x.dataAttributeValues.split(',')));
})
}
With the above code,the first dropdown dataAttributeId gets loaded correctly
but couldn't trigger the selectionChange of that control so it refreshes the dataAttributeValues control and sets the value.
Tried,
this.refreshUserDataAttributeValuesByAttrId(x.dataAttributeId, i);
Any help?
The way to solve this is to manually call the refreshUserDataAttributeValuesByAttrId method after you set the value of your dataAttributeId control. You can do this in your bindValuesToDynamicForm method where you are iterating over your array and setting the values.
Here’s how you can do it:
After pushing a new group into your form array, the refreshUserDataAttributeValuesByAttrId method is called with the current dataAttributeId and index, which should update your List2 array as expected.
However, setting the values for dataAttributeValues control won't be enough because the values from array are strings and the values in your mat-option are probably different objects. You need to find the correct objects from List2[i] to set as the values for your dataAttributeValues control.
To set the correct values, you might need to modify your addUserDataAttributes method to find the correct objects from List2[i] to set as the default values for your dataAttributeValues control. You would do this after the List2[i] array is populated by the refreshUserDataAttributeValuesByAttrId method.
Here is a rough idea of how you might do this:
In your bindValuesToDynamicForm method, update the call to addUserDataAttributes to pass the index as well: