Dawood Awan
Dawood Awan

Reputation: 7348

Checkbox List Not working in Knockout JS

I am new to Knockout. I am trying to create a List of Checkboxes, I followed the Answer here:

Working with a list of checkboxes in knockoutjs

But I am getting an error when trying to Bind the CHECKED Property of the Checkboxes.

The HTML:

<ul data-bind="template: { name: 'choiceTmpl', foreach: EnquiryTypeList, templateOptions: { selections: SelectedEnquiryTypes } }"></ul>

<script id="choiceTmpl" type="text/html">
    <li>
        <input type="checkbox" data-bind="attr: { value: $data.Id }, checked: SelectedEnquiryTypes" />
        <span data-bind="text: $data.Text"></span>
    </li>
</script>

The JavaScript:

var viewModel = {
    EnquiryTypeList: [new EnquiryType(1, "Text 1"), new EnquiryType(2, "Text 2")],
    SelectedEnquiryTypes: ko.observableArray()

};

function EnquiryType(id, text){
    Id = id,
    Text = text
};

ko.applyBindings(viewModel);

It works when I put 1 or 0 in place of checked: SelectedEnquiryTypes

<ul data-bind="template: { name: 'choiceTmpl', foreach: EnquiryTypeList, templateOptions: { selections: SelectedEnquiryTypes } }"></ul>

<script id="choiceTmpl" type="text/html">
    <li>
        <input type="checkbox" data-bind="attr: { value: $data.Id }, checked: 1" />
        <span data-bind="text: $data.Text"></span>
    </li>
</script>

Upvotes: 0

Views: 248

Answers (4)

Dawood Awan
Dawood Awan

Reputation: 7348

Just in case someone else comes across this problem I am posting the Solution that worked for me:

<div id="EnquiryType" class="collapse col-md-12">
    <ul data-bind="foreach: Items" class="list-inline">
       <li>
           <input type="checkbox" data-bind="attr: { value: Id }, checked: Checked" />
            <span data-bind="text: Text"></span>
       </li>
    </ul>
</div>

On Server Side I created a class Called: CheckBoxViewModel

    public class CheckBoxViewModel
    {
        public int Id { get; set; }
        public string Text { get; set; }
        public bool Checked { get; set; }
    }

In My ViewModel Passed a List<CheckBoxViewModel> to the View,

public class ViewModel{

public List<CheckBoxViewModel> Items {get;set;}
}

In the Knockout used the Mapping Plugin to Map ViewModel:

var defaultModel = @Html.Raw(Json.Encode((CreateQuoteViewModel)Model));

var model = ko.mapping.toJS(defaultModel);

ko.applyBindings(model);

So basically I edited my Logic to use: @Thalsan's Answer.

Upvotes: 0

webketje
webketje

Reputation: 11006

  1. templateOptions has been deprecated for a while. Make sure the documentation you read is up to date.
  2. Knockout bindings work with object properties, not private variables. Eg, instead of Id = id, do this.Id = id.
  3. In your checked binding, you're setting selectedEnquiryTypes, which is an array. The binding only works with booleans/ values that can evaluate to booleans (eg 0,1).

For this purpose, add a selected property to every enquiryType, and filter the selected items in a computed, as in @Skaiol's fiddle.

Upvotes: 0

Skaiol
Skaiol

Reputation: 300

I think you should use ko.computed. Here's the example: http://jsfiddle.net/7ac8v0wa/5/

Upvotes: 5

Thalsan
Thalsan

Reputation: 5700

Not sure what you are trying. To show the text when the checkbox is clicked you can use the following.

HTML:

<ul data-bind="foreach: EnquiryTypeList">

    <li>
        <input type="checkbox" data-bind="attr: { value: Id }, checked: Check" />
        <!-- ko if: Check -->
        <span data-bind="text: Text"></span>
        <!-- /ko -->
    </li>

</ul>

JavaScript:

var viewModel = {
    EnquiryTypeList: ko.observableArray([new EnquiryType(1, "Text 1"), new EnquiryType(2, "Text 2")]),
};

function EnquiryType(id, text){
    this.Id = ko.observable(id),
    this.Text = ko.observable(text),
    this.Check = ko.observable(false);
};

ko.applyBindings(viewModel);

To observe the elements within the EnquiryType, you have to make them observable as well. Since you want to keep track of the list, that is the one that should be the observableArray. To check if the checkbox is checked, just simply add a boolean observable within your EnquiryType.

Upvotes: 1

Related Questions