Reputation: 1666
I'm attempting to use the manual select value binding to get the id of the object that's been selected, but I'm finding that it doesn't populate unless given an explicit value. Here's an example:
<div id="container">
<select data-bind="value: selectedOption">
<!-- notice the explicit value of 0 given below... why is that necessary to get selectedOption to be populated when bound? -->
<option value="0" data-bind="value: initialSelectedOptionId, text: 'initially selected option'"></option>
<!-- ko foreach: options -->
<option data-bind="value: id, text: name"></option>
<!-- /ko -->
</select>
<span data-bind="text: selectedOption"></span>
var viewModel = {
options: ko.observableArray([
{id: 1, name: 'first option'},
{id: 2, name: 'second option'},
{id: 3, name: 'third option'},
{id: 4, name: 'fourth option'}
]),
selectedOption: ko.observable(),
initialSelectedOptionId: ko.observable(3)
};
ko.applyBindings(viewModel, document.getElementById('container'));
//uncommenting the following line will initially select the correct option
//viewModel.selectedOption(viewModel.initialSelectedOptionId());
Here is the jsfiddle that shows the issue in action. Notice that the selectedOption property is populated when it's explicit, but not when it's done with a binding. Is this behavior a bug? If not, what is the reasoning behind the decision?
Upvotes: 2
Views: 212
Reputation: 331
I have updated one of the fiddle answers to a cleaner code. I don't see the need of using foreach in the options tag
<div id="container">
<select data-bind="value: selectedOption, options: options, optionsText: 'name'">
</select>
<span data-bind="text: selectedOption().name"></span>
It's also using both options and optionsText for the select tag
Upvotes: 0
Reputation: 1519
Does this behave how you expect it to?
<div id="container">
<select data-bind="value: selectedOption">
<!-- notice the explicit value of 0 given below... why is that necessary to get selectedOption to be populated when bound? -->
<option data-bind="value: initialSelectedOptionId, text: 'initially selected option'"></option>
<!-- ko foreach: options -->
<option data-bind="value: id, text: name"></option>
<!-- /ko -->
</select>
<span data-bind="text: selectedOption"></span>
var viewModel = {
options: ko.observableArray([
{id: 1, name: 'first option'},
{id: 2, name: 'second option'},
{id: 3, name: 'third option'},
{id: 4, name: 'fourth option'}
]),
selectedOption: ko.observable(3),
initialSelectedOptionId: ko.observable(0)};
ko.applyBindings(viewModel, document.getElementById('container'));
//uncommenting the following line will initially select the correct option
viewModel.selectedOption(3);
Fiddle here to see it working.
I think the reason this isn't working without setting selectedOption after applying the binding, is because of the order that the bindings happen. The <select data-bind="value: selectedOption">
is bound first, and since no drop-down options have been bound yet KO cannot correctly apply this binding.
I tracked the value of selectedOption and found that directly after applying the binding, it was set to an empty string. I'm guessing that when it applies the bindings to the DOM, KO has then updated this value (via 2-way binding) to match the 'selected value' of the drop-down (since no items have been bound at that stage). From that point on (until you modify it of course) all bindings to selectedOption will appear blank.
Make sense?
Upvotes: 1
Reputation: 1
you need to layout your select box a bit more like this:
<div id="container">
<select data-bind="options: options, value: selectedOption">
</select>
<span data-bind="text: selectedOption"></span>
Then for your JS you only need to do this:
var viewModel = {
options: ko.observableArray([
{id: 1, name: 'first option'},
{id: 2, name: 'second option'},
{id: 3, name: 'third option'},
{id: 4, name: 'fourth option'}
]),
selectedOption: ko.observable(3),
};
ko.applyBindings(viewModel, document.getElementById('container'));
Hope that helps, this link might also be helpful for you: http://knockoutjs.com/documentation/options-binding.html
Upvotes: 0