1
votes

I am trying to populate a dropdown using knockout. The array that I use to populate the optionsText is an array of JSON objects. I need the optionsValue to be either the index of the object in the array or a sequential number.

I have the following code in my viewModel:

    self.job.submitOptionsArray = this.collection.toJSON();
    this.job.applyPreset = ko.observableArray(self.job.submitOptionsArray);

and in my view:

<select name="" id="applyPreset" data-bind="options: applyPreset, optionsText: 'name', optionsValue: '???', value: somfn"></select>

I need a solution that does not use jQuery.

3

3 Answers

1
votes

You can format your object in order to have an index according to your collection. You can do it once or every time the array changes with a manual subscription.

this.job.applyPreset = ko.observableArray(self.job.submitOptionsArray);
this.job.applyPreset.subscribe(function(arrayValue) {
    var index = 0;
    ko.utils.arrayForEach(arrayValue, function(arrayItem){
        arrayItem.index = index++;
    })
})

Use index as your optionsValue and you are set.

1
votes

Instead of using the options binding, you may find it more beneficial in your case to manually create the options with a foreach binding.

For example:

<select data-bind="value: someValue, foreach: options">
    <option data-bind="text: title, attr: {value: $index()}"></option>
</select>
<div data-bind="text: someValue"></div>

Your options can be anything, I just tested it with this:

self.options = ko.observableArray([{
   title: "Some text",
   otherData: "someOtherData",
   evenMore: "even more Data"
 }, {
   title: "Some text 2",
   otherData: "someOtherData",
   evenMore: "even more Data"
 }, {
   title: "Some text 2",
   otherData: "someOtherData",
   evenMore: "even more Data"
 }]);

If you want to include a caption, just move the foreach binding into a virtual element and add one option manually above the rest.

0
votes

You will have to fix that yourself, the optionsValue can only point to a member on the object. If you do not supply the optionsValue the value will be the object itself.

If the object has an id member use that, or use a computed observable with a write method that writes the actual index instead of the object a underlying observable..