Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I bind a dynamic set of jQuery Mobile buttons using Knockout.js?

I'm using jQuery Mobile (jQM) and Knockout.js (ko) to develop an application. In this application, I need to generate a variable number of buttons that are defined by a constantly updating web service.

So, in my markup, I have:

<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
    <button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
</div>

buttonLabels is a list of short strings returned from the web service. It's defined as:

self.buttonLabels = ko.observableArray();

This all works fine when the buttons are not "jQM styled". However, when I style them using:

$("#answerPage-buttons").trigger("create");

problems arise during the update.

The issue seems to be that jQM wraps the buttons in a div (with a sibling span) to make them all nice and mobile looking. However, when the ko applies the updates via the bindings, it only removes the tags, leaving the surrounding stuff, and adds new button tags - which are then also styled by the jQM trigger call.

So, I end up with an ever-growing list of buttons - with only the last set being operational (as the previous ones are gutted by the removal of their button element, but all the styling remains).

I've managed to address this, I think, by placing the following call immediately after the observable is updated:

$("#answerPage-buttons div.ui-btn").remove();

However, my feeling is that there's probably a better approach. Is there?

like image 470
dommer Avatar asked May 01 '12 20:05

dommer


1 Answers

I found a solution.

If I surround the buttons with a div, it seems to work - e.g.

<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
    <div>
        <button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
    </div>
</div> 

I'm guessing this is because the markup added by jQM remains "inside" the markup replicated by ko. Without the div, jQM wraps the button tag, which was the immediate child of the tag that contains the ko foreach binding.

like image 130
dommer Avatar answered Nov 15 '22 07:11

dommer