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