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.
source to share
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
source to share
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);
}
};
source to share
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>
source to share
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
source to share
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.
<select data-bind="options: availableGroups, optionsText: 'Name',
value: selectedGroup, optionsCaption: 'Choose...'"></select>
source to share
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.
source to share