1
votes

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:

  • Triggering style refresh in the model methods: $('button').button(); or $('.ui-page-active' ).page( 'destroy' ).page();
  • Starting the binding after pageinit. This broke the entire thing.
  • As a test, I tried a data-bind to set ui-disable instead of disabling the button. It applies the class but jqm needs a refresh somehow. Can I put code into the data-bind to do the refresh?

    <button data-bind="css: {'ui-disable': gifts().length > 0}" type='submit'>Submit</button>

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 });
1
I don't see your problem in the jsFiddle. Using the latest Chrome the Sumbit button is not clickable if I remove all the gifts... - nemesv
You are correct but I didn't realize that because the mobile style doesn't change on the button. I updated the question to reflect that. Do I need to somehow bind a handler to refresh it? - wtjones
I tried binding ui-disable as well. I updated the question to reflect this. - wtjones

1 Answers

4
votes

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/