blog

home / developersection / blogs / implementing form validation with knockout.js

Implementing Form Validation with Knockout.js

Implementing Form Validation with Knockout.js

Ravi Vishwakarma 642 27-Jun-2024

Implementing form validation with Knockout.js involves several steps. Here's a detailed guide to help you get started:

Step 1: Setup Your Project

First, ensure you have Knockout.js included in your project. You can do this by adding the Knockout.js library to your HTML file.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Form Validation demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <!-- Link to Knockout.js library for MVVM pattern support -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
        integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.4/knockout.validation.min.js"
        integrity="sha512-b99MDNv5TqiZtPKH2UeHzDAVydmgrOJEPtaPPEF8AgV86eYyqINFI/K7/7f0+R4WNTAVv8KvvpjwfOYHv5rd5g=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  </head>
  <body>
    <div class="container">
        <!-- Your form will go here -->
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  </body>
</html>

Step 2: Create Your ViewModel

Create a ViewModel that will handle the form data and validation logic. You can define your observables and validation rules in this ViewModel.

function AppViewModel() {
    var self = this;
    
    self.firstName = ko.observable('').extend({
        required: {
            message: "First name is required."
        }
    });
    
    self.lastName = ko.observable('').extend({
        required: {
            message: "Last name is required."
        }
    });

    self.email = ko.observable('').extend({
        required: {
            message: "Email is required."
        },
        email: {
            message: "Please enter a valid email address."
        }
    });

    self.password = ko.observable('').extend({
        required: {
            message: "Password is required."
        },
        minLength: {
            message: "Password must be at least 6 characters long.",
            params: 6
        }
    });

    self.confirmPassword = ko.observable('').extend({
        required: {
            message: "Confirm Password is required."
        },
        equal: {
            message: "Passwords do not match.",
            params: self.password
        }
    });

    self.errors = ko.validation.group(self);

    self.submitForm = function() {
        if (self.errors().length === 0) {
            alert('Form is valid!');
            // Proceed with form submission logic
        } else {
            self.errors.showAllMessages();
        }
    };
}

ko.applyBindings(new AppViewModel());

Step 3: Setup Knockout Validation

You'll need to include the Knockout Validation library to use the validation rules. Add the following script to your HTML:

// Initialize Knockout validation
ko.validation.init({
    registerExtenders: true, // Register custom validation rules
    messagesOnModified: true, // Show validation messages as soon as a field is modified
    insertMessages: true, // Insert validation messages next to the input elements
    parseInputAttributes: true, // Parse HTML5 input attributes for validation rules
    errorClass: 'text-danger fw-semibold', // CSS class for validation error messages
    messageTemplate: null // Use default message template
}, true);

Step 4: Create Your HTML Form

Now, create your HTML form and bind the input fields to your ViewModel properties using the data-bind attribute.

<body>
    <form data-bind="submit: submitForm">
        <div>
            <label for="firstName">First Name:</label>
            <input type="text" id="firstName" data-bind="value: firstName">
            <span data-bind="validationMessage: firstName"></span>
        </div>
        <div>
            <label for="lastName">Last Name:</label>
            <input type="text" id="lastName" data-bind="value: lastName">
            <span data-bind="validationMessage: lastName"></span>
        </div>
        <div>
            <label for="email">Email:</label>
            <input type="email" id="email" data-bind="value: email">
            <span data-bind="validationMessage: email"></span>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" data-bind="value: password">
            <span data-bind="validationMessage: password"></span>
        </div>
        <div>
            <label for="confirmPassword">Confirm Password:</label>
            <input type="password" id="confirmPassword" data-bind="value: confirmPassword">
            <span data-bind="validationMessage: confirmPassword"></span>
        </div>
        <button type="submit">Submit</button>
    </form>
</body>

Step 5: Apply Knockout Bindings

Finally, ensure your ViewModel is bound to your HTML form. This should be done in your JavaScript file as shown in the ViewModel creation step above.

// Apply bindings
ko.applyBindings(new AppViewModel());

Combine the whole code

