9

I want to navigate useing a dynamically generated select drop down. It doesn't appear I can do that directly, so I'd simply like to make a function call when the select changes.

To do that, I have this:

---In the template---

<select (change)="navSelected($event)">
    <option *ngFor="let button of navButtons;"
    value="button.route" >{{button.label}}</option>
</select>

suffice it to say that 'navButtons' is an array of objects that have a 'label' field.

---In the class---

navSelected(navName) {
    console.log(navName + " Clicked!");
}

This actually works fine.

I got to this point from the great help of Mark Rajcok and his answer in this older question: How can I get new selection in "select" in Angular 2?

That said, I'd like to be able to pass the selected value in the navSelected() function call. I'm unsure how to do that.

I have tried adding [ngValue]="button" on a wild guess from other searches to the option tag and then referencing the button variable in the (change) event handler (so: (change)="navSelected(button.label)" and other combos, to no avail. I've seen a lot of references to ngModel but they seem old and I'm not entirely sure they apply anymore (and I couldn't get them to work anyway in RC4).

I could probably pull some jquery or whatever out to find the select and get it's value, but that seems very rinky-dink compared to simply being able to call the function correctly.

Cœur
  • 37,241
  • 25
  • 195
  • 267
lowcrawler
  • 6,777
  • 9
  • 37
  • 79

3 Answers3

15

The value you are looking for is on the $event.target and you can get it with $event.target.value, see my example below.

navSelected($event) {
    console.log($event.target.value + " Clicked!");
}

If you are looking to get the selected text of the option you can do this

navSelected($event) {
    let selectElement = $event.target;
    var optionIndex = selectElement.selectedIndex;
    var optionText = selectElement.options[optionIndex];
    console.log(optionText + " Clicked!");
}
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
eltonkamami
  • 5,134
  • 1
  • 22
  • 30
  • After changing the binding of button.route to `{{button.route}}` that works. What if I simply wanted to get the object passed in (button), rather than a value string? – lowcrawler Jul 22 '16 at 22:12
  • 1
    if you needed a dynamic value attribute you would have to bind this way `[value]="button.route"`. – eltonkamami Jul 22 '16 at 22:15
  • So I change the binding to `[value]="button"`. (again, trying to get the object, itself). in my navSelected(navName) function I see the toString() results of the button object outputted to the console. yay. However, if I try to access the object like an object and output it's parameters: `console.log(navName.route)` I get undefined. – lowcrawler Jul 22 '16 at 22:23
  • 1
    @lowcrawler now that is like a stringified version of the object you will have to use `JSON.parse(value).route`. it makes things more complex than they need to be. if you can just stick to passing the route or label that you need – eltonkamami Jul 22 '16 at 22:26
  • Cool, thanks. Your first comments solved the direct problem I was having, and then I was just trying to learn more. Thanks for indulging me. – lowcrawler Jul 22 '16 at 22:34
1

As a shortcut for @eltonkamami 's answer, you can pass your object like this:

<select (change)="navSelected(navButtons[$event.target.selectedIndex])">
    <option *ngFor="let button of navButtons;">{{button.label}}</option>
</select>

And capture it like this:

navSelected(button: [type of navButtons]){
    console.log(button);
}
Stef Geysels
  • 1,023
  • 11
  • 27
0

Instead of $event. Try using the below typecast function.

$any($event.target).value

Which will stop the type checking in the template.

Keegs
  • 460
  • 6
  • 12