Custom Datepicker Control Using Bootstrap and AngularJS

When we want to develop a web-based application using AngularJs, it often requires a datepicker control with some extra features like max date, min date and so on. But like classic ASP.NET, a ready-made control is not always available in the AngularJs framework. But actually, if we want to create a custom datepicker control, we can create it easily. Using this article, we will learn how to create a custom datepicker control.
 
For that, we will first open Visual Studio and create a blank ASP.NET web application. We then need to install some Nuget packages such as AngularJs, Bootstrap and Angular UI.

 
 
First we create a datepicker directory with the attributes. For this, we first create a HTML file named Date.html and the following code in that file:
  1. <div>  
  2.     <input type="text" class="form-control" style="width:{{DateParam.width}};" placeholder="{{DateParam.placeHolder}}"  
  3.            ng-model="DateParam.selectedDate" id="{{TextControlID}}" ng-disabled="DateParam.Disabled" ng-click="open($event)"  
  4.            ng-model-options="{debounce:1000}" ng-change="fnChangeDate();">  

  5.     <input type="text" class="form-control" datepicker-popup="{{DateParam.dateFormat}}" is-open="opened" min-date="DateParam.minDate" max-date="DateParam.maxDate"  
  6.            datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close"  
  7.            style="width:{{DateParam.width}}; visibility:hidden; height:0; padding:0;" ng-model="CalDate" show-weeks="DateParam.showWeeks"  
  8.            show-button-bar="DateParam.showButtonBar" year-range="DateParam.yearRange" datepicker-mode="DateParam.datepickerMode"  
  9.            starting-day="1" />  
  10.     <span class="input-group-btn" style="visibility:{{hidden}}; ">  
  11.         <button type="button" id="{{ButtonControlID}}" class="btn btn-default" ng-click="open($event)" ng-disabled="DateParam.Disabled">  
  12.             <i class="glyphicon glyphicon-calendar"></i>  
  13.         </button>  
  14.     </span>  
  15. </div>  
Now first, we need to define the Angular app as in the following:
  1. var CustomCtrlApp = angular.module('CustomCtrlApp', ['ui.bootstrap']);   
