CE0
CE0

Reputation: 191

Angular 5 how to bind drop-down value based on another drop-down

I have a select drop-down that i populate from an api, i want to be able to populate a second select drop-down based on the user's first choice and subsequently populate a second drop-down based on the user's second choice. Say i have my input fields so

form.component.html

<div class="form-group col-sm-6">
 <label> Category</label>
 <select class="form-control" [(ngModel)]="product.productCategory" [formControl]="productForm.controls['productCategory']" require>
   <option *ngFor="let item of categorys" [value]="item.slug">{{item.name}}</option>
 </select>
</div>
<div class="form-group col-sm-6">
  <label> Product Type</label>
  <select class="form-control" [(ngModel)]="product.productType" [formControl]="productForm.controls['productType']" require>
    <option *ngFor="let item of productTypes" [value]="item.slug">{{item.name}}</option>
  </select>
</div>
<div class="form-group col-md-6">
  <label>Sub-Category</label>
    <select class="form-control" [(ngModel)]="product.subCategory" [formControl]="productForm.controls['subCategory']" require>
      <option *ngFor="let item of subs" [value]="item.slug">{{item.name}}</option>
    </select>
</div>

As it is i am binding the whole list to each individual select drop-down but i want the subCategory to be only those under the selected category and same then productType based on the subCategory selected. This is how i retrieve the category as it is the parent selection

form.component.ts

fetchCategorys() {
this.categorySrv.fetchCategories().then((response: any) => {
  this.categorys = response;
  console.log(this.categorys);
})
  .catch(error => this.error = error)
}

I am using same method to get the subCategory and productType respectively. As you can see it brings all the items in each section from db but i want to be able to bind subCategory based on the choice of category and also bind productType based on the choice of subCategory. Note that console.log(this.categorys) displays the category with their respective subCategory and productType but i can't figure out how to make the binding correspond.

Upvotes: 1

Views: 5226

Answers (1)

Karl Johan Vallner
Karl Johan Vallner

Reputation: 4300

Template

<div class="form-group col-sm-6">
 <label> Category</label>
 <select class="form-control" (change)="categoryChange($event)" [(ngModel)]="product.productCategory" [formControl]="productForm.controls['productCategory']" require>
   <option *ngFor="let item of categorys" [value]="item.slug">{{item.name}}</option>
 </select>
</div>
<div class="form-group col-sm-6">
  <label> Product Type</label>
  <select class="form-control" (change)="productTypeChanged($event)" [(ngModel)]="product.productType" [formControl]="productForm.controls['productType']" require>
    <option *ngFor="let item of productTypes" [value]="item.slug">{{item.name}}</option>
  </select>
</div>
<div class="form-group col-md-6">
  <label>Sub-Category</label>
    <select class="form-control" [(ngModel)]="product.subCategory" [formControl]="productForm.controls['subCategory']" require>
      <option *ngFor="let item of subs" [value]="item.slug">{{item.name}}</option>
    </select>
</div>

Component

public allProductTypes: ProductType[];
public allSubs: Category[];

public categoryChange( $event: Category ) {
    this.productTypes = this.allProductTypes.filter( _productType => _productType.belongsTo( $event));
}

public productTypeChanged( $event: ProductType ) {
    this.subs = this.allSubs.filter( _sub => _sub.belongsTo( $event ) ); 
}

So you bind your to the dropdown change events. Then, each time a category or product type is chosen, we filter the data that the dropdowns have available to show.

You will also probably have to reset the downstream choices, aka. when changing category, then reset product type and sub cat, because the new top level category might not allow for the old type and subcat values to exist.

Upvotes: 1

Related Questions