Search code examples
javascriptvalidationknockout.jsknockout-validation

KnockoutJS validate only if field is partially complete


Looking for a solution to only validating a input field if it's partially complete ie, don't validate if the user has not entered a value. http://jsfiddle.net/2H2Bv/

Would also be interested to see a solution for removing the validation summary message, "Complete missing fields below", at the top when all fields meet their validation requirements ie when all validation messages attached to each input have disappeared AND before the submit button is clicked...

HTML

<script id="customMessageTemplate" type="text/html">
    <em class="customMessage" data-bind='validationMessage: field'></em>
</script>

<!-- ko if: displayAlert -->
<p class="customMessage" data-bind="text: validationSummary"></p> <br />
<!-- /ko -->

<fieldset>
    <legend>Details</legend>
    <label>First name:
        <input data-bind='value: firstName' />
    </label>
    <label>Last name:
        <input data-bind='value: lastName' />
    </label>
    <div data-bind='validationOptions: { messageTemplate: "customMessageTemplate" }'>
        <label>Email:
            <input data-bind='value: emailAddress' required pattern="@" />
        </label>
</fieldset>
<br>
<button type="button" data-bind='click: submit'>Submit</button>
<br>
<br> <span data-bind='text: errors().length'></span> errors

JS:

ko.validation.rules.pattern.message = 'Invalid.';

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

var viewModel =  function() {
    this.firstName = ko.observable().extend({
        minLength: 2,
        maxLength: 10
    });
    this.lastName = ko.observable().extend({
        required: true
    });
    this.emailAddress = ko.observable().extend({ // custom message
        required: {
            message: 'Enter your email address.'
        }
    });
    this.validationSummary = ko.observable("Complete missing fields below:");
    this.displayAlert = ko.observable(false);
    this.submit = function () {
        if (this.errors().length == 0) {
            alert('Thank you.');
        } else {
            this.displayAlert(true);
            this.errors.showAllMessages();
        }
    };
    this.errors = ko.validation.group(this);
};

ko.applyBindings(new viewModel());

Solution

  • If I understand correctly you want the email validation to run once the user has typed something and not be "red" when the page loads.

    To do this you need to remove the required and pattern attribues so your input becomes:

    <input data-bind='value: emailAddress' />

    and to add email validation to your model so your observable becomes:

    this.emailAddress = ko.observable().extend({ // custom message
         required: {
              message: 'Enter your email address.'
         }, email:true
    });
    

    updated fiddle