with
with

Reputation: 306

Knockout css binding in a foreach

In a <ul> foreach binding, I want knockout to add a dynamic css class to each <li>.

The objects I'm binding to look like this:

{
    id: 1234,
    class: "foo",
}

I want knockout to add the class property of each item to the corresponding <li>, like so:

<ul data-bind="foreach: TheList">
    <li data-bind="css: class" />
</ul>

So that my [effective] output is like this:

<ul>
    <li class="foo" />
    <li class="bar" />
    <li class="etc" />
</ul>

I can't figure out the binding syntax. I've tried this,

<li data-bind="css: class" />

It throws an error:

Unable to parse bindings. Message: SyntaxError: Syntax error; Bindings value: css: class

I've tried this,

<li data-bind="css: $data.class" />

It throws an error:

Unable to parse bindings. Message: SyntaxError: Expected identifier; Bindings value: css: $data.class

I wrapped class in quotes to avoid js keyword conflict,

<li data-bind="css: 'class'" />

This does not throw an error, but it yields unexpected results. I'm 100% positive that "trim" is not one of the class property values of any item in the collection:

<li class="trim" data-bind="css: 'class'" __ko__1354588574237="ko3">

I don't know how or if I can use a computed in this case because AFAIK I can't pass a variable (like$index or $data) into the computed, therefore the computed can't know which item to return class for.

What is the appropriate binding syntax for this scenario, is it possible?

Solution / Workarounds

This appears to be a css: binding issue in IE8 when the property is named 'class'. Here are 3 different workarounds if you run into it:

Change the name of the field to something other than 'class' (if you have control of the source).

Or, you can modify the objects in the list so that the value is accessible from a different name, i.e.,

for (var i = 0; i < TheList.length; i++)
{
    TheList[i].safeName = TheList[i]['class'];
}

Or, you can use the attr: binding instead of the css: binding, which does not appear to suffer from the same issue and can use members called 'class' so long as they are encased in quotes:

<li data-bind="attr: { 'class': 'class' } />

Upvotes: 2

Views: 1741

Answers (1)

nathan gonzalez
nathan gonzalez

Reputation: 11987

this should work:

<ul data-bind="foreach: TheList">
    <li data-bind="css: $data['class'], text: $data['class']" />
</ul>​

i think you're running into a keyword issue with class. working jsfiddle.

Upvotes: 1

Related Questions