Now, in the script folder, add a JavaScript file named Date.js that is basically the controller file of the datepicker directory. In the JavaScript file, add the following code:
  1. CustomCtrlApp.directive("ngDate", ['$filter'function () {  
  2.     this;  
  3.     return {  
  4.         restrict: "EA",  
  5.         scope: {  
  6.             DateSetup: '=dateSetup'  
  7.         },  
  8.         templateUrl: '../HTMLTemplate/Date.html',  
  9.         controller: function ($scope, $element, $attrs, $filter) {  
  10.             $scope.initializeAttribute = function () {  
  11.                 $scope.DateChange = false;  
  12.                 $scope.DateParam = $scope.DateSetup;  
  13.                 $scope.TextControlID = ($scope.DateParam.Id == undefined ? 'dtp1' : $scope.DateParam.Id);  
  14.                 $scope.ButtonControlID = ($scope.DateParam.Id == undefined ? 'btn1' : $scope.DateParam.Id);  
  15.   
  16.                 if ($scope.DateParam.dateFormat == undefined) {  
  17.                     $scope.DateParam.dateFormat = 'shortDate';  
  18.                 }  
  19.   
  20.                 if ($scope.DateParam.showWeeks == undefined) {  
  21.                     $scope.DateParam.showWeeks = false;  
  22.                 }  
  23.   
  24.                 if ($scope.DateParam.showButtonBar == undefined) {  
  25.                     $scope.DateParam.showButtonBar = false;  
  26.                 }  
  27.   
  28.                 if ($scope.DateParam.showCalendarIcon == undefined) {  
  29.                     $scope.DateParam.showCalendarIcon = false;  
  30.                 }  
  31.   
  32.                 $scope.hidden = $scope.DateParam.showCalendarIcon == true ? 'visible' : 'hidden';  
  33.   
  34.                 if ($scope.DateParam.selectedDate == undefined) {  
  35.                     $scope.CalDate = $scope.FormatDate(new Date());  
  36.                     $scope.DateParam.selectedDate = '';  
  37.                 }  
  38.                 else {  
  39.                     $scope.CalDate = $scope.FormatDate($scope.DateParam.selectedDate);  
  40.                     $scope.DateParam.selectedDate = $scope.FormatDate($scope.DateParam.selectedDate);  
  41.                 }  
  42.   
  43.                 if ($scope.DateParam.width == undefined) {  
  44.                     $scope.DateParam.width = '80%';  
  45.                 }  
  46.   
  47.                 if ($scope.DateParam.minDate == undefined) {  
  48.                     $scope.DateParam.minDate = null;  
  49.                 }  
  50.   
  51.                 if ($scope.DateParam.maxDate == undefined) {  
  52.                     $scope.DateParam.maxDate = null;  
  53.                 }  
  54.   
  55.                 if ($scope.DateParam.yearRange == undefined) {  
  56.                     $scope.DateParam.yearRange = 20;  
  57.                 }  
  58.   
  59.                 if ($scope.DateParam.datepickerMode == undefined) {  
  60.                     $scope.DateParam.datepickerMode = 'day';  
  61.                 }  
  62.   
  63.             }  
  64.   
  65.             $scope.initializeMethod = function () {  
  66.                 $scope.DateParam.method = {  
  67.                     setEnabled: function (args) {  
  68.                         $scope.DateParam.Disabled = !args;  
  69.                     },  
  70.                     setMinDate: function (minDate) {  
  71.                         $scope.DateParam.minDate = minDate;  
  72.                     },  
  73.                     setMaxDate: function (maxDate) {  
  74.                         $scope.DateParam.maxDate = maxDate;  
  75.                     },  
  76.                     getMinDate: function () {  
  77.                         return $scope.DateParam.minDate;  
  78.                     },  
  79.                     getMaxDate: function () {  
  80.                         return $scope.DateParam.maxDate;  
  81.                     },  
  82.                     setSelectedDate: function (selDate) {  
  83.                         $scope.CalDate = $scope.FormatDate(selDate);  
  84.                         $scope.DateParam.selectedDate = $scope.FormatDate(selDate);  
  85.                     },  
  86.                     getSelectedDate: function () {  
  87.                         return $scope.CalDate;  
  88.                     },  
  89.                     clearSelection: function () {  
  90.                         $scope.clear();  
  91.                     }  
  92.                 };  
  93.             }  
  94.   
  95.             $scope.clear = function () {  
  96.                 $scope.CalDate = null;  
  97.                 $scope.DateParam.selectedDate = null;  
  98.             };  
  99.   
  100.             $scope.open = function ($event) {  
  101.                 $event.preventDefault();  
  102.                 $event.stopPropagation();  
  103.                 $scope.opened = true;  
  104.             };  
  105.   
  106.             $scope.$watch('CalDate'function () {  
  107.                 if ($scope.opened) {  
  108.                     $scope.opened = false;  
  109.                     $scope.DateParam.selectedDate = $scope.FormatDate($scope.CalDate);  
  110.                     $scope.DateParam.events.onDateChanged(new Date($scope.CalDate));  
  111.                 }  
  112.             });  
  113.   
  114.             $scope.$watch('DateParam.selectedDate'function () {  
  115.                 if ($scope.DateChange) {  
  116.                     $scope.opened = true;  
  117.                     $scope.CalDate = $scope.DateParam.selectedDate;  
  118.                 }  
  119.             });  
  120.   
  121.             $scope.fnChangeDate = function () {  
  122.                 $scope.DateChange = true;  
  123.             }  
  124.   
  125.             $scope.dateOptions = {  
  126.                 formatYear: 'yy',  
  127.                 startingDay: 1  
  128.             };  
  129.   
  130.             $scope.FormatDate = function (args) {  
  131.                 return $filter('date')(args, $scope.DateParam.dateFormat);  
  132.             }  
  133.   
  134.             $scope.initializeAttribute();  
  135.             $scope.initializeMethod();  
  136.         }  
  137.     }  
  138. }]);  
In the preceding code, we specify some attribute of the Datepicker control like:
  1. Width
  2. selectedDate
  3. Date Format
  4. Min Date
  5. Max Date
  6. Enabled
  7. Place Holder
  8. Show weeks
  9. Show Button Bar
Also, we defined the onDateChanged Event that is fired on the target page after date selection.

Also, we defined some methods of the datepicker control like:
  1. SetEnabled
  2. setMinDate
  3. SetMaxDate
  4. getMinDate
  5. getMaxDate
  6. getSelectedDate
  7. clearSelection
