Drop knockout
I am having trouble getting the selected item in a dropdown.
<p>
Your Group:
<select data-bind="options: availableGroups, optionsText: 'Name', optionsValue: 'GroupId', value: selectedGroup, optionsCaption: 'Choose...'"></select>
</p>
<p>
I am visible
You have chosen <span data-bind="text: selectedGroup() ? selectedGroup().Name : 'Nothing'"></span>
</p>
When I select something from the dropdown, I would like to get the selection text, not the value. I am very new to knockout and am trying to figure this out. I created a fiddle for this.
http://jsfiddle.net/voam/FjRxn/
For your original question, @Pete's answer is correct, but since you need to store the GroupId as a value, you could do this (modified fiddle) .
The property selectedGroup
was first renamed to selectedGroupId
.
Then a new calculated observable selectedGroup
was determined based on selectedGroupId
:
self.selectedGroup = ko.computed(function () {
for (var i = 0; i < groups.length; i++) {
if (groups[i].GroupId == self.selectedGroupId())
return groups[i];
}
return null;
});
Was also determined var self = this
I just wanted to post a solution I used recently to solve this problem. It uses binding handlers (valueAppendText and textFromOption) and adds an observable to the observable, tracked by the dropdown. This solution is not complete, but it demonstrates the idea of not using computed append to get the dropdown text. This solution also uses jQuery which can be removed, but since I use jQuery in my projects (mostly) I left it. Below is a jsFiddle link demonstrating the functionality.
Fiddle: http://jsfiddle.net/FjRxn/65/
Markup:
<select data-bind="options: availableGroups, optionsText: 'Name', optionsValue: 'GroupId', valueAppendText: selectedGroup, optionsCaption: 'Choose...'"></select>
<p>
I am visible
You have chosen <span data-bind="textFromOption: selectedGroup"></span>
<div>
Group Id: <span data-bind="text: selectedGroup"></span>
</div>
</p>
Binding handlers:
ko.bindingHandlers.valueAppendText = {
init: function(element, valueAccessor, allBindingsAccessor, context) {
var $element, newValueAccessor, observable, setText;
observable = valueAccessor();
observable.selectedOptionText = ko.observable(null);
newValueAccessor = function() {
return observable;
};
$element = $(element);
setText = function() {
return observable.selectedOptionText($element.find("option:selected").text());
};
setTimeout(setText, 5);
$element.change(function() {
return setText();
});
return ko.bindingHandlers.value.init(element, newValueAccessor, allBindingsAccessor, context);
},
update: function(element, valueAccessor, allBindingsAccessor, context) {
return ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, context);
}
};
ko.bindingHandlers.textFromOption = {
update: function(element, valueAccessor, allBindingsAccessor, context) {
var newValueAccessor, observable;
observable = valueAccessor();
newValueAccessor = function() {
if (ko.isObservable(observable.selectedOptionText)) {
return observable.selectedOptionText();
}
return observable();
};
return ko.bindingHandlers.text.update(element, newValueAccessor, allBindingsAccessor, context);
}
};
Edit
<select data-bind="options: availableGroups, optionsText: 'Name', optionsValue: 'GroupId', value: selectedGroup, optionsCaption: 'Choose...'"></select>
To:
<select data-bind="options: availableGroups, optionsText: 'Name', value: selectedGroup, optionsCaption: 'Choose...'"></select>
You can also use the subscribe feature on your watched selected group. I also created another observable as "selectedGroupId".
In the subscription event, set the GroupId value to the new observable "selectedGroupId"
self.selectedGroup.subscribe(function(item)
{
debugger;
self.selectedGroupId(item.GroupId);
return item.Name;
});
See the updated Fiddle here
The simplest solution would be to remove the optionsValue binding from your element. Then it will store the entire object in an observable and you can get all of your properties.
jsfiddle
<select data-bind="options: availableGroups, optionsText: 'Name',
value: selectedGroup, optionsCaption: 'Choose...'"></select>
Personally, I would use @ pomber's answer with a little editing.
self.selectedGroup = ko.computed(function(){
return ko.utils.arrayFirst(self.availableGroups(), function(grp) {
return grp.GroupId == self.selectedGroupId();
}
}, this);
I don't like using for-loops on computed observables.
Fiddle