0

I am new to angular and developing my very first application using angular 4 and typescript

I want to use Cascading drop-down in table using angular4

Currently, I have been working on it but when I change drop down from the first row it is a binding second level dropdown for all row.

I want to bind the second level drop down of the row from the first level drop down is changed.

I have some idea on my mind to achieve this but I guess It might be a patch so I am very curious to know any proper way of angular to achieve this.

ts file code

import { Component, OnInit, EventEmitter } from '@angular/core';
import { Category } from '../model/Category';
import { SubCategory } from '../model/subCategory';
import { Partner } from '../model/partner';
import { GetdataService } from '../../../../Server/api/Getdata.service';
import { Router } from '@angular/router';

@Component({
  templateUrl: 'UploadFile.component.html'
})
export class UploadFileComponent implements OnInit {
  AllCategoryList: Category[] = [];
  AllSubCategoryList: SubCategory[] = [];
  constructor(private _datatask: GetdataService, private _router: Router) { }

  onChangeCategory(deviceValue) {         
    if (deviceValue > 0) {
      this._datatask.getAllSubCategory(deviceValue).subscribe(
        (data: SubCategory[]) => {
          this.AllSubCategoryList = data;
        }
      );
      console.log("from component: " + deviceValue);
    }
    else
      {
        //clear dropdown...
        this.AllSubCategoryList= [];        
      }
  }

  ngOnInit() {
    this._datatask.getAllCategory().subscribe(
      (data: Category[]) => {
        this.AllCategoryList = data;
      }
    );

    this._datatask.getAllPartner().subscribe(
      (data: Partner[]) => {
        this.AllPartnerList = data;
      }
    );
  }  
}

HTML file

<div>
  <table width="100%" border="1">
    <thead>     
      <th>Category</th>
      <th>SubCategory</th>
      <th>Partner</th>
    </thead>
    <tbody *ngFor="let transaction of transactions">
      <tr>       
        <td>
          <select style="Width:100px;" (change)="onChangeCategory($event.target.value)" >
            <option value=0>--Select--</option>
                <option  value="{{item.ID}}"  *ngFor="let item of AllCategoryList" [ngValue]="item.ID" >{{item.Category}}</option>
            </select>
        </td>
        <td>
          <select style="Width:100px;">
            <option value=0>--Select--</option>
                 <option  *ngFor="let item of AllSubCategoryList" [ngValue]="item.ID" >{{item.SubCategory}}</option> 
            </select>
        </td>
        <td>
          <select style="Width:100px;">
            <option value=0>--Select--</option>
                <option  *ngFor="let item of AllPartnerList" [ngValue]="item.ID" >{{item.PartnerName}}</option>
            </select>
        </td>
      </tr>
    </tbody>
  </table>
</div>

any help will be highly appreciated.

2 Answers 2

3

The problem is you needed an array of states... (in the plunker you listed in the comments below). You can probably apply same to your code in original question.

list-component.ts tweaks

export class CountryListComponent {

  states: State[] = [[] as State[],[] as State[],[] as State[]] 

  onSelect(value,index) {
    this.states[index] = this._dataService.getStates().
      filter((item)=> item.countryid == value);
  }
}

list-component.html tweak

  • Updated: after this exchange with @GünterZöchbauer :
  • Use (ngModelChange) over (change)

  <select [(ngModel)]="selectedCountry[number].id"
    (ngModelChange)="onSelect($event, number)">

Fixed Plunker

Sign up to request clarification or add additional context in comments.

12 Comments

Thanks for your reply...But if you can explain what you are asking to do...I am not able to get what you are asking to do
Okay...Let me try with that
sorry JGFMK, but your solution is not working for me.
If you post a Plunker of what you've got, I'll take a look.
@JGFMK : i have seen your solution but it's not working for me,also i have created Plunker regarding this. In this one can change first country from first row then binding state regarding in second whole column's dropdown insted of first one.any help..?plnkr.co/edit/BkDk9wLB3J5Uv2ijEX6i?p=preview
|
0

I am also faced this problem and finally got a solution using custom pipe.

make a filter in external file like - mycustomfilter.ts

mycustomfilter.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'myCustomFilter',
    pure: false
})
export class myCustomFilterPipe implements PipeTransform {

  transform(items: any[], field : string, value): any[] {
    if (!items) return [];
    if (!value || value.length === 0) return items;
    return items.filter(it =>
    it[field] === value);
  }
}

declarations in app module

@NgModule({
  imports: [ BrowserModule, FormsModule ],
  declarations: [ App, myCustomFilterPipe],
  bootstrap: [ App ]
})

item-order.component.ts

categoryList=[{id:1,name:'Office Stationery'},
              {id:2,name:'Grocery'}
        ];
itemList=[
         {id:1,name:'Pen',categoryID:1},
         {id:2,name:'A4 Peper',categoryID:1},
         {id:3,name:'Oil',categoryID:2},
         {id:4,name:'Sugar',categoryID:2}
    ];

item-order.component.html

<tr *ngFor="let order of o.controls; let i = index" [formGroup]="order" class="form-row">
              
<td>
<select class="form-control" formControlName="ItemCategoryID">
<option value="">Select</option>
<option *ngFor="let s of categoryList" [ngValue]="s.id">{{s.name}}</option>
</select>
</td>
<td>
<select class="form-control" formControlName="ItemID">
<option value="">Select</option>
<option *ngFor="let s of itemList | myCustomFilter : 'categoryID' : order.value.ItemCategoryID" [ngValue]="s.id">{{s.name}}</option>
</select>
</td>
</tr>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.