Pregunta

I have in my viewmodel for boolean properties, each tied to a checkbox. I am attempting to write a custom knockout validator that ensures at least one checkbox is checked. I've got the validator written and hooked up (i.e. it fires when a checkbox changes, and only returns false when no checkboxes are checked), but the validation message doesn't show up.

First off, here is a fiddle: http://jsfiddle.net/internetH3ro/aRS4a/10/

Here is the validator:

ko.validation.rules['requiresOneOf'] = {
    getValue: function (o) {
        return (typeof o === 'function' ? o() : o);
    },
    validator: function (val, fields) {
        var self = this;
        var result = true;
        ko.utils.arrayForEach(fields, function (field) {
            var val = self.getValue(field);
            if (val) {
                result = false;
            }
        });

        return result;
    },
    message: 'Must select one option'
};
ko.validation.registerExtenders();

Here is the view model (names changed to protect the innocent):

function ViewModel() {
    var self = this;
    self.checkboxOne = ko.observable(true);
    self.checkboxTwo = ko.observable(true);
    self.checkboxThree = ko.observable(true);
    self.checkboxFour = ko.observable(true);
    self.customValidation = ko.observable().extend({
        requiresOneOf: [self.checkboxOne, self.checkboxTwo, self.checkboxThree, self.checkboxFour]
    });
}

And the associated HTML:

<label>
    <input type="checkbox" data-bind="checked: checkboxOne" />Checkbox One
</label><br />
<label>
    <input type="checkbox" data-bind="checked: checkboxTwo" />Checkbox Two
</label><br />
<label>
    <input type="checkbox" data-bind="checked: checkboxThree" />Checkbox Three
</label><br />
<label>
    <input type="checkbox" data-bind="checked: checkboxFour" />Checkbox Four
</label>
<span data-bind="validationMessage: customValidation"></span>

I've stepped through the validator and have confirmed that when no checkboxes are checked, it returns false, however the span that should show my validation message displays nothing. I'm assuming I'm missing a step or something simple, but I can't find it. Think I've been staring at the code too long. Any help would be greatly appreciated, thanks.

UPDATE: I've noticed, though, that if I add the custom validator to a validation group, that picks up the fact that it's not valid. I've updated the fiddle to illustrate this. So my validator is working, I just can't get the darn message to display.

http://jsfiddle.net/internetH3ro/aRS4a/

¿Fue útil?

Solución

Please don't use the validation plugin from cdnjs!

Even its latest version is more than one year old and it is full of bugs, so use the latest version from github until the cdnjs version is not updated.

After you've update the validation plugin the latest version, you just need set messagesOnModified: false in your validation configuration.

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

Demo JSFiddle.

You need to do this because your observable self.customValidation never gets actually updated it only provides the validator but the plugin only display the error message if your underlying observable has been modified unless you have the messagesOnModified: false setting.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top