2

I am coding up a dropdown list using knockout.js:

views() is an array of Objects instantiated via JSON using REST. displayName is a String attribute of these objects and is not observable. I would like to compare the displayName attribute and if it matches a certain word, I would like to apply some style to that option.

<select id="views" data-bind="
    options: views(),
    optionsText: 'displayName',
    optionsValues: 'id',
    value: selectedView,
    style: { color: ( displayName == 'some arbitrary text') ? 'red' : 'black' }
 "></select>

The dropdown works as intended when I dont add the style binding to it. I can do a simple comparision (i.e. 1 == 1) and it works (although all the options turn red). What I want to do is to compare the 'displayName' attribute to some arbitrary text. It is just a string now, containing any text, but later on this string will be called from my ViewModel.

This will allow me to set certain options in different styles, if my view model requires them to be. Any ideas?

Husman
  • 6,819
  • 9
  • 29
  • 47
  • What is the problem? Also, what is `displayName`? (is it observable?) – SLaks Jul 17 '13 at 15:02
  • views() is an array of Objects instantiated via JSON using REST. displayName is a String attribute of these objects and is not observable. I would like to compare the displayName attribute and if it matches a certain word, I would like to apply some style to that option. – Husman Jul 17 '13 at 15:08
  • The == comparision does not work at the moment. I can read displayName and it displays in the dropdown, but I am unable to compare it to another String for some reason. – Husman Jul 17 '13 at 15:09
  • Are you using jQuery as well? I can't get a fiddle to work just right because of needing Knockout AND jQuery just want to check – PW Kad Jul 17 '13 at 15:28

2 Answers2

6

The solution in my case was to use the optionsAfterRender callback:

<select id="views" data-bind="
                         options: views(),
                         optionsText: 'displayName',
                         optionsValue: 'id',
                         value: selectedView,
                         optionsAfterRender: optionsAfterRender
                      "></select>

And then in my model:

self.optionsAfterRender = function(option, view) {
            if (view.defaultView) {
                option.className = 'defaultViewHighlight';
            }
        };
Husman
  • 6,819
  • 9
  • 29
  • 47
1

You should be able to keep track of the value of the selectedView observable and test against it's displayName property. If it is possible I would recommend making displayName an observable though.

http://jsfiddle.net/p5T8V/

<select id="views" data-bind="
    options: viewers(),
    optionsText: 'displayName',
    optionsValues: 'id',
    value: selectedView,
    style: { color: ( $parent.selectedView().displayName == 'not ok') ? 'red' : 'black' } ">

<span data-bind="text: selectedView().displayName" />

Putting that span at the bottom will allow you see the value of selectedView().displayName. The reason you need to add $parent in your style is that you are binding the element to selectedView. There may be a more efficient way using something like $(this).displayName but I don't have time to make a new project and fiddle only accepts one framework

PW Kad
  • 14,953
  • 7
  • 49
  • 82
  • If you read my answer you would realize that is because it is using jQuery and I only have 1 framework loaded (knockout) – PW Kad Jul 17 '13 at 15:39
  • Interesting, I have never tried this before but I will take more of a look at it. Do you have an example illustrating this with a framework such as jQuery or Knockout? – PW Kad Jul 17 '13 at 15:48
  • kindly check http://doc.jsfiddle.net/basic/introduction.html#external-resources and http://stackoverflow.com/questions/17478396/external-resources-in-jsfiddle-adding-twitter-bootstrap-cdn – ebram khalil Jul 17 '13 at 15:53