I'm trying to data-bind to a validatedObservable but the control does not seem updatable as other knockout observables.
Fiddle here, http://jsfiddle.net/EricHerlitz/x7UUg/
Short explanation
// variable with the data bound observable
that.validationErrors = ko.validatedObservable();
// Elements to validate
var validationGroup = {
email1: that.email1,
firstName: that.firstName
};
// Trying to use the validatedObservable in a normal knockout way doesn't work
that.validationErrors(validationGroup);
// This will fill the variable with the observable result but as usual when performing this pattern the viewmodel must be rebound.
that.validationErrors = ko.validatedObservable(validationGroup);
Source
<h3>Registrering</h3>
<div class="form-group">
<label for="Email1">E-postadress</label>
<input data-bind="value: email1" id="Email1" class="form-control" placeholder="E-postadress (du kommer få lösenords-länk skickad hit)" />
</div>
<div class="form-group">
<label for="Firstname">Förnamn</label>
<input data-bind="value: firstName" id="Firstname" class="form-control" placeholder="Förnamn" />
</div>
<button type="button" class="btn btn-primary" data-bind="click: registerClick">Registrera</button>
<div class="alert alert-danger" data-bind="visible: !validationErrors.isValid()">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4>There be dragons!</h4>
<div data-bind="foreach: validationErrors.errors">
<div data-bind="text: $data"></div>
</div>
</div>
Js
var GK = GK || {};
GK.VM = GK.VM || {};
GK.VM.Member = function (template) {
/*** Private variables ***/
var that = this;
/*** Public variables ***/
that.validationErrors = ko.validatedObservable();
// variables with validation, https://github.com/Knockout-Contrib/Knockout-Validation
that.email1 = ko.observable().extend({
required: { params: true, message: "missingEmail" },
pattern: { params: /^([\d\w-\.]+@([\d\w-]+\.)+[\w]{2,4})?$/, message: "wrongEmailFormat" }
});
that.firstName = ko.observable().extend({
required: { params: true, message: "missingFirstName" }
});
that.registerClick = function () {
// Elements to validate
var validationGroup = {
email1: that.email1,
firstName: that.firstName
};
// This would be ideal but doesn't work
//that.validationErrors(validationGroup);
//console.log(that.validationErrors.errors()); // does not contain any erros
// This will destroy the data-bind but register the validatedObservable
// Requires rebinding of the control :(
that.validationErrors = ko.validatedObservable(validationGroup);
console.log(that.validationErrors.errors()); // contains errors
};
};
var viewModel = new GK.VM.Member();
ko.applyBindings(viewModel);
Any advice how to deal with this? Thanks.
Current you cannot update a validatedObservable
after it has been created without re-creating it completely.
However if you don't need this dynamic aspect of adding removing properties to it but you just need to show the collected validation messages based on criteria (when the registerClick
is called) then there are alternative solutions.
One solution would be to create the validatedObservable
normally:
that.validationErrors = ko.validatedObservable({
email1: that.email1,
firstName: that.firstName
});
Then add a new observable:
that.showErrorMessages = ko.observable();
and use that in the UI
<div class="alert alert-danger"
data-bind="visible: showErrorMessages() && !validationErrors.isValid()">
and in the registerClick
to toggle when the validation messages should be shown:
that.registerClick = function () {
that.showErrorMessages(true);
};
Demo JSFiddle.