Reputation: 1016
I am having trouble getting the selected item of a bound drop down list.
<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 choose something from the drop down list, I would like to get the text of the selection, not the value. I am very new to knockout and trying to get a handle on this. I've created a fiddle for this.
http://jsfiddle.net/voam/FjRxn/
Upvotes: 3
Views: 3319
Reputation: 720
Personally I would use @pomber's answer, with a small edit.
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-loop in computed observables.
Upvotes: 0
Reputation: 403
The simplest solution would be to remove the optionsValue binding from your element. It will then store the whole object in the observable and you can get to all of your properties.
<select data-bind="options: availableGroups, optionsText: 'Name',
value: selectedGroup, optionsCaption: 'Choose...'"></select>
Upvotes: 0
Reputation: 21
I just wanted to post a solution I've been using recently to solve this issue. It utilizes binding handlers (valueAppendText and textFromOption) and appends an observable to the observable being tracked by the drop down. This solution isn't complete, but demonstrates the idea of not using adding a computed to get the drop down text. This solution also utilizes jQuery, which could be removed, but since I use jQuery in my projects (mostly), I left it in. The jsFiddle link below demonstrates 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);
}
};
Upvotes: 2
Reputation: 3591
You can also use subscribe function on your observable selectedGroup. I have also created another observable as "selectedGroupId".
On subscribe event i assign value of GroupId to new observable "selectedGroupId"
self.selectedGroup.subscribe(function(item)
{
debugger;
self.selectedGroupId(item.GroupId);
return item.Name;
});
Please see updated Fiddle here
Upvotes: 0
Reputation: 6723
Change
<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>
Upvotes: 0
Reputation: 23980
For your original question @Pete's answer is right, but since you need to preserve GroupId as the value you could do this (modified fiddle).
First the selectedGroup
property was renamed to selectedGroupId
.
Then a new computed observable selectedGroup
was defined based on the 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;
});
Also the var self = this
was defined
Upvotes: 2