I have a form and a provision to add the field groups dynamically, initially it shows one field group and Add or X it will add and remove the groups
The form itself contains a dropdown and the scenario I'm currently stuck is at, when I select or deselect the options if should reflect in the sibling dropdowns that got added and also when removed .. The selected option should no more be available for other dropdowns and when removed or changed it should be available again...
I'm keeping a track of selected options with index as:
selectedCities = {};
and onChange of dropdown
modifySelectedCities(val, i) { this.selectedCities[i] = val.value; }
The issue I' currently facing is the dropdown when selected with the option itself would be gone since it is no more in the options, below is the code I tried so far
availableCities(i) {
console.log('sc', this.selectedCities);
const av = this.cities
.map((city) => {
if (!Object.values(this.selectedCities).includes(city)) {
return city;
} else {
null;
}
})
.filter(Boolean);
console.log('av', av);
return av;
}
<div class="card flex justify-content-center">
<form [formGroup]="myForm">
<div formArrayName="fieldsArray" class="form-group-container">
<div
*ngFor="let fieldGroup of fieldsArray.controls; let i=index"
[formGroupName]="i"
class="form-group-city"
>
<p-dropdown
placeholder="Select city"
formControlName="city"
[options]="availableCities()"
(onChange)="modifySelectedCities($event, i); availableCities(i)"
>
<ng-template let-option pTemplate="item">
<div>{{ option }}</div>
</ng-template>
</p-dropdown>
<i
class="pi pi-times"
(click)="removeFields(i)"
style="font-size: 1.5rem; cursor: pointer; margin-left: 10px"
></i>
</div>
</div>
<div style="margin-top: 20px">
<button pButton type="button" label="Add" (click)="addFields()"></button>
</div>
</form>
</div>
I couldn't think of how to get this work, and I hope it is clear on what I'm trying
Attaching the full repro in this Stackblitz link, any help is highly appreciated, Thank you
I created forked STACKBLITZ with possible solution.
Some points:
options
property, because it will be called on each change detection cycle, rather update it when needed (initial state, add group, remove group)I added recalculate function:
recalculateOptions() {
this.options.forEach((_, ind) => {
this.options[ind] = [
...Object.keys(this.availableCities),
...(this.selectedCities[ind] ? [this.selectedCities[ind]] : []),
].sort();
});
this.addDisabled =
!Object.keys(this.availableCities).length ||
this.fieldsArray.length !== this.selectedCities.length;
}