2
votes

I've created a knockoutjs application using AMD. Currently I'm kinda stuck with validation. Here's the ViewModel code:

define(['knockout', 'hasher', 'text!./login-window.html'],
    function (ko, hasher, templateMarkup) {
    'use strict';

    function LoginWindowViewModel(params) {
        //observables
        this.properties = ko.validatedObservable({
            username: ko.observable().extend({
                required: { message: 'Please supply your user name' }
            }),
            password: ko.observable().extend({
                required: { message: 'Please supply your password' }
            })
        });
    }

    return { viewModel: LoginWindowViewModel, template: templateMarkup };

});

<div data-bind="css: { 'form-group': true, 'has-error': !properties().username.isValid() }">
    <label for="input-username" class="col-lg-3 control-label">Username</label>
    <div class="col-lg-9">
        <input type="text" name="input-username" class="form-control" data-bind="value: properties().username" />
    </div>
</div>
<div data-bind="css: { 'form-group': true, 'has-error': !properties().password.isValid() }">
    <label for="input-password" class="col-lg-3 control-label">Password</label>
    <div class="col-lg-9">
        <input type="text" name="input-password" class="form-control" data-bind="value: properties().password" />
    </div>
</div>

The problem is that on page load knockout adds has-errors class to the "wrapper divs" (those with form-group class). How can I turn on validation after user typed something into bound input?

Before you point me here: Knockout Validation evaluates immediately on load - I don't have a problem with a validation message showing up, but with div being added a class it shouldn't have at that moment.

2

2 Answers

1
votes

Try this on the binding:

css: { 'form-group': true, 'has-error': !properties().username.isValid() && properties().username.isModified() }

Basically we are checking if observable has been modified to present the error. isModified is an observable that is inserted automatically by ko validation.

If something in your view model is actually setting the observable to empty or null, (some initialisation code for example) you then need to:

properties().username.isModified(false)

I Haven't tested it so it might need some tweaking

-1
votes

I figured out a temporary solution, but I don't like it, so anybody with a better idea - please come forward :).

this.shouldValidateUsername = ko.pureComputed(function () {
    return !this.properties().username.isValid() && this.validationIsOn();
}, this);
this.shouldValidatePassword = ko.pureComputed(function () {
    return !this.properties().password.isValid() && this.validationIsOn();
}, this);

and the interesting part of html is:

<div data-bind="css: { 'form-group': true, 'has-error': shouldValidateUsername() }">(...)

I'm switching the validationIsOn observable thus turning the validation on and off.