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 a knockout.js library. For doing this, right-click on References > Manage NuGet Packages.
 
Knockout
 
Now, type Knockout.js in the search text box, select the first line, as shown below, and click the 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.   
  4.     <head>  
  5.         <title>.: Validation Form :.</title>  
  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.         <style type="text/css">  
  12.         .errorStyle {  
  13.   
  14.             background-color: #ffd800;  
  15.             color: #808080;  
  16.             font-size: 13px;  
  17.             padding: 5px 5px;  
  18.             border-radius: 5px;  
  19.             margin-top: 7px;  
  20.         }  
  21.         </style>  
  22.     </head>  
  23.   
  24.     <body>  
  25.         <nav class="navbar navbar-default navbar-fixed-top">  
  26.             <div class="container-fluid">  
  27.                 <div class="navbar-header">  
  28.                     <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">  
  29.                         <span class="sr-only">Toggle navigation</span>  
  30.                         <span class="icon-bar"></span>  
  31.                         <span class="icon-bar"></span>  
  32.                         <span class="icon-bar"></span>  
  33.                     </button>  
  34.                     <a class="navbar-brand" href="#">Validation With KnockOut JS</a>  
  35.                 </div> <!-- END HEADER NAV -->  
  36.             </div> <!-- END CONTAINER -->  
  37.         </nav><!-- END NAV-->  
  38.         <div class="container" style="margin-top: 7%;">  
  39.             <div class="row">  
  40.                 <div class="col-md-8">  
  41.                     <div class="panel panel-default">  
  42.                         <div class="panel-heading">  
  43.                             <b> Employee Form</b>  
  44.                         </div> <!-- END HEADING-->  
  45.                         <div class="panel-body">  
  46.                             <form>  
  47.                                 <div class="form-group">  
  48.                                     <label for="FirstName">First Name</label>  
  49.                                     <input type="text" id="FirstName" class="form-control" data-bind="value:FirstName" placeholder="First Name" />  
  50.                                 </div><!-- END FIRST NAME -->  
  51.                                 <div class="form-group">  
  52.                                     <label for="LastName">Last Name</label>  
  53.                                     <input type="text" id="LastName" class="form-control" data-bind="value:LastName" placeholder="Last Name" />  
  54.                                 </div><!-- END Last Name -->  
  55.                                 <div class="form-group">  
  56.                                     <label for="Email">Email</label>  
  57.                                     <input type="text" id="Email" class="form-control" data-bind="value:Email" placeholder="Email" />  
  58.                                 </div><!-- END Email -->  
  59.                                 <div class="form-group">  
  60.                                     <label for="Country">Country</label>  
  61.                                     <select class="form-control" data-bind="options: CountryList, value: Country, optionsCaption:'Choose your country ...'"></select>  
  62.                                 </div> <!-- END COUNTRY -->  
  63.                                 <div class="form-group">  
  64.                                     <label for="PhoneNumber">Phone Number</label>  
  65.                                     <input type="text" id="PhoneNumber" class="form-control" data-bind="value:PhoneNumber" placeholder="Phone Number" />  
  66.                                 </div><!-- END Phone Number -->  
  67.                                 <div class="form-group">  
  68.                                     <label for="Address">Address</label>  
  69.                                     <input type="text" id="Address" class="form-control" data-bind="value:Address" placeholder="Address" />  
  70.                                 </div><!-- END Address -->  
  71.                                 <div class="form-group">  
  72.                                     <label for="Password">Password</label>  
  73.                                     <input type="password" id="Password" class="form-control" data-bind="value:Password" placeholder="Password" />  
  74.                                 </div><!-- END Password -->  
  75.                                 <div class="form-group">  
  76.                                     <label for="Password">Confirm Password</label>  
  77.                                     <input type="password" id="ConfirmPassword" class="form-control" data-bind="value:ConfirmPassword" placeholder="ConfirmPassword" />  
  78.                                 </div><!-- END Confirm Password -->  
  79.                                 <div class="form-group">  
  80.                                     <label for="captcha">20 + 30</label>  
  81.                                     <input type="text" id="captcha" class="form-control" data-bind="value:captcha" placeholder="Captcha" />  
  82.                                 </div><!-- END  CAPTCHA -->  
  83.                                 <button type="button" class="btn btn-success" data-bind="click:submit">  
  84.                                     <span class="glyphicon  glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Save  
  85.                                 </button>  
  86.                                 <button type="button" class="btn btn-info">  
  87.                                     <span class="glyphicon  glyphicon glyphicon-refresh" aria-hidden="true"></span> Reset  
  88.                                 </button>  
  89.                                 <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>  
  90.                                 <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>  
  91.                             </form> <!-- END FORM-->  
  92.                         </div> <!-- END BODY-->  
  93.                     </div> <!-- END PANEL-->  
  94.                 </div> <!-- END COL-MD-8-->  
  95.             </div> <!-- END ROW-->  
  96.         </div> <!-- END CONTAINER-->  
  97.         <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->  
  98.         <script src="Scripts/jquery-1.10.2.min.js"></script>  
  99.         <!-- Include all compiled plugins (below), or include individual files as needed -->  
  100.         <script src="Scripts/bootstrap.min.js"></script>  
  101.         <!--KnockOutJs librairies-->  
  102.         <script src="Scripts/knockout-2.3.0.js"></script>  
  103.         <script src="Scripts/knockout.validation.js"></script>  
  104.         <script type="text/javascript">  
  105.         $(document).ready(function() {  
  106.   
  107.             ko.validation.init({  
  108.   
  109.                 registerExtenders: true,  
  110.                 messagesOnModified: true,  
  111.                 insertMessages: true,  
  112.                 parseInputAttributes: true,  
  113.                 errorClass: 'errorStyle',  
  114.                 messageTemplate: null  
  115.   
  116.             }, true);  
  117.   
  118.             // Captcha Function    
  119.             var captcha = function(val) {  
  120.                 return val == 50;  
  121.             }  
  122.   
  123.             //checkPassword Function    
  124.             var checkPassword = function(val, other) {  
  125.                 return val == other;  
  126.             }  
  127.   
  128.             var viewModel = {  
  129.   
  130.                 //var self = this;    
  131.   
  132.                 FirstName: ko.observable().extend({ required: true, minLength: 2, maxLength: 17 }),  
  133.                 LastName: ko.observable().extend({ required: true, minLength: 2, maxLength: 17 }),  
  134.                 Email: ko.observable().extend({ email: true }),  
  135.                 CountryList: ko.observableArray(['Morocco''India''USA']),  
  136.                 Country: ko.observable().extend({ required: true }),  
  137.                 PhoneNumber: ko.observable().extend({  
  138.                     required: true,  
  139.                     pattern: {  
  140.                         message: 'Phone Number does not match my pattern',  
  141.                         params: '^06-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}$'  
  142.                     }  
  143.                 }),  
  144.                 Address: ko.observable().extend({ required: true }),  
  145.                 Password: ko.observable().extend({ required: true }),  
  146.                 captcha: ko.observable().extend({  
  147.   
  148.                     //custom Validation    
  149.                     validation: {  
  150.                         validator: captcha,  
  151.                         message: 'Please check your captcha !!'  
  152.                     }  
  153.                 }),  
  154.                 submit: function() {  
  155.                     $('div.alert-success').hide();  
  156.                     $('div.alert-danger').hide();  
  157.                     if (viewModel.errors().length === 0) {  
  158.                         //alert('Thank you');    
  159.                         $('div.alert-success').show();  
  160.                     } else {  
  161.                         //alert('Please check your submission');    
  162.                         $('div.alert-danger').show();  
  163.                     }  
  164.   
  165.                 }  
  166.             };  
  167.   
  168.             //Confirm Password    
  169.             viewModel.ConfirmPassword = ko.observable().extend({  
  170.   
  171.                 validation: {  
  172.                     validator: checkPassword,  
  173.                     message: 'Please check your password !',  
  174.                     params: viewModel.Password  
  175.                 }  
  176.   
  177.             })  
  178.             //Catch errors    
  179.             viewModel.errors = ko.validation.group(viewModel);  
  180.             ko.applyBindings(viewModel);    
  181.         });  
  182.         </script>  
  183.     </body>  
  184.   
  185. </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.
  • Messageaccepts 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 a 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 the comments box.