I have two pages, the first is a login page, simple :
Model KnockoutJs
function Login(){
var self=this;
self.email = ko.observable().extend({ email: true, required: true });
self.password = ko.observable().extend({ required: true});
}
Model Binding
$(function () {
ko.validation.configure({
insertMessages: true,
decorateElement: true,
errorElementClass: 'validation',
messageTemplate: "ValidationTemplate",
errorsAsTitle: false
});
var login = new Login();
ko.applyBindings(login);
});
Template Definition
<script type="text/html" id="ValidationTemplate">
<span data-bind="attr: { error: field.error },
visible: field.isModified() && !field.isValid(),
event: { mouseover: layout.errorTooltip }"
class="glyphicon glyphicon-exclamation-sign f-validation-message"></span>
</script>
Everything works fine, the little icon appears over the input which gets red borders.
Then the other page, with models hierarchy :
Model KnockoutJs Parent
function Parent()
{
var self=this;
self.child= new Child();
}
Model KnockoutJs Child
function Child()
{
var self=this;
self.val1= ko.observable().extend({ required: true });
self.val2= ko.observable().extend({ required: true });
}
Model Parent Binding
$(function () {
ko.validation.configure({
insertMessages: true,
decorateElement: true,
errorElementClass: 'validation',
messageTemplate: "ValidationTemplate",
errorsAsTitle: false
});
var parent= new Parent();
ko.applyBindings(parent);
});
The inputs are in this case included in a with block
<div data-bind="with:$root.child">
...
</div>
The validation template is the same.
So, the icon does not appear but the borders, yes.
When I check the code, KnouckoutJs did not "spread" the template on each input.
The only difference is the multi models system, but not sure how it impacts the binding?
Thank you for your help.
Yoann
Ok, I found the problem, it was not linked at all with the multi model or validation template.
I was binding data like follow :
//data: JS object
self.obsProp(ko.mapping.fromJS(data));
self.obsProp().value1.extend({required:true});
self.obsProp().value2.extend({required:true});
WRONG Way, the correct way to map the data with validation :
var validationMapping = {
value1: {
create: function(options) {
return ko.observable(options.data).extend( {required: true} );
}
},
value2: {
create: function(options) {
return ko.observable(options.data).extend( {required: true} );
}
}
};
self.obsProp(ko.mapping.fromJS(data,validationMapping));
And everything works fine.
Thanks :)