Reputation: 2387
I am using KnockoutJS to render a Select control but to do so I am using the ko foreach binding rather than the options binding. The Select area currently looks like this:
<select class="form-control" data-bind="value: selectedItem">
<option>-- Select an Item --</option>
<!-- ko foreach: groups -->
<optgroup data-bind="attr: { label: name }, foreach: items">
<option data-bind="text: name, option: $data"></option>
</optgroup>
<!-- /ko -->
</select>
So why am I not using the options binding? The reason is because I need to send back 2 values to the server rather than just one, where just using the value field would not be enough. So underneath this control I have 2 hidden fields that looks like this:
<input type="hidden" name="Model.SelectItemId" data-bind="value: selectedItem().itemId" />
<input type="hidden" name="Model.SelectedItemTypeId" data-bind="value: selectedItem().itemTypeId" />
This all works fine, renders as expected and passes the correct values to the server. However now I want to ability to set a default value on the select field based on a value passed into the page, and I can't seem to get this to work.
I've tried setting a value in the observable on the model like this:
function ViewModel() {
...
this.groups = ko.observable(getGroups());
// Set selected to a hardcoded item just for now to test
this.selectedItem = ko.observable(this.groups()[0].items[1]);
}
This unfortunately doesn't make a difference since when the page renders it still shows the default -- Select an Item -- option in the control and the 2 hidden fields still have a value of 0. Note however that when I remove the select control from the view and render the page the 2 hidden fields do have the default item values set so it's as if the select control is resetting the selected item back to the first default item.
I've also tried setting an afterRender on the select control and the ko foreach so that I can set the selected item that way after knockout has finished rendering, but I run into the same issue and nothing has changed.
Any help on this issue would be much appreciated. Please let me know if you want me to go into more detail on a certain area to help resolve the issue.
Upvotes: 0
Views: 2378
Reputation: 245
I have a few comments:
ViewModel.groups should be an observableArray.
Try adding a non-observable defaultItem parameter to your ViewModel:
function ViewModel() {
this.groups = ko.observableArray(getGroups());
this.selectedItem = ko.observable();
this.defaultItem = this.groups()[0].items[1];
}
An 'option' (singular) binding doesn't exist. Update your binding on the options element, changing 'option' to 'value', and add this 'attr' component:
<option data-bind="text: name,
value: $data,
attr: { selected: ($data === $parents[1].defaultItem ? 'selected' : null) }">
</option>
Upvotes: 2