3

I have X number of dropdowns that I dynamically created using Knockout, and now I want to preselect one option per dropdown. Coincidentally, I have an observable array with X entries that correspond to the options I want selected. How can I use this array to select my options?

Example viewmodel:

function AppViewModel() {
    var self = this;
    self.array = ko.observable(["Dog","Cat"]);
}

In this example, I have two dropdowns, both of which have a "Dog" and "Cat" option. I want to select "Dog" for the first dropdown and "Cat" for the second.

Here's my HTML:

<div data-bind="foreach: array">
      <label>
        <select data-bind="options: array"></select>
      </label>
</div>
user3757174
  • 483
  • 2
  • 8
  • 17
  • If your requirements are really that simple you can use the `$index()` inside your foreach to access the selected values: http://jsfiddle.net/pvF43/ – nemesv Jun 25 '14 at 20:28
  • 1
    @nemesv this is exactly what I needed. $index() is the way to go when you need to populate based on indices of an array. Thank you! – user3757174 Jun 26 '14 at 14:33

1 Answers1

2

As per the docs you need a value binding for your selected binding.

function AppViewModel() {
    var self = this;
    self.array = ko.observable(["Dog","Cat"]);
    self.selected = ko.observable(self.array()[0]);
}

And then:

<select data-bind="options: array, value: selected "></select>

Example: http://jsfiddle.net/H6DL5/

If you've got many of these dropdowns, then you can use an array of subVMs for your result. Something like this:

function AppViewModel() {
    var self = this;
    self.array = ko.observable(["Dog", "Cat", "Weasel"]);
    self.dropDowns = ko.observableArray([
    new SubVM("Dog"),
    new SubVM("Cat")]);
}

function SubVM(selected) {
    var self = this;
    self.selected = ko.observable(selected);
}

Which you can bind like this:

<div data-bind="foreach:dropDowns">
    <select data-bind="options: $parent.array, value: selected "></select>
</div>

Now you can add as many drop-downs as you need by adding them to the dropDowns array in your parent VM.

Example: http://jsfiddle.net/H6DL5/1/

If you need different options in each drop-down, just add an array for the available options to your SubVM and bind for options that instead of the parent list.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • I have the same number of dropdowns as I do elements in the array, so I don't want to just hardcode a selected value in. – user3757174 Jun 25 '14 at 19:33
  • @user3757174: You are going to need to put the actual selected values somewhere aren't you? You could create an array of values, but better might be to create a sub VM that has the selected value. – Matt Burland Jun 25 '14 at 19:37
  • Definitely, but I won't always have 2 dropdowns—there could be many more, depending on the data passed in. Maybe I should dynamically create observables? – user3757174 Jun 25 '14 at 19:38
  • @user3757174: I'd use an array of subVMs in your ViewModel, but I'm not entirely clear where you are getting the list of options from and where you are getting the list of selected items from? Is the list of available options supposed to be the same for all drop-downs? – Matt Burland Jun 25 '14 at 19:45
  • The list of available options is the same for all drop-downs, but the list of options I want to select is something that I computed given some input from the user. – user3757174 Jun 25 '14 at 19:47