2
votes

I am trying to create a Checkbox List using Knockout and require that at least one Checkbox is checked using Knockout Validation.

The issue that I am having is that the required validation message appears multiple times, once for each option, if no checkbox is checked. How do I resolve this issue?

working example: http://jsfiddle.net/aaronhoffman/BtK3t/

The HTML

<script id="koValidationCustomMessageTemplate" type="text/html">
    <em class="text-danger" data-bind="validationMessage: field"></em>
</script>

<div class="col-sm-5" data-bind="foreach: TheCheckboxListOptions">
    <div class="checkbox">
        <label>
            <input type="checkbox" data-bind="value: $data, checked: $root.TheCheckboxListSelectedValues" /><span data-bind="text: $data"></span>
        </label>
    </div>
</div>

and the javascript

ko.validation.configure({
    registerExtenders: true,
    messagesOnModified: true,
    insertMessages: true,
    parseInputAttributes: true,
    messageTemplate: "koValidationCustomMessageTemplate"
});

var TheViewModel = {

    TheCheckboxListOptions: [
        "Option 1",
        "Option 2",
        "Option 3",
        "Option 4"
    ],

    TheCheckboxListSelectedValues: ko.observableArray().extend({
        required: { message: "At least one option is required." }
    }),

};


ko.applyBindings(TheViewModel);
2
Could you change the view model to include a computed boolean property that returns true of the number of selected is greater than 1 and write a validation against that instead of the whole array? - arb
Thanks, I am using a similar solution to that today, I am just looking for a better one. - Aaron Hoffman

2 Answers

1
votes

The errors collection generated by the knockout validation only has a single error message. However, because the observable is bound to an array of controls it displays it once per control. You can customize the validation message template to be an asterisk or empty per control, then display a validation summary above the control array. See my modified fiddle.

http://jsfiddle.net/BtK3t/2/

<script id="koValidationCustomMessageTemplate" type="text/html">
    <span style="color: Red" data-bind="if: field.isModified() && !field.isValid()">*</span>
</script>

<ul data-bind="foreach: errors, visible: showValidationSummary"
    style="display: none; margin-left: 5px; text-align: left;">
    <li style="color: Red"><span data-bind="text: $data"></span></li>
</ul>
0
votes

For this type of stuff, I usually use the jQuery validation to validation the form before submitting (post back or via AJAX). I write a custom jQuery validation rule. Here is an example:

$.validator.addMethod('required_checkbox', function(value, element) {
    var $module = $('#myCheckboxList');
    var checked = $module.find('input[type="checkbox"]:checked');
    if (checked.length === 0) {
        return false;
    } else {
        return true;
    }
});

$.validator.addClassRules('required-checkbox', { 'required_checkbox': true });

And the markup looks like:

<ul id="myCheckboxList">
    <li><input type="checkbox" name="MyCheckboxes" class="required-checkbox" value="@myList.Id"></li>
    ....
</ul>

You can validate the entire form or a part of it by doing something like this from within your Knockout viewmodel before submitting:

$('form').validate();