26

In html, when we click on the text or hover over the text of a radio button or checkbox, we are able to select it with the html as shown below:

<label>
<input type="checkbox" />option 1
</label>

OR

<input id="checkboxid" type="checkbox" />
<label for="checkboxid">option 1</label>

I am trying to get the same behavior with knockout, but unable to find much help on the same:

<label data-bind="text: $data.optiontext">
    <input type="checkbox" data-bind="value: $data.optionvalue, checked: $parent.selectedOptions" />
</label>

The View (or html) is below (Note the below code does not contain the above html, so when you try it you will need to make the above changes and check it):

<div data-bind="foreach: options">
    <input type="checkbox" data-bind="value: $data.optionvalue, checked: $parent.selectedOptions" />
    <label data-bind="text: $data.optiontext"></label>
</div>

<hr />

<div data-bind="text: selectedOptionsList"></div>​

Here is the view model:

var viewModel = {
    options: [
                { optiontext: 'Simple', optionvalue: "1" },
                { optiontext: 'Advanced', optionvalue: "2" }
             ],
    selectedOptions: ko.observableArray(["2"])
};

viewModel.selectedOptionsList = ko.computed(function() {
    return this.selectedOptions().join(",");
}, viewModel);

ko.applyBindings(viewModel);

Here is the jsFiddle link: http://jsfiddle.net/rupesh_kokal/AFzbY/

Kobi
  • 135,331
  • 41
  • 252
  • 292
Rups
  • 629
  • 1
  • 8
  • 19

2 Answers2

36

You can achieve the 1. version with using an extra span for the text:

<label>
    <input type="checkbox" data-bind="value: $data.optionvalue, 
           checked: $parent.selectedOptions" />
    <span data-bind="text: $data.optiontext"/>
</label>

Demo fiddle.

Or the 2. version with using the attr binding to set the id and the for attribute:

<input type="checkbox" data-bind="value: $data.optionvalue, 
       checked: $parent.selectedOptions, attr: { id: optiontext}" />    
<label data-bind="text: $data.optiontext, attr: {for: optiontext}" />

Demo fiddle

nemesv
  • 138,284
  • 16
  • 416
  • 359
  • Thanks nemesv. The first option would best suit for my task. The 2nd version won't work in my case, as I have various checkbox controls, which are created dynamically and would require to have some dynamic way to assign a unique id to the same. Is there any way we can achieve this with knockout like creating a unique id which knockout internally takes care of assigning? – Rups Dec 01 '12 at 19:22
  • 1
    There is nothing built into knockout which would take care of generating and assigning unique ids. So you need to implement this yourself: Some SO questions about id creation http://stackoverflow.com/questions/3231459/create-unique-id-with-javascript, http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript – nemesv Dec 01 '12 at 19:26
  • Thanks nemesv, would look into it. – Rups Dec 01 '12 at 20:33
  • lodash and underscore come with _.uniqueId that could be used for the id attributes. – kzh Oct 24 '13 at 14:46
  • The first option caused problems for me ... it broke IE8 for some reason. I might try the second option with unique id's but it doesn't look like it's worth the time. – goamn Jan 20 '17 at 06:11
  • Actually it is a valid solution on IE8 WITH one modification ... the must have the closing element: . Actually even if you have then it will have the same error. – goamn Jan 20 '17 at 06:42
4

Yo can even get the binding to drop the extra span-element, by using Knockouts comment-binding syntax:

<label>
<input type="checkbox" data-bind="value: $data.optionvalue, 
       checked: $parent.selectedOptions" />
<!-- ko text: $data.optiontext --><!-- /ko --></label>

This will prevent the checkbox and the span from breaking up on two lines, if used in narrow spaces.

Jesper Jensen
  • 835
  • 8
  • 16