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/

+3


source to share


6 answers


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

+2


source


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);
    }
  };

      

+2


source


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>

      

0


source


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

0


source


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>

      

0


source


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

0


source







All Articles