Search code examples
javascriptdata-bindingwindows-8.1windows-phone-8.1winjs

Databind to className winjs


I have a repeater containing a button. The button's class should be set based on it's status.

How would I go about databinding the State: property to a CSS className?

DATA

items = new WinJS.Binding.List([
    {
        JobOperations: [
            { AccountType: "Internal", Index: 1, Requirements: "Do something to something else", Rework: true, State: "onHold", LoadHours: "5.7" },
            { AccountType: "Retail", Index: 2, Requirements: "Watch something for a duration of time", Rework: true, State: "complete", LoadHours: "2.1" }
        ]
    }
]);

HTML & BINDINGS

<div id="rptOperations" data-win-control="WinJS.UI.Repeater" class="buttonList operationsList" data-win-options="{data: items}">
    <button data-win-bind="className: State" class="button">
        <span data-win-bind="textContent: Index" class="index">1/span>
        <span data-win-bind="textContent: Requirements" class="requirements"></span>
        <span data-win-bind="textContent: AccountType" class="accountType"></span>
        <span data-win-bind="textContent: LoadHours" class="loadHours"></span>
    </button>
</div>

Desired Output

(Note the classes onHold and complete on the buttons)

<div id="rptOperations" class="buttonList operationsList">
    <button class="button onHold">
        <span class="index">1</span>
        <span class="requirements">Do something to something else</span>
        <span class="accountType">Internal</span>
        <span class="loadHours">5.7</span>
    </button>
    <button class="button complete">
        <span class="index">2</span>
        <span class="requirements">Watch something for a duration of time</span>
        <span class="accountType">Retail</span>
        <span class="loadHours">2.1</span>
    </button>
</div>

The code above is a dumbed down version for this example. Everything works perfectly in the actual app up until I try to bind to className which causes the app to crash.

If I can't do it this way, what would be the best way? I've done an extensive search on google before I posted this and cannot find much on the subject.


Solution

  • It is difficult to tell without more code but I have seen people have problems in WinJS when they don't call Binding.processAll in their code

    app.onactivated = function (args) {
    
        // Other activation code ...
    
        var personDiv = document.querySelector('#nameSpan');
        WinJS.Binding.processAll(personDiv, person);
        var bindingSource = WinJS.Binding.as(person);
    }

    In general you can resolve most of the issues referencing these two tutorials but if you feel you have gotten this all correct, we need some more code to help! Ref: http://msdn.microsoft.com/en-us/library/windows/apps/hh700358.aspx , http://msdn.microsoft.com/en-us/library/windows/apps/Hh700356.aspx

    In your case you can define a namespace and your data as follows:

     "use strict";
        WinJS.Namespace.define("MyAppData", {
            items: new WinJS.Binding.List([
               { AccountType: "Internal", Index: 1, Requirements: "Do something to something else", Rework: true, State: "onHold", LoadHours: "5.7" },
                { AccountType: "Retail", Index: 2, Requirements: "Watch something for a duration of time", Rework: true, State: "complete", LoadHours: "2.1" }
            ])
        });

    Then wire this to your controls like this:

     <div id="rptOperations" data-win-control="WinJS.UI.Repeater" class="buttonList operationsList" data-win-options="{data: MyAppData.items}">
            <button data-win-bind="className: State" class="button">
                <span data-win-bind="textContent: Index" class="index"></span>
                <span data-win-bind="textContent: Requirements" class="requirements"></span>
                <span data-win-bind="textContent: AccountType" class="accountType"></span>
                <span data-win-bind="textContent: LoadHours" class="loadHours"></span>
            </button>
        </div>