2

In Twitter Bootstrap for a checkbox with labels is used markup like:

<label class="checkbox">
    <input type="checkbox" value="option1">
    Option 1
</label>

Knockout standard 'text' binding for label is not working: checkbox markup simple replaces with text. I have created a custom binding:

ko.bindingHandlers['checkboxLabelText'] = {
    'update': function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if ((value === null) || (value === undefined))
            value = "";
        $(element).html($(element).html() + " " + _.escape(value));
    }
};

It works fine with inline templates,

<!-- This code works -->
<div class="accordion-inner">
    <!-- ko foreach:categories -->
    <div class="control-group">
        <div class="controls">
            <label class="checkbox" data-bind="checkboxLabelText: title">
                <input type="checkbox" data-bind="checked: checked" />
            </label>
        </div>
    </div>
    <!-- /ko -->
</div>

but not works in named templates: checkbox appears but does not have bindings.

<!-- This code does not work -->
<div class="accordion-inner" data-bind="template: {foreach: categories, name: 'checkboxEditorTemplate'}">
</div>
<script type="text/html" id="checkboxEditorTemplate">
    <div class="control-group">
        <div class="controls">
            <label class="checkbox" data-bind="checkboxLabelText: title">
                <input type="checkbox" data-bind="checked: $data.checked()" />
            </label>
        </div>
    </div>
</script>

Any help?

1 Answers1

3

As you found, the text binding will replace its contents with the specified text. In your case, I feel that a better choice is to structure your markup like:

<label class="checkbox">
    <input type="checkbox" value="option1">
    <span data-bind="text: title"></span>
</label>

With this structure, you can avoid the custom binding and achieve the same result. ​​​​​​​​​​​​​​​​

RP Niemeyer
  • 114,592
  • 18
  • 291
  • 211
  • Can I ask why that you would want to do it without the span? It is better HTML to not have elements that contain both text and other elements. – RP Niemeyer Jun 25 '12 at 14:37
  • Your current code seems fine: http://jsfiddle.net/rniemeyer/4JVRA/. You just want to bind against `checked` and not `$data.checked()` in the second example. – RP Niemeyer Jun 25 '12 at 14:44