Now, we add a HTML page in the HTML folder named DateDemo.html and add the following code there:
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4.     <title>Date Demo</title>  
  5.     <script src="../RefScript/angular.min.js"></script>  
  6.     <script src="../RefScript/ui-bootstrap.min.js"></script>  
  7.     <script src="../RefScript/ui-bootstrap-tpls.min.js"></script>  
  8.     <script src="../PageScript/CustomCtrlApp.js"></script>  
  9.     <script src="../DirectiveScript/Date.js"></script>  
  10.     <script src="../PageScript/DateDemo.js"></script>  
  11.   
  12.     <link href="../RefStyle/bootstrap.min.css" rel="stylesheet" />  
  13.   
  14. </head>  
  15. <body ng-app="CustomCtrlApp">  
  16.     <div ng-controller="DateDemo">  
  17.         <table width="100%" cellpadding="0" cellspacing="0">  
  18.             <tr>  
  19.                 <td style="width:20%;">Select Date </td>  
  20.                 <td style="width:20%;">  
  21.                     <ng-date date-setup="DateArgs"></ng-date>  
  22.                 </td>  
  23.                 <td style="width:50%;">  
  24.                     <input type="button" value="On/Off" ng-click="fnToggle()" />  
  25.                     <input type="button" value="Clear" ng-click="fnClear()" />  
  26.                       
  27.                     <input type="button" value="Set Min Date" ng-click="fnSetMinDate()" />  
  28.                     <input type="button" value="Set Max Date" ng-click="fnSetMaxDate()" />  
  29.                     <input type="button" value="Set Sel Date" ng-click="fnSetSelDate()" />  
  30.   
  31.                     <input type="button" value="Get Min Date" ng-click="fnGetMinDate()" />  
  32.                     <input type="button" value="Get Max Date" ng-click="fnGetMaxDate()" />  
  33.                     <input type="button" value="Get Sel Date" ng-click="fnGetSelDate()" />  
  34.                 </td>  
  35.             </tr>  
  36.             <tr>  
  37.                 <td>{{SelectedDate}}</td>  
  38.             </tr>  
  39.         </table>  
  40.     </div>  
  41. </body>  
  42. </html>  
Now to define the datedemo controller. For this, we add another JavaScript file in the script folder named datedemo.js and add the following code:
  1. CustomCtrlApp.controller("DateDemo", ['$scope''$http''$filter',  
  2.     function ($scope, $http, $filter) {  
  3.         $scope.Heading1 = "Date Control";  
  4.   
  5.         $scope.DateArgs = {  
  6.             width: '70%',  
  7.             //selectedDate: new Date(),  
  8.             dateFormat: 'dd/MM/yyyy',  
  9.             //minDate: new Date('2010-04-14'),  
  10.             //maxDate: new Date('2015-07-24'),  
  11.             enabled: true,  
  12.             placeHolder: 'Enter DOB',  
  13.             Id: 'dtpDOB',  
  14.             showWeeks: false,  
  15.             showButtonBar: false,  
  16.             showCalendarIcon: false             
  17.         };  
  18.   
  19.         $scope.Enable = true;  
  20.   
  21.         if ($scope.DateArgs.events == undefined) {  
  22.             $scope.DateArgs.events = {};  
  23.         }  
  24.   
  25.         $scope.DateArgs.events.onDateChanged = function (args) {  
  26.             $scope.SelectedDate = $filter('date')(args, $scope.DateArgs.dateFormat);  
  27.         }  
  28.   
  29.         $scope.fnToggle = function () {  
  30.             $scope.Enable = !$scope.Enable;  
  31.             $scope.DateArgs.method.setEnabled($scope.Enable);  
  32.         }  
  33.   
  34.         $scope.fnClear = function () {  
  35.             $scope.DateArgs.method.clearSelection();  
  36.         }  
  37.   
  38.         $scope.fnGetMinDate = function () {  
  39.             alert($scope.DateArgs.method.getMinDate());  
  40.         }  
  41.   
  42.         $scope.fnGetMaxDate = function () {  
  43.             alert($scope.DateArgs.method.getMaxDate());  
  44.         }  
  45.   
  46.         $scope.fnGetSelDate = function () {  
  47.             alert($scope.DateArgs.method.getSelectedDate());  
  48.         }  
  49.   
  50.         $scope.fnSetMinDate = function () {  
  51.             $scope.DateArgs.method.setMinDate(new Date('2015-01-01'));  
  52.         }  
  53.   
  54.         $scope.fnSetMaxDate = function () {  
  55.             $scope.DateArgs.method.setMaxDate(new Date('2015-07-31'));  
  56.         }  
  57.   
  58.         $scope.fnSetSelDate = function () {  
  59.             $scope.DateArgs.method.setSelectedDate(new Date('2015-07-20'));  
  60.         }  
  61.     }]);  
Now, run the project and the output will be as in the following: