user3378165
user3378165

Reputation: 6916

Add titles to a list

I have a select field with a list of fees, every fee has an id, description and status- New or Old.

<select id="feesSelect" data-bind="options: $root.fees(), optionsText: 'description', optionsValue: 'feesID', value: feeID(), optionsCaption: 'Choose Fee'"></select>

The list is ordered by status.

How can I add titles to the option elements within the list, according to the status- one title: new and one: old.

I need my list to look like that:

I tried that- but it's not working:

<select id="feesSelect" data-bind="foreach: $root.fees(), value: feeID()>
      <option data-bind="value: feesID, text: description, attr: {title: status}"></option>
</select>

Upvotes: 0

Views: 87

Answers (1)

user3297291
user3297291

Reputation: 23397

Things you need to do:

  1. Split your flat list in to a nested list: groups -> fees
  2. Loop over the groups to make <optgroup> elements
  3. Loop over the fees to make <option> elements

For step 2 and 3, you can define a quick custom binding as described in this excelent answer by R.P. Niemeyer

For step 1, you'll need to loop through your list of fees and add them to a group. For example:

const feeGroups = [
  { label: "new", fees: fees.filter(f => f.type === "old") },
  { label: "old", fees: fees.filter(f => f.type === "new") }
];

You can check out a working example in the snippet below.

// From: https://stackoverflow.com/a/11190148/3297291
ko.bindingHandlers.option = {
  update: function(element, valueAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor());
    ko.selectExtensions.writeValue(element, value);
  }
};

const fees = [
  { type: "old", description: "test1" },
  { type: "old", description: "test2" },
  { type: "new", description: "test3" },
  { type: "new", description: "test4" }
];

const feeGroups = [
  { label: "new", fees: fees.filter(f => f.type === "new") },
  { label: "old", fees: fees.filter(f => f.type === "old") }
];

ko.applyBindings({ feeGroups, selectedFee: ko.observable() });
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<select data-bind="foreach: feeGroups, value: selectedFee">
    <optgroup data-bind="attr: {label: label}, foreach: fees">
        <option data-bind="text: description, option: $data"></option>
    </optgroup>
</select>

Upvotes: 1

Related Questions