Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Knockout.js Validations With and Without a Plugin

DZone's Guide to

Knockout.js Validations With and Without a Plugin

Learn how to use Knockout.js to implement validations while using a Knockout.js plugin, or without the use of such a plugin.

· Web Dev Zone
Free Resource

Never build auth again! Okta makes it simple to implement authentication, authorization, MFA and more in minutes. Try the free developer API today! 

Here we are going to see how we can implement some basic validations using Knockout.js. As we mentioned in the headline, we are going to create validation demos in two manners.

  • Without using any plugins, our own custom way.
  • Using an existing plugin, the easy way.

If you are totally new to Knockout.js, I strongly recommend you read my previous post here, where I have shared some basics of Knockout.js. We will be using Visual Studio for our development. I hope you will like this. Now let’s begin.

Download Source Code

  • Knockout.js Validations
  • Create an HTML Page

    To work with Knockout.js, we need a page, right? Let’s create it first. Before we do that, please do not forget to install Knockout.js and jQuery from NuGet.

    Image title


    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
    </head>
    <body>
    </body>
    </html>


    Now create a JavaScipt file and include it in your page.

     <script src="Validations-Without-Plugin.js"></script> 


    Knockout.js Validation Without Using a Plugin

    Open your JS file (Validations-Without-Plugin.js), this is where we are going to write our scripts. As a first step, we need to create our view model and bind it using tje applyBindings function. 

    $(function () {
        function myViewModel(firstName, lastName, email) {
            this.txtFirstName = ko.observable(firstName);
            this.txtLastName = ko.observable(lastName);
            this.txtEmail = ko.observable(email);
        };
        ko.applyBindings(new myViewModel("Sibeesh", "Venu", "sibikv4u@gmail.com"));
    });


    Now, let's create our view.

    <!DOCTYPE html>
    <html>
    <head>
        <title>KnockOut JS Validations</title>
        <meta charset="utf-8" />
        <script src="Scripts/jquery-3.1.1.min.js"></script>
        <script src="Scripts/knockout-3.4.1.js"></script>
        <script src="Scripts/Validations-Without-Plugin.js"></script>
    
    </head>
    <body>
        <table>
            <caption>Knockout JS Validation</caption>
            <tr>
                <td>
                    First Name: <input type="text" id="txtFirstName" name="txtFirstName" data-bind='value: txtFirstName' />
                </td>
            </tr>
            <tr>
                <td>
                    Last Name: <input type="text" id="txtLastName" name="txtLastName" data-bind='value: txtLastName' />
                </td>
            </tr>
            <tr>
                <td>
                    Email: <input type="text" id="txtEmail" name="txtEmail" data-bind='value: txtEmail' />
                </td>
            </tr>
            <tr>
                <td>
                    <input type="button" value="Submit" />
                </td>
            </tr>
        </table>
    </body>
    </html>


    If you run your page, you can see the view has been updated with the values we have given in our view model (do you remember the use of observable()?)

    Image title

    So far everything is good. Now it is time to update our view model and create some extenders.

    Knockout.js extenders are the easy way to give some additional functionalities to your observables. It can be anything, in this case we are going to create some validations for our observables or our controls.

    We can create the extenders and update the view as follows:

    $(function () {
        ko.extenders.isRequired = function (elm, customMessage) {
    
            //add some sub-observables to our observable
            elm.hasError = ko.observable();
            elm.message = ko.observable();
    
            //This is the function to validate the value entered in the text boxes
    
            function validateValueEntered(valEntered) {
                elm.hasError(valEntered ? false : true);
                //If the custom message is not given, the default one is taken
                elm.message(valEntered ? "" : customMessage || "I am required �� ");
            }
    
            //Call the validation function for the initial validation
            validateValueEntered(elm());
    
            //Validate the value whenever there is a change in value
            elm.subscribe(validateValueEntered);
    
            return elm;
        };
    
        ko.extenders.isEmail = function (elm, customMessage) {
    
            //add some sub-observables to our observable
            elm.hasError = ko.observable();
            elm.message = ko.observable();
    
            //This is the function to validate the value entered in the text boxes
    
            function validateEmail(valEntered) {
                var emailPattern = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
                //If the value entered is a valid mail id, return fals or return true
                elm.hasError((emailPattern.test(valEntered) === false) ? true : false);
                //If not a valid mail id, return custom message
                elm.message((emailPattern.test(valEntered) === true) ? "" : customMessage);
            }
    
            //Call the validation function for the initial validation
            validateEmail(elm());
    
            //Validate the value whenever there is a change in value
            elm.subscribe(validateEmail);
    
            return elm;
        };
    
        function myViewModel(firstName, lastName, email) {
            this.txtFirstName = ko.observable(firstName).extend({ isRequired: "You missed First Name" });
            this.txtLastName = ko.observable(lastName).extend({ isRequired: "" });
            this.txtEmail = ko.observable(email).extend({ isEmail: "Not a valid mail id" });
        };
        ko.applyBindings(new myViewModel("Sibeesh", "Venu", "sibikv4u@gmail.com"));
    });


    Here .extend({ isRequired: “You missed First Name” }); is used for calling the extenders we just created. The first parameter is the extender name you are creating, and the second one is just a custom message. I had explained the codes with comments, if you have any issues or doubts, please feel free to pose your queries. Now it is time to update our view.

    <!DOCTYPE html>
    <html>
    <head>
        <title>KnockOut JS Validations</title>
        <meta charset="utf-8" />
        <script src="Scripts/jquery-3.1.1.min.js"></script>
        <script src="Scripts/knockout-3.4.1.js"></script>
        <script src="Scripts/Validations-Without-Plugin.js"></script>
        <style>
            .error {
                color: #D8000C;
                background-color: #FFBABA;
                font-family: cursive;
            }
            table {
                border: 1px solid #c71585;
                padding: 20px;
            }
            td {
                border: 1px solid #ccc;
                padding: 20px;
            }
        </style>
    </head>
    <body>
        <table>
            <caption>Knockout JS Validation</caption>
            <tr>
                <td>
                    First Name: <input type="text" id="txtFirstName" name="txtFirstName" data-bind='value: txtFirstName, valueUpdate: "afterkeydown"' />
                    <span class="error" data-bind='visible: txtFirstName.hasError, text: txtFirstName.message'></span>
                </td>
            </tr>
            <tr>
                <td>
                    Last Name: <input type="text" id="txtLastName" name="txtLastName" data-bind='value: txtLastName, valueUpdate: "afterkeydown"' />
                    <span class="error" data-bind='visible: txtLastName.hasError, text: txtLastName.message'></span>
                </td>
            </tr>
            <tr>
                <td>
                    Email: <input type="text" id="txtEmail" name="txtEmail" data-bind='value: txtEmail, valueUpdate: "afterkeydown"' />
                    <span class="error" data-bind='visible: txtEmail.hasError, text: txtEmail.message'></span>
                </td>
            </tr>
            <tr>
                <td>
                    <input type="button" value="Submit" />
                </td>
            </tr>
        </table>
    </body>
    </html>


    Every observable will have their own hasError and message properties. And have you noticed that we are usig valueUpdate: “afterkeydown” in each data-bind event of our control? This is for initiating validation. Now let’s run our application and see whether it is working fine or not.

    Image title

    Knockout.js Validation Using a Plugin: The Easy Way

    As we are going to use a plugin, we need to install it from the NuGet first. You can always get the plugin from here.

    Image title

    Can we create our view model now?

    $(function () {
        function myViewModel(firstName, lastName, email) {
            this.txtFirstName = ko.observable(firstName).extend({ required: true });
            this.txtLastName = ko.observable(lastName).extend({ required: false });
            this.txtEmail = ko.observable(email).extend({ email: true });
        };
        ko.applyBindings(new myViewModel("Sibeesh", "Venu", "sibikv4u@gmail.com"));
    });


    You can see that, there is only few lines of code when compared to the other file one we created. Now we can create our view.

    <!DOCTYPE html>
    <html>
    <head>
        <title>KnockOut JS Validations</title>
        <meta charset="utf-8" />
        <script src="Scripts/jquery-3.1.1.min.js"></script>
        <script src="Scripts/knockout-3.4.1.js"></script>
        <script src="Scripts/knockout.validation.js"></script>
        <script src="Scripts/Validations-Plugin.js"></script>
        <style>
            table {
                border: 1px solid #c71585;
                padding: 20px;
            }
            td {
                border: 1px solid #ccc;
                padding: 20px;
            }
        </style>
    </head>
    <body>
        <table>
            <caption>Knockout JS Validation</caption>
            <tr>
                <td>
                    First Name: <input type="text" id="txtFirstName" name="txtFirstName" data-bind='value: txtFirstName' />
                </td>
            </tr>
            <tr>
                <td>
                    Last Name: <input type="text" id="txtLastName" name="txtLastName" data-bind='value: txtLastName' />
                </td>
            </tr>
            <tr>
                <td>
                    Email: <input type="text" id="txtEmail" name="txtEmail" data-bind='value: txtEmail' />
                </td>
            </tr>
            <tr>
                <td>
                    <input type="button" value="Submit" />
                </td>
            </tr>
        </table>
    </body>
    </html>


    Please don’t forget to include the knockout.validation.js in your page. If everything is ready, run your application and see the output.

    Image title

    That’s all for today. You can always download the source code attached to see the complete code and application. Happy coding!

    References

  • Knockout JS
  • Knockout-Validation Plugin
  • See Also

  • Articles related to Knockout.js
  • Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

    Topics:
    web dev ,knockout.js ,validation

    Published at DZone with permission of Sibeesh Venu, DZone MVB. See the original article here.

    Opinions expressed by DZone contributors are their own.

    THE DZONE NEWSLETTER

    Dev Resources & Solutions Straight to Your Inbox

    Thanks for subscribing!

    Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

    X

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}