Here's a full example combining everything:

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Form Validation demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <!-- Link to Knockout.js library for MVVM pattern support -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
        integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.4/knockout.validation.min.js"
        integrity="sha512-b99MDNv5TqiZtPKH2UeHzDAVydmgrOJEPtaPPEF8AgV86eYyqINFI/K7/7f0+R4WNTAVv8KvvpjwfOYHv5rd5g=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <style type="">
        *, :root{
            font-size: medium;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="mt-4">
            <h5 class="fw-bold">Form Validation</h5>
            <hr />
        </div>
        <form class="row g-3" data-bind="submit: submitForm">
            <div class="col-12 col-md-6">
                <label class="fw-bold form-label" for="firstName">
                    First Name
                    <span class="fw-bold text-danger ms-1" data-bind="visible: isRequired('firstName')">*</span>
                </label>
                <input type="text" id="firstName" data-bind="value: firstName" class="form-control">
                <!-- <span data-bind="validationMessage: firstName"></span> -->
            </div>
            <div class="col-12 col-md-6">
                <label class="fw-bold form-label" for="lastName">
                    Last Name<span class="fw-bold text-danger ms-1"
                        data-bind="visible: isRequired('lastName')">*</span></label>
                <input type="text" id="lastName" data-bind="value: lastName" class="form-control">
                <!-- <span data-bind="validationMessage: lastName"></span> -->
            </div>
            <div class="col-12">
                <label class="fw-bold form-label" for="email">
                    Email
                    <span class="fw-bold text-danger ms-1" data-bind="visible: isRequired('email')">*</span>
                </label>
                <input type="email" id="email" data-bind="value: email" class="form-control">
                <!-- <span data-bind="validationMessage: email"></span> -->
            </div>
            <div class="col-12 col-md-6">
                <label class="fw-bold form-label" for="password">
                    Password
                    <span class="fw-bold text-danger ms-1" data-bind="visible: isRequired('password')">*</span>
                </label>
                <input type="password" id="password" data-bind="value: password" class="form-control">
                <!-- <span data-bind="validationMessage: password"></span> -->
            </div>
            <div class="col-12 col-md-6">
                <label class="fw-bold form-label" for="confirmPassword">
                    Confirm Password
                    <span class="fw-bold text-danger ms-1" data-bind="visible: isRequired('confirmPassword')">*</span>
                </label>
                <input type="password" id="confirmPassword" data-bind="value: confirmPassword" class="form-control">
                <!-- <span data-bind="validationMessage: confirmPassword"></span> -->
            </div>
            <div>
                <button class="btn btn-primary" type="submit">Submit</button>
            </div>
        </form>
    </div>
    <script type="text/javascript">

        // Initialize Knockout validation
        ko.validation.init({
            registerExtenders: true, // Register custom validation rules
            messagesOnModified: true, // Show validation messages as soon as a field is modified
            insertMessages: true, // Insert validation messages next to the input elements
            parseInputAttributes: true, // Parse HTML5 input attributes for validation rules
            errorClass: 'text-danger fw-semibold', // CSS class for validation error messages
            messageTemplate: null // Use default message template
        }, true);

        function AppViewModel() {
            var self = this;

            self.firstName = ko.observable('').extend({
                required: {
                    message: "First name is required."
                }
            });

            self.lastName = ko.observable('');

            self.email = ko.observable('').extend({
                required: {
                    message: "Email is required."
                },
                email: {
                    message: "Please enter a valid email address."
                }
            });

            self.password = ko.observable('').extend({
                required: {
                    message: "Password is required."
                },
                minLength: {
                    message: "Password must be at least 6 characters long.",
                    params: 6
                }
            });

            self.confirmPassword = ko.observable('').extend({
                required: {
                    message: "Confirm Password is required."
                },
                equal: {
                    message: "Passwords do not match.",
                    params: self.password
                }
            });

            self.errors = ko.validation.group(self);

            //Using knockout
            self.isRequired = function (observable) {
                if (ko.isObservable(self[observable])) {
                    let rules = self[observable].rules();
                    return rules.some(function (rule) {
                        return rule.rule === 'required';
                    });
                }
                return false;
            };

            //using javascript
            // self.isRequired = function(observable) {
            //     if (self.hasOwnProperty(observable)) {
            //         let rules = self[observable].rules();
            //         return rules.some(function(rule) {
            //             return rule.rule === 'required';
            //         });
            //     }
            // };

            self.submitForm = function () {
                if (self.errors().length === 0) {
                    alert('Form is valid!');
                    // Proceed with form submission logic
                    self.errors.showAllMessages(false);
                } else {
                    self.errors.showAllMessages();
                }
            };
        }

        ko.applyBindings(new AppViewModel());
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
        crossorigin="anonymous"></script>
</body>

</html>

Output -

Implementing Form Validation with Knockout.js

Read more

Client-Side vs. Server-Side Validation: When to Use Each in Knockout.js

Integrating Knockout.js with RESTful APIs

Product Drag and Drop with Knockout

Getting Started with Templates in Knockout.js


Ravi Vishwakarma

Software Developer

Hi, my self Ravi Vishwakarma. I have completed my studies at SPICBB Varanasi. now I completed MCA with 76% form Veer Bahadur Singh Purvanchal University Jaunpur. SWE @ MindStick | Software Engineer | Web Developer | .Net Developer | Web Developer | Backend Engineer | .NET Core Developer

Leave Comment

Comments

Liked By