I have a select field that populates data as below. I populate data items as their names. My goal is to select data's name and their corresponded ids.
Here is my HTML template:
<select class="custom-select d-block w-100" id="test" [(ngModel)]="record.firstName" #firstName="ngModel" name="firstName">
<option value="">Choose...</option>
<option *ngFor="let item of items" value="{{ item.name}}">{{ item.name }}</option>
</select>
When I select an item from the dropdown, record.firstName is set to item.name as expected. I was wondering how can I also retrieve item.id when I select the same item. I couldn't find a resource or tutorials to fix this. Any help will be appreciated!
Instead of setting the option values to item.name, you can set them to the item objects with [ngValue]. That will allow you to access any property of the selected item. If necessary, you can handle the ngModelChange event to do additional processing.
<select [(ngModel)]="selectedItem" (ngModelChange)="processSelectedItem($event)" ...>
<option [ngValue]="undefined">Choose...</option>
<option *ngFor="let item of items" [ngValue]="item">{{ item.name }}</option>
</select>
As an example, you could set record to a modified version of the selected item with:
processSelectedItem(item) {
this.record.firstName = item.name;
this.record.item_id = item.id;
}
Alternatively, you could bind the options to item.id (I assume that the id is unique), and set the record.firstName in the ngModelChange event handler:
<select [(ngModel)]="record.item_id" (ngModelChange)="processSelectedItem($event)" ...>
<option value="-1">Choose...</option>
<option *ngFor="let item of items" [value]="item.id">{{ item.name }}</option>
</select>
with:
processSelectedItem(itemId) {
this.record.firstName = this.items.find(x => x.id === itemId).name;
}
Related
<select class="custom-select rounded-0" id="exampleSelectRounded0" name="kode_poli">
#foreach ($polikliniks as $poliklinik)
<option value="{{$poliklinik->id}}">{{$poliklinik->kode_poli}} | {{$poliklinik->nama_poli}}</option>
#endforeach
</select>
My select option value will return a first id of poliklinik table
How to set select option 'selected' with another value in poliklinik table with my selected value when i insert before?
You will need to write an option with the selected id as the value and selected name in between the option tag
<select class="custom-select rounded-0" id="exampleSelectRounded0" name="kode_poli">
<option value="{{$selected->id}}">{{$selected->kode_poli}}</option>
#foreach ($polikliniks as $poliklinik)
<option value="{{$poliklinik->id}}">{{$poliklinik->kode_poli}}</option>
#endforeach
</select>
Note: substitute the selected with the model you used in saving it
I wanted to bind a select element values to array RelatedComponentIDs:
<select class="form-control form-control-sm" formControlName="RelatedComponentIDs">
<option [ngValue]="null"></option>
<option [ngValue]="type.Value" *ngFor="let type of allComponents">{{ type.Name }}</option>
</select>
this.form= this.formBuilder.group({
RelatedComponentIDs: [[]],
});
When I am selecting any value in select, it is mapping to RelatedComponentIDs but as a string not as a array.
I wanted it to return to array.
Any help?
Thanks.
So guys, I have this very simple snippet
<div class="form-group">
<label for="exampleFormControlSelect1">Example select</label>
<select class="form-control" id="exampleFormControlSelect1" (change)="onChooseMenuItem($event.target.value)">
<option selected disabled>Please select a program</option>
<option
style="cursor: pointer"
*ngFor="let menuItem of ngrxMenuItems, let i = index"
value={{i}}
>{{menuItem.type}}
</option>
</select>
</div>
when i make a choice it always shows me the first option as selected. Let's say ngrxMenuItems is an array with [1,2,3,4]. No matter what is the choice you make it will show you only the first option.
What i tried:
- removing (change)="onChooseMenuItem($event.target.value)" and replacing it with (click) event on every row
- trying ngIf options
What I assume it is:
= Some Angular behaviour I am not aware of.
You main problem is here (change)="onChooseMenuItem($event.target.value), the reason being that the target property does not exist on the $event emitted event, you need to handle the value part in the ts method like so
Html
<div class="form-group">
<label for="exampleFormControlSelect1">Example select</label>
<select class="form-control" id="exampleFormControlSelect1" (change)="onChooseMenuItem($event)"> <!-- Change the (change) event emitter -->
<option selected disabled>Please select a program</option>
<option
style="cursor: pointer"
*ngFor="let menuItem of ngrxMenuItems, let i = index"
value={{i}}
>{{menuItem.type}}
</option>
</select>
</div>
Ts
onChooseMenuItem(event: any){
const value = event.target.value;
console.log(value);
}
You do not bind a value from your component to your selection.
So select does not know which values is the actual to select as option.
You must add ngModel to your select:
<select class="form-control" id="exampleFormControlSelect1" [(ngModel)]="select1">
<option selected disabled>Please select a program</option>
<option
style="cursor: pointer"
*ngFor="let menuItem of ngrxMenuItems, let i = index"
value={{i}}
>{{menuItem.type}}
</option>
'select1' is a variable in your component containing the information about the selected option.
I am have a hard time trying to do an ngFor on nested JSON. I have read that ngFor is supposed to be for arrays only, but there are so many APIs that pump out nested JSON, that I figure that has to be a way.
The following is an example of the category JSON that I am receiving - I am simplifying what it could be:
{
"Categories": {
"candles": {
"name": "Candle"
},
"oils": {
"name": "Oil"
},
"chocolates": {
"name": "Chocolates"
},
"toys": {
"name": "Toys"
}
}
}
The following is an example of the http get:
this.http.get(this.jsonUriNestObj).subscribe(resultObj => {
this.categoryObj = resultObj["Categories"];
console.log(
"resultObj['Categories']: ",
JSON.stringify(resultObj["Categories"])
);
This would be an example of what comes back in the console:
resultObj['Categories']: {"candles":{"name":"Candle"},"oils":{"name":"Oil"},"chocolates":{"name":"Chocolates"},"toys":{"name":"Toys"}}
The following is what is currently not displaying any options in the select, but at the same time, zero errors and zero warnings:
<select id="categories" class="form-control">
<option value="">Please select an item</option>
<option
*ngFor="let item of this.categoryObj.name; let i = index"
value="{{ i }}"
>{{ item }}</option
>
</select>
I have tried this.categoryObj[i], this.categoryObj[i]['name'], etc...
How do I ngFor a nested JSON - hopefully, you can offer a dynamic solution.
As usual, thanks in advance and happy new year to you and yours
You can use keyValue pipe to iterate objects - I think this pipe is available from angular 6.1
Try something like this
<select id="categories" class="form-control">
<option value="">Please select an item</option>
<option
*ngFor="let item of this.categoryObj | keyvalue; let i = index"
value="{{ item.key }}"
>{{ item.value.name }}</option
>
</select>
I think this might help you - but make sure this pipe seems to be impure
For more info check this - Happy new year and happy coding :)
You are iterating over the object not array, array can be iterated easily.
You can use pipe to transform your objects to array or you can change your json object to array.
You need one new variable which can iterate easily and you can use it later, like this
name = 'Angular';
categoryObj = {"candles":{"name":"Candle"},"oils":{"name":"Oil"},"chocolates":{"name":"Chocolates"},"toys":{"name":"Toys"}}
outputData: any;
constructor(){
this.outputData = Object.keys(this.categoryObj).reduce((prev,curr)=>{
prev.push(this.categoryObj[curr].name);
return prev;
},[])
}
and in your view
<select id="categories" class="form-control">
<option value="">Please select an item</option>
<option
*ngFor="let item of this.outputData; let i = index"
value="{{ i }}"
>{{ item }}</option
>
</select>
EDIT:
As you want to iterate through object inside array, you can use
this.outputData = Object.keys(this.categoryObj).reduce((prev, curr) => {
prev.push(this.categoryObj[curr]);
return prev;
}, [])
this will give you array of objects
0: Object
name: "Candle"
1: Object
name: "Oil"
and you can bind it like this
<select id="categories" class="form-control">
<option value="">Please select an item</option>
<option
*ngFor="let item of this.outputData; let i = index"
value="{{ i }}"
>{{ item.name }}</option
>
</select>
Demo
Declare one variable to hold the revised JSON list:
list : any[] = [];
Just replace your get request with this:
this.http.get(this.jsonUriNestObj).subscribe(resultObj => {
this.categoryObj = resultObj["Categories"];
Object.keys(this.categoryObj).forEach(key => {
this.list.push(this.categoryObj[key])
})
});
HTML:
<select id="categories" class="form-control">
<option value="">Please select an item</option>
<option *ngFor="let item of list; let i = index" [value]="i">
{{ item.name }}
</option>
</select>
FORKED STACKBLITZ
I have a select HTML element in an Angular ngFor loop:
<select formControlName="type" required>
<option *ngFor="let type of typeList" [ngValue]="type.value">{{ type.caption }}</option>
</select>
In Internet Explorer, the first item in the list is selected when the template loads, but it's value isn't set in the form control, so causes a 'required' validation error until another value is selected in the list. I want to have a 'Please select' option that has a null value to prevent this happening.
This is for Angular 2+ used with or without TypeScript
Add an option like so:
<option [ngValue]="null">Please select</option>
So your control will look like:
<select formControlName="type" required>
<option [ngValue]="null">Please select</option>
<option *ngFor="let type of typeList" [ngValue]="type.value">{{ type.caption }}</option>
</select>
This works as Angular inspects the value attribute because of the square brackets. The value becomes a true null, unlike if we used value="" (this is just an empty string and doesn't match null).
In case you're not using ngForm, another approach to implementing the selected value is to do something like [value]='selectedType' (change)='selectedType = $event.target.value' in your select tag. For example:
In your component.ts:
public selectedType: string;
In your component.html
<select [value]='selectedType' (change)='selectedType = $event.target.value'>
<option value=''>-- Select your Type --</option>
<option *ngFor="let type of typeList" [ngValue]="type.value">{{ type.caption }}</option>
</select>
component.ts
public selectedValue = 'None';
component.html:
<div ">
<label>Highlight</label>
<select [(ngModel)]="selectedTrunk" (change)="onChangeTrunk($event)">
<option value='None'>None</option>
<option *ngFor="let trunklist of DRLNameTrunkList" [selected]="trunk" [value]="trunklist.SIPTRUNKNAME">{{trunklist.SIPTRUNKNAME}}</option>
</select>
</div>
This is my code pelase modify as per your requirements