I am using Angular 2 (TypeScript).
I want to do something with the new selection, but what I get in onChange() is always the last selection. How can I get the new selection?
<select [(ngModel)]="selectedDevice" (change)="onChange($event)">
<option *ngFor="#i of devices">{{i}}</option>
</select>
onChange($event) {
console.log(this.selectedDevice);
// I want to do something here with the new selectedDevice, but what I
// get here is always the last selection, not the one I just selected.
}
If you don't need two-way data-binding:
<select (change)="onChange($event.target.value)">
<option *ngFor="let i of devices">{{i}}</option>
</select>
onChange(deviceValue) {
console.log(deviceValue);
}
For two-way data-binding, separate the event and property bindings:
<select [ngModel]="selectedDevice" (ngModelChange)="onChange($event)" name="sel2">
<option [value]="i" *ngFor="let i of devices">{{i}}</option>
</select>
export class AppComponent {
devices = 'one two three'.split(' ');
selectedDevice = 'two';
onChange(newValue) {
console.log(newValue);
this.selectedDevice = newValue;
// ... do other stuff here ...
}
If devices is array of objects, bind to ngValue instead of value:
<select [ngModel]="selectedDeviceObj" (ngModelChange)="onChangeObj($event)" name="sel3">
<option [ngValue]="i" *ngFor="let i of deviceObjects">{{i.name}}</option>
</select>
{{selectedDeviceObj | json}}
export class AppComponent {
deviceObjects = [{name: 1}, {name: 2}, {name: 3}];
selectedDeviceObj = this.deviceObjects[1];
onChangeObj(newObj) {
console.log(newObj);
this.selectedDeviceObj = newObj;
// ... do other stuff here ...
}
}
Plunker - does not use <form>
Plunker - uses <form> and uses the new forms API
You can pass the value back into the component by creating a reference variable on the select tag #device and passing it into the change handler onChange($event, device.value) should have the new value
<select [(ng-model)]="selectedDevice" #device (change)="onChange($event, device.value)">
<option *ng-for="#i of devices">{{i}}</option>
</select>
onChange($event, deviceValue) {
console.log(deviceValue);
}
Just use [ngValue] instead of [value]!!
export class Organisation {
description: string;
id: string;
name: string;
}
export class ScheduleComponent implements OnInit {
selectedOrg: Organisation;
orgs: Organisation[] = [];
constructor(private organisationService: OrganisationService) {}
get selectedOrgMod() {
return this.selectedOrg;
}
set selectedOrgMod(value) {
this.selectedOrg = value;
}
}
<div class="form-group">
<label for="organisation">Organisation
<select id="organisation" class="form-control" [(ngModel)]="selectedOrgMod" required>
<option *ngFor="let org of orgs" [ngValue]="org">{{org.name}}</option>
</select>
</label>
</div>
I ran into this problem while doing the Angular 2 forms tutorial (TypeScript version) at https://angular.io/docs/ts/latest/guide/forms.html
The select/option block wasn't allowing the value of the selection to be changed by selecting one of the options.
Doing what Mark Rajcok suggested worked, although I'm wondering if there's something I missed in the original tutorial or if there was an update. In any case, adding
onChange(newVal) {
this.model.power = newVal;
}
to hero-form.component.ts in the HeroFormComponent class
and
(change)="onChange($event.target.value)"
to hero-form.component.html in the <select> element made it work
use selectionChange in angular 6 and above. example
(selectionChange)= onChange($event.value)
I was has same problem and i solved using the below code :
(change)="onChange($event.target.value)"
In Angular 8 you can simply use "selectionChange" like this:
<mat-select [(value)]="selectedData" (selectionChange)="onChange()" >
<mat-option *ngFor="let i of data" [value]="i.ItemID">
{{i.ItemName}}
</mat-option>
</mat-select>
Angular 7/8
As of angular 6,the use of ngModel input property with reactive forms directive have been deprecated and removed altogether in angular 7+. Read official doc here.
Using reactive form approach you can get/set selected data as;
//in your template
<select formControlName="person" (change)="onChange($event)"class="form-control">
<option [value]="null" disabled>Choose person</option>
<option *ngFor="let person of persons" [value]="person">
{{person.name}}
</option>
</select>
//in your ts
onChange($event) {
let person = this.peopleForm.get("person").value
console.log("selected person--->", person);
// this.peopleForm.get("person").setValue(person.id);
}
Another option is to store the object in value as a string:
<select [ngModel]="selectedDevice | json" (ngModelChange)="onChange($event)">
<option [value]="i | json" *ngFor="let i of devices">{{i}}</option>
</select>
component:
onChange(val) {
this.selectedDevice = JSON.parse(val);
}
This was the only way I could get two way binding working to set the select value on page load. This was because my list that populates the select box was not the exact same object as my select was bound to and it needs to be the same object, not just same property values.
If you don't need two-way data-binding:
<select (change)="updateSorting($event)">
<option disabled selected>Sorting</option>
<option value="pointDes">pointDes</option>
<option value="timeDes">timeDes</option>
<option value="timeAsc">timeAsc</option>
<option value="pointAsc">pointAsc</option>
</select>
updateSorting(e: any) {
// console.log((e.target as HTMLSelectElement)?.value); // also work
console.log(e.target.value);
}
<mat-form-field>
<mat-select placeholder="Vacancies" [(ngModel)]="vacanciesSpinnerSelectedItem.code" (ngModelChange)="spinnerClick1($event)"
[ngModelOptions]="{standalone: true}" required>
<mat-option *ngFor="let spinnerValue of vacanciesSpinnerValues" [value]="spinnerValue?.code">{{spinnerValue.description}}</mat-option>
</mat-select>
I used this for angular Material dropdown. works fine
I tried all the suggestions and nothing works for me.
Imagine the situation: you need a 2-way binding and you have a lookup with NUMBER values and you want to fill your SELECT with the values from this lookup and highlight the chosen option.
Using [value] or (ngModelChange) is a no-go, because you won't be able to select the chosen option after user initiated the change: [value] considers everything a string, as to (ngModelChange) - it obviously should not be used when user initiates the change, so it ruins the proper selection. Using [ngModel] guarantees the fixed format of received VALUE as INDEX: VALUE and it's easy to parse it correspondingly, HOWEVER once again - it ruins the selected option.
So we go with [ngValue] (which will take care of proper types), (change) and... [value], which guarantees the handler receives VALUE, not a DISPLAYED VALUE or INDEX: VALUE :) Below is my working clumsy solution:
<select
class="browser-default custom-select"
(change)="onEdit($event.target.value)"
>
<option [value]="">{{
'::Licences:SelectLicence' | abpLocalization
}}</option>
<ng-container *ngIf="licencesLookupData$ | async">
<option
*ngFor="let l of licencesLookupData$ | async"
[ngValue]="l.id"
[value]="l.id"
[selected]="l.id == selected.id"
>
{{ l.id }} {{ l.displayName | defaultValue }}
</option>
</ng-container>
</select>
onEdit(idString: string) {
const id = Number(idString);
if (isNaN(id)) {
this.onAdd();
return;
}
this.licencesLoading = true;
this.licencesService
.getById(id)
.pipe(finalize(() => (this.licencesLoading = false)), takeUntil(this.destroy))
.subscribe((state: Licences.LicenceWithFlatProperties) => {
this.selected = state;
this.buildForm();
this.get();
});
}
latest ionic 3.2.0 have modified (change) to (ionChange)
eg:
HTML
<ion-select (ionChange)="function($event)"> <ion-option>1<ion-option>
</ion-select>
TS
function($event){
// this gives the selected element
console.log($event);
}
In Angular 5 I did with the following way. get the object $event.value instead of $event.target.value
<mat-form-field color="warn">
<mat-select (ngModelChange)="onChangeTown($event)" class="form-width" formControlName="branch" [(ngModel)]="branch" placeholder="Enter branch">
<mat-option *ngFor="let branch of branchs" [value]="branch.value">
{{ branch.name }}
</mat-option>
</mat-select>
</mat-form-field>
onChangeTown(event): void {
const selectedTown = event;
console.log('selectedTown: ', selectedTown);
}
My requirement is to show the content based on selection of dropdown list.
component.ts
OptionList: LookupActionCode[]=[];
public setList(actionType: any):void{
this.anotherOptionList = [];
if(actionType == dataConstant.calendar){
this.List.push(
{
Name: dataConstant.content
},
{
Name: dataConstant.showcontent
},
{
Name: dataConstant.hidecontent
},
)}
switch(actionType){
case dataConstant.memberdata:
this.OptionList = this.memberCodes;
break;
case dataConstant.referral:
this.OptionList= this.optionalCodes;
break;
case dataConstant.Calendar:
this.OptionList = this.List;
break;
}
.component.html
//first dropdown
<label for="OptionList" class="cpp-required"> <b>Action</b></label>
<select id=action class="form-control" required (change) ="setList($event.target.value)">
<option value="" disabled [selected]="true"></option>
<option [value] = "dataConstant.referral">{{dataConstant.referral}}</option>
<option [value] = "dataConstant.memberdata">{{dataConstant.memberdata}}</option>
<option [value] = "dataConstant.calendar">{{dataConstant.content}}</option>
</select>
//second dropdown
<label> <b>Action</b></label>
<select id=action class="form-control" required>
<option value="" disabled [selected]="true"></option>
<option *ngFor="let option of optionList" [value] ="option">{{option.Name}} </option>
</select>
<div *ngIf="logic>
//some content to show and hide the data
</div>
So my requirement is from the first dropdown if i select the dataConstant.content then In secondit will show the realted dropdown lists those are dataConstant.content,dataConstant.showcontent and dataConstant.showcontent (implemented)
So If select the dataConstant.showcontent value then I need to show the data in div
Can anyone help me on this
If you first add a property to your component in ts to hold the selected value:
theProperty: string | undefined;
and on your select list in html add:
<select [(ngModel)]="theProperty" ect...
This will set up two way binding between your property and the select list. (Note reactive forms are good option here but have chose this for simplicity).
You can then add:
*ngIf="theProperty === thingToMatchTo"
But maybe pick a more sensible property name than what I've used.
NOTE - Make sure you add FormsModule to your imports in the Module that this component is declared. It's what makes the ngModel directive available to you.
Let's say I have this code:
<select id = dropdown-list>
<option value = "0"> Yes </option>
<option value = "1"> No </option>
</select>
The user can select yes or no from a dropdown list. How can I use pure JS/HTML to figure out what the user has selected (and is currently showing in the dropdown list box when the list isn't expanded) so I can use that data elsewhere? The only way I can figure out is if I add an eventListener on each option but I feel there is a better way. I am quite new to JS so I'm not sure. Thank you.
You can use onchange attribute from select element.
<select id="dropdown-list" onchange="onChange(this.value)">
<option value = "0"> Yes </option>
<option value = "1"> No </option>
</select>
and in JS:
function onChange(val) {
// `val` is the value
}
Execute a JavaScript function changeResult when a user changes the selected option of a element:
Flow:
We bind changeRegult using onchange event listener.
When we change the dropdown menu, it calls changeResult function.
Inside the function, we select our dropdown menu using its id property.
After getting the element by id, we can now access all properties.
Here we want to show the value property, so we use document.getElementById("dropdown-list").value.
For more check this link.
function changeResult() {
var x = document.getElementById("dropdown-list").value;
document.getElementById("result").innerHTML = "You selected: " + x;
}
<select id = "dropdown-list" onchange="changeResult()">
<option value = "0"> Yes </option>
<option value = "1"> No </option>
</select>
<p id="result"></p>
You may want to use on change event.
Since you use each I suppose you are using Jquery.
If you have any question just let me know.
$(document).ready(function(){
$('#dropdown-list').on('change',function(){
alert($(this).children('option:selected').val());
})
});
https://jsfiddle.net/u4dz162o/
I want to display a select with all the option of my enum and change the value to update my database.
To do so:
I have an enum:
export enum SubscriptionEnum {
DAILY= 'DAILY',
ANNUAL= 'ANNUAL',
HALF-YEARLY = 'HALF-YEARLY ',
QUARTERLY = 'QUARTERLY ',
MONTHLY = 'MONTHLY ',
}
In my .ts file i create my enum var:
SubscriptionEnum = SubscriptionEnum ;
And then i display the option in my .html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select #subscriptionid="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This example give me the select with all option and the value change in the view page when i clicked on a new option.
Then, i add the (change) in the select to call a method that change the content of the client subscription in the db. I did it like that:
.html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
In my changeInfo i send the event and take the event.id and the event.value to update my db and it works because the select option change when i click on it and the <p>{{client.subscription}}</p> that is a value of my db take the good value.
Then i wanted to add a selector so my option value take directly the good value and this is not working ...
I add it like that:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
selected="{{option.key == client.subscription}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This give highlight me my sentence and tell me "Wrong attribute method" and when i reload my page my div contains the good value which is "ANNUAL" but my option is equal to QUARTERLY. If i click to change the option, the good value will be saved in my db but the display of my select selector will be wrong.
What do i not understand ? Thank you for your help
There is a subtle difference between two similar Angular syntaxes:
selected="{{option.key == client.subscription}}"
and
[selected]="option.key == client.subscription"
There are both property bindings but the former assigns interpolated value to property.
It means that even in case of falsy values selected property will get true;
el.selected = 'false'
because string is a truthy value in js.
So you can consider the following options:
Use correct property binding:
[selected]="option.key == client.subscription"
Use value binding on <select> tag instead:
<select #subscription id="subscription" [value]="client.subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}} {{option.key == client.subscription}}
</option>
</select>
What is the proper way to implement dropdowns in ng2? I did some googling but I wasn't finding a lot of consistency.
My search.component.ts has a searchMetadata property which gets set via ngOnInit().
searchMetadata.Authors looks like [{Id=1, Value="Bob Smith"},{Id=2, Value="Mary Jones"}]
The final ng2 dropdown should be something like this:
<select #ddlAuthor (change)="updateSearchResults()">
<option value="1">John Smith</option>
<option value="2">Jane Doe</option>
<option value="3">John Denver</option>
</select>
What is the proper way to implement ng2 for this in the component.html?
You can use *ngFor to iterate over an array/collection populate the value and text accordingly. I've updated the answer to simulate a delay of 3000ms before setting the values to mimic an HTTP API call.
HTML:
<select #ddlAuthor (change)="updateSearchResults($event)">
<option *ngFor="let option of options" [value]="option.Id">{{option.Value}}</option>
</select>
TS:
export class App {
options: any[];
constructor() {}
ngOnInit() {
// simulated delay for API call
Observable
.of([
{Id:1, Value:"Bob Smith"},
{Id:2, Value:"Mary Jones"}
]).delay(3000).subscribe(values => {
this.options = values;
});
}
updateSearchResults($event) {
console.log($event);
}
}
Here is a plunker demonstrating the functionality.
Note: The array you referenced in your question [{Id=1, Value="Bob Smith"},{Id=2, Value="Mary Jones"}] is not valid JavaScript syntax. Objects are structured as { key: value }, it would need be a colon ":" character between the key and value rather than a equal sign "=" like in C# Object Initialization. Having the "=" will cause errors in your Angular application.
Hopefully that helps!
This works:
<select (change)="updateSearchResults()" #ddlAuthor>
<option *ngFor="let author of blogSearchMetadata.Authors">{{author.Value}}</option>
</select>