Knockout.js - Get text selected value in a drop-down menu

Igor picture Igor · Dec 2, 2014 · Viewed 28.6k times · Source

I would like to know how to get the value of the TEXT selected from the dropdown menu, just remember that my drop down menu has the fixed data and are not populated by a "ko.observableArray ()". Any ideas?

When I select an option want to have: Value and Text selection.

<p>
    Select a car:
    <select data-bind="value: selectedValue, optionsText:???">
      <option value="volvo">Volvo</option>
      <option value="saab">Saab</option>
      <option value="mercedes">Mercedes</option>
      <option value="audi">Audi</option>
    </select>
</p>

<span data-bind="text: selectedValue"></span>
<br/>
<span data-bind="text: selectedText"></span>

My ko ViewModel:

var viewModel = {
      selectedValue : ko.observable(),
      selectedText :  ko.observable()
};

ko.applyBindings(viewModel);

See this Fiddle: JSFiddle

Answer

lante picture lante · Dec 2, 2014

I dont know if there is a possible solution with Knockout.js. I let you two possible solutions:

Solution 1

You can use a bit of native Javascript to achieve your goal:

viewModel.selectedValue = ko.observable();
viewModel.selectedText = ko.computed(function () {
    var elem = document.querySelector("select option[value=" + viewModel.selectedValue() + "]");
    return elem && elem.innerHTML;
});

As you see, you can take the "value" and use it to return the DOM element that meets your requirements. Of course you can replace select with an id, if you need it.

Check this fiddle to see it working.

Solution 2

The Knockout way of doing this is having an array with all elements to be populated:

var cars = [{ id: 'volvo', name: 'Volvo' }, { id: 'saab', name: 'Saab' }, { id: 'mercedes', name: 'Mercedes' }, { id: 'audi', name: 'Audi' }];

After that, it depends on what you need when you say "value", remember that you are binding an object, not a key/value list:

HTML:

<select data-bind="options: cars, value: selectedCar, optionsText: 'name'"></select>

And your JS:

selectedCar = ko.observable();
selectedValue = ko.computed(function () { 
    return selectedCar() && selectedCar().id; 
});
selectedText =  ko.computed(function () { 
    return selectedCar() && selectedCar().name; 
});

This way you will have separately your "value" and your "text" (better called id and name properties) into two computed observables.

See the fiddle working.