wtjones
wtjones

Reputation: 4160

Binding issues with knockout and jQuery Mobile

UPDATE: The third bullet below ("so I tried the following" section) is the closest I have come to a fix. I think I basically need to 1) disable the button, 2) add ui-disable, 3) jqm refresh, all within the data-bind or model.

I am trying to get one of the knockout demos to run with jqm in order to build something similar in my project. It mostly works except that the submit button does not disable goes disabled but does not appear grayed out if items = 0.

If you remove jqm, the example works fine and the button turns gray. I realize that jqm can conflict with knockout due to dom manipulation so I tried the following:

Here is the fiddle I have been using to troubleshoot this: http://jsfiddle.net/wtjones/wkEgn/

What am I missing?

    <form action='/someServerSideHandler'>
    <p>You have asked for <span data-bind='text: gifts().length'>&nbsp;</span> gift(s)</p>
    <table data-bind='visible: gifts().length > 0'>
        <thead>
            <tr>
                <th>Gift name</th>
                <th>Price</th>
                <th />
            </tr>
        </thead>
        <tbody data-bind='foreach: gifts'>
            <tr>
                <td><input class='required' data-bind='value: name, uniqueName: true' /></td>
                <td><input class='required number' data-bind='value: price, uniqueName: true' /></td>
                <td><a href='#' data-bind='click: $root.removeGift'>Delete</a></td>
            </tr>
        </tbody>
    </table>

    <button data-bind='click: addGift'>Add Gift</button>
    <button data-bind='enable: gifts().length > 0' type='submit'>Submit</button>
</form>

The model code:

var GiftModel = function(gifts) {
    var self = this;
    self.gifts = ko.observableArray(gifts);

    self.addGift = function() {
        self.gifts.push({
            name: "",
            price: ""
        });       
    };

    self.removeGift = function(gift) {
        self.gifts.remove(gift);                
    };

    self.save = function(form) {
        alert("Could now transmit to server: " + ko.utils.stringifyJson(self.gifts));
        // To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.gifts);
    };
};

var viewModel = new GiftModel([
    { name: "Tall Hat", price: "39.95"},
    { name: "Long Cloak", price: "120.00"}
]);
ko.applyBindings(viewModel);

// Activate jQuery Validation
//$("form").validate({ submitHandler: viewModel.save });

Upvotes: 1

Views: 3138

Answers (1)

Rango
Rango

Reputation: 3907

Yep. If you change button properties via JS (or using KO to change these props), then you must call the refresh method to update visual styling.

$('button').button('refresh');

So I suggest to create custom binding instead of default enable that updates mobile button styling (if applied):

ko.bindingHandlers.mobileEnable = {
    update: function(el) {
        ko.bindingHandlers.enable.update.apply(el, arguments);
        $.fn.button && $(el).button('refresh');
    }
}

and...

<button data-bind='mobileEnable: gifts().length > 0' type='submit'>Submit</button>

Corrected fiddle: http://jsfiddle.net/wkEgn/2/

Upvotes: 4

Related Questions