How to set the class attribute of an <option> element via KnockoutJS

I have an HTML select element that populates through the KnockoutJS viewmodel as follows:

 <select data-bind="options: $data.answers, optionsText: function(item) { return item.text }, value: selectedAnswer, optionsCaption: 'Choose...'"></select> 

What I would like to do is set the class attribute for each option element in some way, so I get:

 <option class="someValue">12345</option> 

Can this be done in KnockoutJS? I find it difficult to find a solution to this.

EDIT:

I just tried foreach binding, as suggested by Artem, and it is very close to work as I want. But there is one problem.

There is a function on the Question object that subscribes to the SelectedAnswer observable:

this.selectedAnswer.subscribe(function (answer) {}

When I use foreach binding, subscribe() fires once for each question (it should not fire until I select the answer. I think this is due to the fact that the "Select ..." option is no longer shown) .

To bind foreach , how can I return the default text back to "Select ..." and stop the selectedAnswer.subscribe() arrow until the user selects an item, and not when this list is full.

EDIT:

OK how I did it.

In the KO model class of the viewmodel, I have a logical bindingFinished which I check inside selectedAnswer.subscribe() . If false , then we simply return from the function; if true, continue as usual.

I also add a default โ€œSelectโ€ option, adding a new Answer to the beginning of the array. The end result is that the subscription function is not executed when the data is bound, only after the user has selected an option.

Many thanks to Artyom for your help.

+4
source share
4 answers

You can use foreach binding instead of options in the select tag:

 <select data-bind="value: selectedAnswer"> <option class="someValue">Choose...</option> <!-- ko foreach: $data.answers --> <option class="someValue" data-bind="value: $data, text: text"></option> <!-- /ko --> </select> 

The fiddle works here: http://jsfiddle.net/vyshniakov/5bPWQ/1/

+4
source

You can do this with optionsAfterRender . It will call the provided function for each option element that it generated.
All you have to do is add a class to the element.

Example:

HTML

 <select class="form-control" data-bind="options: list, optionsAfterRender: addOptionClass"></select> 

Js

 this.addOptionClass = function(optionElement) { optionElement.classList.add("form-control"); }; 
+3
source

For me, the code using the selected value (selectedAnswer) gave an error after applying this fix. I fixed this by adding value="" to the default option (Select ...).

0
source

In previous answers, I just found another way to do this

  <select data-bind="foreach: yourArray"> <option data-bind="value: IdValue, text: TextValue, attr: { customAttr: anyValueField }"></option> </select> 

This works for me. I hope this helps others

0
source

Source: https://habr.com/ru/post/1447918/


All Articles