0

I have a SPA in which I am using Durandal / KnockoutJS with knockout.validation.js. Inside the {view}.js I have this set

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

    });

and inside one of the views I have

 <input class="input-member"
                    type="text" 
                    data-bind="value: memberno, validationOptions: { errorElementClass: 'input-validation-error' }"/>

When the view is first activated the element correctly has the style input-validation-error applied.

On subsequent loading of the view the css is not applied as I require. I can see in firebug that the input field now has this class applied input-member validationElement

I don't know where validationElement came from - but something got messed up with the knockout bindings. I have tried moving the validation config into the shell.js but the result is the same (and not a good idea anyway).

Edit:

So far looks like errorElementClass: 'input-validation-error' is not being reapplied to the element after navigation. If the field is modified-focused-cleared , the validation fires normally. validationElement is the placeholder for the errorElementClass

Update

Found this bit of info at the github site and seems to be what im after

in {view}.js

function activate() {

    vm.memberno.isModified(false);
    return true;
}

The above code seems to work for input fields but not for select fields. Another idea I'm looking at is adding a binding handler like so

    ko.bindingHandlers.validationElement = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var valueIsValid = valueAccessor().isValid();
        if (!valueIsValid) {
            $(element).addClass("input-validation-error");
        } else {
            $(element).removeClass("input-validation-error");
        }
    }
}

which works for all selects and inputs but is always on. If there's a way to deactivate this binding until the first form submit fires I think that will do it.

MikeW
  • 4,749
  • 9
  • 42
  • 83
  • Where is `ko.validation.configu ... });` called? Is this in a initialization function or the activated function? Maybe post some more code, and also this could help: [link]http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks/ – Leroy Meijer Jun 17 '13 at 14:00
  • 1
    What would trigger the binding to be re-applied? Unless there is some event or an observable change, simply navigating back to the view would not cause the binding to update. You might want to put some code in the view model's `activate` function that forces validation. – CodingGorilla Jun 17 '13 at 14:04
  • thanks @LeroyMeijer , looking to the lifecycle docs.. it looks like viewAttached() would be a candidate – MikeW Jun 18 '13 at 05:39
  • @CodingGorilla that makes sense and has probably got me closest so far, if I hit a dead end ill mark it up – MikeW Jun 18 '13 at 05:43
  • @MikeW Judging from your post, you're probably right that viweAttached() is what you're looking for. Keep in mind that if you're caching views, you'll need to configure alwaysAttachView:true on your composition binding. On another note, I've found it much easier to use jquery.validate as opposed to knockout.validation. Let me know if you want the custom binding and details on the jQuery version. – chrisjsherm Jun 18 '13 at 21:31
  • many thanks @chrisjsherm this was more an exploratory exercise of the knockout-validation project, i think you're right on jquery.validate being easier.. in this case i went with codinggorilla's suggestion – MikeW Jun 19 '13 at 12:59
  • @CodingGorilla i'll tick your answer – MikeW Jun 26 '13 at 12:15

1 Answers1

0

There needs to be a way to re-apply the binding or cause the binding to update. Try putting some code in the view model's activate function that forces validation.

CodingGorilla
  • 19,612
  • 4
  • 45
  • 65