3

I have a very simple issues, but being new to knockout I'm struggling.

I want to have a few clickable buttons that change css class and send and ajax query when pressed (they can be toggled or not, basically)

Here's my knockout view:

function addStuffViewModel() {
    // Data
    var self = this;
    self.movement = ko.observableArray([
        { name: 'Car', isChecked: false },
        { name: 'Bus', isChecked: false },
        { name: 'Bike', isChecked: false },
         ]);

    toggleButton = function(data,event) {
            data.isChecked = true;
            alert(data.isChecked)
    }    
};

ko.applyBindings(new addStuffViewModel());

And here is the call:

<table style="text-align:center;margin:auto">
    <tr data-bind="foreach: movement">
        <td>
            <a class="btn" style="width:100%;margin:2px" data-bind="text: $data.name,
                                   css: { 'btn-success': $data.isChecked },
                                   click: function(data, event) { toggleButton(data, event) }" /></a>
        </td>
    </tr>
</table>

This alerts the fact that the isChecked has changed, but the observableArray does not register the change. I feel like I want it to be a bit more "magical" than it actually is.

I'm sure it's a grotesque mistake and people will laugh, but any help would be appreciated

1 Answer 1

3

The properties inside each object in your observable array that you want to "listen" to need to be observable as well. Typically the way to do this would be to create another ViewModel that describes those objects:

function Item(name, isChecked) {
    this.name = ko.observable(name);
    this.isChecked = ko.observable(isChecked);
}

Then update your observable array:

self.movement = ko.observableArray([
    new Item('Car', false),
    new Item('Bus', false),
    new Item('Bike', false)]);

Example: http://jsfiddle.net/CCNtR/25/


You could tighten up your code further by defining the toggleButton function on item:

function Item(name, isChecked) {
    var self = this;

    this.name = ko.observable(name);
    this.isChecked = ko.observable(isChecked);
    this.toggleButton = function () {
        self.isChecked(true);
    };
}

... and then update your view:

<a class="btn" style="width:100%;margin:2px" 
    data-bind="text: name,
    css: { 'btn-success': isChecked },
    click: toggleButton" /></a>

Example: http://jsfiddle.net/CCNtR/26/

Sign up to request clarification or add additional context in comments.

1 Comment

As I said, newbie mistake. Thanks ! I've been pulling my hair a little bit on this.. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.