Validation Form With Knockout.JS

Introduction

In this article, we will see how we can implement validation rules with knockout.js library. Client Side validation improves the performance and helps us to validate the data before saving it into the database.

As I mentioned, in this demo, we will show a form with different fields, where we are applying the validation rules. I hope, you will like this.

Let’s start.

Create your Application

Open Visual Studio and select File-> click New Project.

The New Project Window will pop up. Select ASP.NET Web Application (.NET Framework), name your project and click OK.

Knockout

Now, a new dialog will pop up to select the template. We are going to choose MVC and click OK.

Knockout

Knockout part

First of all, we are installing knockout.js library. For doing this, right click on References > Manage NuGet Packages.

Knockout

Now, type Knockout.js in search text box, select the first line, as shown below and click Install button.

Knockout

After installing Knockout.js library from Solution Explorer, make sure that JS files given below have been added, as shown below.

Knockout

Create HTML page

Now, we need to add new HTML page. To do this, right click on Project > Add > HTML page.

Knockout

EmployeeForm.html 

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <title>.: Validation Form :.</title>  
  5.   
  6.     <meta charset="utf-8" />  
  7.     <meta http-equiv="X-UA-Compatible" content="IE=edge">  
  8.     <meta name="viewport" content="width=device-width, initial-scale=1">  
  9.     <!--CSS-->  
  10.     <link href="Content/bootstrap.min.css" rel="stylesheet" />  
  11.   
  12.     <style type="text/css">  
  13.         .errorStyle{  
  14.   
  15.             background-color:#ffd800;  
  16.             color:#808080;  
  17.             font-size:13px;  
  18.             padding:5px 5px;  
  19.             border-radius:5px;  
  20.             margin-top:7px;  
  21.         }  
  22.     </style>  
  23.   
  24. </head>  
  25. <body>  
  26.   
  27.     <nav class="navbar navbar-default navbar-fixed-top">  
  28.   
  29.         <div class="container-fluid">  
  30.   
  31.             <div class="navbar-header">  
  32.                 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">  
  33.                     <span class="sr-only">Toggle navigation</span>  
  34.                     <span class="icon-bar"></span>  
  35.                     <span class="icon-bar"></span>  
  36.                     <span class="icon-bar"></span>  
  37.                 </button>  
  38.                 <a class="navbar-brand" href="#">Validation With KnockOut JS</a>  
  39.             </div> <!-- END HEADER NAV -->  
  40.   
  41.         </div> <!-- END CONTAINER -->  
  42.   
  43.     </nav><!-- END NAV-->  
  44.   
  45.     <div class="container" style="margin-top: 7%;">  
  46.   
  47.         <div class="row">  
  48.   
  49.             <div class="col-md-8">  
  50.   
  51.                 <div class="panel panel-default">  
  52.   
  53.                     <div class="panel-heading">  
  54.                         <b> Employee Form</b>  
  55.                     </div> <!-- END HEADING-->  
  56.   
  57.                     <div class="panel-body">  
  58.   
  59.                         <form>  
  60.   
  61.                             <div class="form-group">  
  62.                                 <label for="FirstName">First Name</label>  
  63.                                 <input type="text" id="FirstName" class="form-control" data-bind="value:FirstName" placeholder="First Name" />  
  64.                             </div><!-- END FIRST NAME -->  
  65.   
  66.                             <div class="form-group">  
  67.                                 <label for="LastName">Last Name</label>  
  68.                                 <input type="text" id="LastName" class="form-control" data-bind="value:LastName" placeholder="Last Name" />  
  69.                             </div><!-- END Last Name -->  
  70.   
  71.                             <div class="form-group">  
  72.                                 <label for="Email">Email</label>  
  73.                                 <input type="text" id="Email" class="form-control" data-bind="value:Email" placeholder="Email" />  
  74.                             </div><!-- END Email -->  
  75.   
  76.                             <div class="form-group">  
  77.                                 <label for="Country">Country</label>  
  78.                                 <select class="form-control" data-bind="options: CountryList, value: Country, optionsCaption:'Choose your country ...'"></select>  
  79.                             </div> <!-- END COUNTRY -->  
  80.   
  81.                             <div class="form-group">  
  82.                                 <label for="PhoneNumber">Phone Number</label>  
  83.                                 <input type="text" id="PhoneNumber" class="form-control" data-bind="value:PhoneNumber" placeholder="Phone Number" />  
  84.                             </div><!-- END Phone Number -->  
  85.   
  86.                             <div class="form-group">  
  87.                                 <label for="Address">Address</label>  
  88.                                 <input type="text" id="Address" class="form-control"data-bind="value:Address" placeholder="Address" />  
  89.                             </div><!-- END Address -->  
  90.   
  91.                             <div class="form-group">  
  92.                                 <label for="Password">Password</label>  
  93.                                 <input type="password" id="Password" class="form-control" data-bind="value:Password" placeholder="Password" />  
  94.                             </div><!-- END Password -->  
  95.   
  96.                             <div class="form-group">  
  97.                                 <label for="Password">Confirm Password</label>  
  98.                                 <input type="password" id="ConfirmPassword" class="form-control" data-bind="value:ConfirmPassword" placeholder="ConfirmPassword" />  
  99.                             </div><!-- END Confirm Password -->  
  100.   
  101.                             <div class="form-group">  
  102.                                 <label for="captcha">20 + 30</label>  
  103.                                 <input type="text" id="captcha" class="form-control" data-bind="value:captcha" placeholder="Captcha" />  
  104.                             </div><!-- END  CAPTCHA -->  
  105.   
  106.                             <button type="button" class="btn btn-success" data-bind="click:submit">  
  107.                                 <span class="glyphicon  glyphicon glyphicon-floppy-disk"  aria-hidden="true"></span> Save  
  108.                             </button>  
  109.   
  110.                             <button type="button" class="btn btn-info">  
  111.                                 <span class="glyphicon  glyphicon glyphicon-refresh"  aria-hidden="true"></span> Reset  
  112.                             </button>  
  113.                               
  114.                             <div class="alert alert-success" role="alert" style="display:none; margin-top: 10px;"> <span class="glyphicon  glyphicon glyphicon-ok-circle" aria-hidden="true"></span> Form has submitted with successful </div>  
  115.                             <div class="alert alert-danger" role="alert" style="display:none; margin-top: 10px;">  <span class="glyphicon  glyphicon glyphicon-remove-circle" aria-hidden="true"></span> Please check your submission </div>  
  116.   
  117.                         </form> <!-- END FORM-->  
  118.   
  119.                     </div> <!-- END BODY-->  
  120.   
  121.                 </div> <!-- END PANEL-->  
  122.   
  123.             </div> <!-- END COL-MD-8-->  
  124.   
  125.         </div> <!-- END ROW-->  
  126.   
  127.     </div> <!-- END CONTAINER-->  
  128.   
  129.   
  130.     <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->  
  131.     <script src="Scripts/jquery-1.10.2.min.js"></script>  
  132.     <!-- Include all compiled plugins (below), or include individual files as needed -->  
  133.     <script src="Scripts/bootstrap.min.js"></script>  
  134.   
  135.     <!--KnockOutJs librairies-->  
  136.     <script src="Scripts/knockout-2.3.0.js"></script>  
  137.     <script src="Scripts/knockout.validation.js"></script>  
  138.   
  139.   
  140.     <script type="text/javascript">  
  141.   
  142.         $(document).ready(function(){  
  143.           
  144.             
  145.   
  146.             ko.validation.init({  
  147.   
  148.                 registerExtenders: true,  
  149.                 messagesOnModified: true,  
  150.                 insertMessages: true,  
  151.                 parseInputAttributes: true,  
  152.                 errorClass:'errorStyle',  
  153.                 messageTemplate: null  
  154.   
  155.             }, true);  
  156.   
  157.             // Captcha Function  
  158.             var captcha = function(val){  
  159.                 return val == 50;  
  160.             }  
  161.   
  162.             //checkPassword Function  
  163.             var checkPassword = function(val, other){  
  164.                 return val == other;  
  165.             }  
  166.   
  167.             var viewModel ={  
  168.   
  169.                 //var self = this;  
  170.   
  171.                 FirstName: ko.observable().extend({ required: true, minLength: 2, maxLength:17}),  
  172.                 LastName : ko.observable().extend({ required: true, minLength: 2, maxLength:17}),  
  173.                 Email : ko.observable().extend({email: true}),  
  174.                 CountryList: ko.observableArray(['Morocco','India','USA']),  
  175.                 Country: ko.observable().extend({ required: true}),  
  176.                 PhoneNumber: ko.observable().extend({  
  177.                     required: true,  
  178.                     pattern: {  
  179.                         message: 'Phone Number does not match my pattern',  
  180.                         params: '^06-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}$'  
  181.                     }  
  182.                 }),  
  183.                 Address: ko.observable().extend({required : true}),  
  184.                 Password: ko.observable().extend({ required: true }),  
  185.                 captcha: ko.observable().extend({  
  186.                   
  187.                     //custom Validation  
  188.                     validation:{  
  189.                         validator: captcha,  
  190.                         message: 'Please check your captcha !!'  
  191.                     }    
  192.                 }),  
  193.                 submit : function(){  
  194.                     $('div.alert-success').hide();  
  195.                     $('div.alert-danger').hide();  
  196.                     if(viewModel.errors().length === 0){  
  197.                         //alert('Thank you');  
  198.                         $('div.alert-success').show();  
  199.                     }else{  
  200.                         //alert('Please check your submission');  
  201.                         $('div.alert-danger').show();  
  202.                     }  
  203.                       
  204.                 }  
  205.                   
  206.   
  207.             };  
  208.   
  209.             //Confirm Password  
  210.             viewModel.ConfirmPassword = ko.observable().extend({  
  211.   
  212.                 validation: {  
  213.                     validator: checkPassword,  
  214.                     message: 'Please check your password !',  
  215.                     params: viewModel.Password  
  216.                 }  
  217.   
  218.             })  
  219.            //Catch errors  
  220.             viewModel.errors = ko.validation.group(viewModel);  
  221.             ko.applyBindings(viewModel);  
  222.   
  223.   
  224.         });  
  225.   
  226.   
  227.     </script>  
  228.   
  229.   
  230. </body>  
  231. </html>   

