James McConnell
James McConnell

Reputation: 2198

Knockout Validation - Validation message binding breaks when using mapping plugin

I've seen some similar questions asked on this subject, but none of them have really helped. I wanted to post this here first before opening a ticket on the GitHub project for the validation plugin in case this is a PEBKAC issue. :)

The issue is simple. I have an object that I populate from JSON and then attach validation to fields. The problem is that if I use the mapping plugin, the validationMessage binding breaks. However, if I explicitly declare every observable, it works fine. You can see a fiddle here. It's pretty self-explanatory, just check the console window when using the breaking code and you can see the error message.

Here are the basic bits of code. First, my Knockout code:

var data = {
    Name: 'test'
};

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

var ns = ns || {}; // namespace

ns.ViewModel = function () {
    var itemToBind = {},
        init = function (json) {
            // Uncomment to break;
            itemToBind = ko.mapping.fromJS(json, {}, itemToBind);

            // Uncomment to make it work
            //itemToBind.Name = ko.observable(json.Name);

            itemToBind.Name.extend({ required: { message: 'Required' } });
        };

    return {
        itemToBind: itemToBind,
        init: init
    };
}();

ns.ViewModel.init(data);
ko.applyBindings(ns.ViewModel);

And then my HTML:

<label>Name: </label>
<input type="text" data-bind="value: itemToBind.Name" />
<div class="validation-section">
    <strong>*</strong>
    <span data-bind="validationMessage: itemToBind.Name"></span>
</div>

I at first thought that my usage of the revealing module pattern was screwing things up somehow, but since it all works if I explicitly declare each observable, I threw that thought out the window.

I have seen some suggestions such as this answer about creating a validation mapping. This would be fine if my models only had a few fields, but some of my forms have upwards of 100 fields, so while that might work, it isn't feasible. And it would actually be less code to just declare each observable.

Hoping someone can either shed some light on a fix or at least confirm that this is a bug with the validation plugin, and then I can head to the GitHub project and work with the creator. Thanks.

Upvotes: 0

Views: 475

Answers (1)

James McConnell
James McConnell

Reputation: 2198

Yeah, yeah, I know, you shouldn't answer your own question, but in case this comes up in a search for someone else, this is what I did to fix it. I initially had this to map my JSON:

ko.mapping.fromJS(json);

I happened to change this line to another way of mapping I saw somewhere else (not entirely sure why I changed it, TBH), and it started working:

ko.mapping.fromJS(json, {}, itemToBind)

I'm not sure why this works, I haven't had time to dig into the details of the different method calls, but this works. So if anyone else is having this issue, there ya go!

Upvotes: 1

Related Questions