0

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:

  • NEW --title
  • test1 --option (fee description)
  • test2 -option (fee description)
  • OLD --title
  • test3 --option (fee description)
  • test4 --option (fee description)

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>
user3297291
  • 22,592
  • 4
  • 29
  • 45
user3378165
  • 6,546
  • 17
  • 62
  • 101
  • It's not clear. You want to add `title` attribute to each `option` based on `status`? The bullet points are really confusing. For eg: *"test1 --this is a fee description"* What does this mean? – adiga Jan 02 '18 at 13:16
  • @adiga Yes, this is exactly what I want- to add a `title` attribute to each `option` based on `status`. I'll try to edit my question and to it a little bit clearer. – user3378165 Jan 02 '18 at 21:08

1 Answers1

1

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>
user3297291
  • 22,592
  • 4
  • 29
  • 45
  • Thank you very much for your answer, in the first step I'm only getting the first set of fees (new), do you have any idea what can auses that? – user3378165 Jan 02 '18 at 12:11
  • I'd need to see an example of the data and the filter you're using to group the fees. Can you create a snippet that shows what you've tried? – user3297291 Jan 02 '18 at 12:23
  • I got it to work, I get the filtered list but the titles are blank, any idea? – user3378165 Jan 02 '18 at 21:27
  • Are you passing the right property names to the label and text bindings? – user3297291 Jan 02 '18 at 21:32
  • I think so, could you give me an explanation about the `selectedFee` properrty? What it does? – user3378165 Jan 03 '18 at 08:33
  • `selectedFee` is where the selected fee object gets stored. Initially, it'll be `{ type: "new", description: "test3" }` since that's the first one in the select box list. – user3297291 Jan 03 '18 at 08:35
  • It's working perfectly, was caused by a class that was hiding it. Thanks so much! – user3378165 Jan 03 '18 at 09:54
  • How can I get to work all the other properties: `optionsValue: 'feesID', value: feeID(), optionsCaption: 'Choose Fee'`? – user3378165 Jan 03 '18 at 10:06
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162411/discussion-between-user3297291-and-user3378165). – user3297291 Jan 03 '18 at 10:07