Adding validation to an observable

In order to apply the validation rules, we have used extenders but before we proceed, please make sure that you have added the libraries given below in your HTML page. 

  1. <!--KnockOutJs librairies-->  
  2.     <script src="Scripts/knockout-2.3.0.js"></script>  
  3.     <script src="Scripts/knockout.validation.js"></script>   

As you can see, ko.validation.init({ … }) function must be initialized with the options given below.

  • registerExtenders: registers custom validation rules defined via ko.validation.rules.
  • messagesOnModified: indicates whether the validation messages are triggered only when the properties are modified or not at all times.
  • insertMessages: If true validation will insert either a <span> element or the template specified by messageTemplate after any element (e.g. <input>), which uses a KO value binding with a validated field.
  • parseInputAttributes: indicates whether to assign the validation rules to your ViewModel, using HTML5 validation attributes.
  • errorClass: defines CSS class assigned to both <input> and validation message elements.

CSS code

  1. <style type="text/css">  
  2.         .errorStyle  
  3.          {  
  4.   
  5.             background-color:#ffd800;  
  6.             color:#808080;  
  7.             font-size:13px;  
  8.             padding:5px 5px;  
  9.             border-radius:5px;  
  10.             margin-top:7px;  
  11.          }  
  12.     </style>   

The next step is that we can validate our model properties by using extend ({….}) function, as shown below.

