How to remove the previously selected option from a drop-down menu in a table?

I am making a project on angular 7.It has a table with a column having dropdowns. The dropdown contains various languages. When a language is selected in a particular row, then it shouldn't appear in the dropdown in the subsequent row. How do I do that?

I tried deleting the selected language from the array using splice().But as it deletes the object, it is also not shown in the dropdown.

Following is the html -(it is the row of the table that defines the dropdown, and this row is dynamic)

 <tr *ngFor="let field of fieldArray;let i = index">
  <td><button class="btn" (click)="deleteFieldValue(i)"><i class="fa fa-trash"></i></button></td>
  <td class="select">
    <select #selectLang (change)="selected(selectLang.value,i)">
      <option value="undefined" disabled>Select Language</option>
      <option *ngFor="let lang of languageList" value={{lang.name}} [ngValue]="lang.name">{{lang.name}}</option>
    </select>
  </td>
  <td>
    <input id="fileUpload" name="fileUpload" type="file" name="upload_file" (change)=onFileChange($event)>
  </td>
</tr>

following is the typescript code -

languageList = [{'name': "Dothraki"},{'name': "Japanese"}, 
{'name':"German"},{'name':"French"},{'name': "Spanish"}, {'name': 
"Russian"}, {'name': "Italian"}];
  selectedLang;
  optionLang:string;
  fieldArray: Array<any> = [];
  newAttribute: any = {};
  fileUploadName: any;
  selected(lang:string,index:number){
    console.log(lang);

    // this.languageList.splice(index, 1);
    for(let i =0; i< this.languageList.length; i++) {
      if(this.languageList[i]['name'] === lang) {
        this.languageList.splice(i,1);
        break;
      }
    }
  }
  addFieldValue() {
    this.fieldArray.push("hg");
    this.newAttribute = {};
  }
  deleteFieldValue(index: number) {
    this.fieldArray.splice(index, 1);
}
  openFileBrowser(event:any){
    event.preventDefault();
    let element: HTMLElement = document.getElementById('fileUpload') as 
HTMLElement;
    element.click();
  }

  onFileChange(event:any){
    let files = event.target.files;
    this.fileUploadName = files[0].name;
    console.log(files);
  }

Solution 1:

you can solve the problem by holding a set of selected languages and display options conditionally based on whether an option/language is selected before or not.

create a Set to hold selected langs

selectedLangs = new Set<string>();

create a view query to get a list of all select elements

@ViewChildren("selectLang") langSelects: QueryList<ElementRef<HTMLSelectElement>>;

whenever a selection is made/changed on any of the select elements re-populate the selectedLangs set

  selected() {
    this.selectedLangs.clear();
    this.langSelects.forEach(ls => {
      const selectedVal = ls.nativeElement.value;
      if (selectedVal && selectedVal !== "undefined") this.selectedLangs.add(selectedVal);
    });
 }

whenever a field is deleted just remove that language from selectedLangs

  deleteFieldValue(index: number, lang: string) {
    this.selectedLangs.delete(lang);
    this.fieldArray.splice(index, 1);
  }

and when displaying options for a select check if it is currently selected on current select or already selected in another select *ngIf="selectLang.value === lang.name || !isSelected(lang.name)"

<ng-container *ngFor="let lang of languageList" >
  <option *ngIf="selectLang.value === lang.name || !isSelected(lang.name)" value={{lang.name}} [ngValue]="lang.name">
      {{lang.name}}
  </option>
</ng-container>

where isSelected is defined as

  isSelected(lang: string) {
    return this.selectedLangs.has(lang);
  }

here is a working demo with full source https://stackblitz.com/edit/angular-dqvvf5