FirstName property

We want to add an extender, which allows an observable to be marked as required and having minLength: 2 characters and maxLength: 17 characters.
  1. FirstName: ko.observable().extend({ required: true, minLength: 2, maxLength:17})  
PhoneNumber property

Adding an extender that allows an observable to be required and Phone Number pattern, as shown below.
  1. PhoneNumber: ko.observable().extend({  
  2.                     required: true,  
  3.                     pattern: {  
  4.                         message: 'Phone Number does not match my pattern',  
  5.                         params: '^06-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}$'  
  6.                     }  
  7.                 })  
Captcha property

We want to implement captcha in our Form. To do this, we need to use validation: {…} object, then we are adding two parameters, as given below.
  • Validator : calls captcha function, which is already defined.
  • Message : accepts the string message, which will be displayed, if the error has occurred.
    1. // Captcha Function  
    2.             var captcha = function(val){  
    3.                 return val == 50;  
    4.             }  
    5.   
    6.             captcha: ko.observable().extend({  
    7.                   
    8.                     //custom Validation  
    9.                     validation:  
    10.                     {  
    11.                         validator: captcha,  
    12.                         message: 'Please check your captcha !!'  
    13.                     }    
    14.                 })  
ConfirmPassword property

Also, we are using the validation object, which needs the parameters given below.
  • Validator : accepts function as a parameter, which will compare the password.
  • Message : accepts the string message, which will be displayed, if the error has occurred.
  • params : provides the password field, which will be compared.
    1. //checkPassword Function  
    2.        var checkPassword = function(val, other){  
    3.                 return val == other;  
    4.          }  
    5.   
    6.              viewModel.ConfirmPassword = ko.observable().extend({  
    7.   
    8.                 validation: {  
    9.                     validator: checkPassword,  
    10.                     message: 'Please check your password !',  
    11.                     params: viewModel.Password  
    12.                 }  
    13.   
    14.               })  

Output

Now, you can run our demo by pressing F5.

Let’s see the output.

Knockout

Please share your feedback and queries in comments box.

Up Next
    Ebook Download
    View all
    Learn
    View all