<!DOCTYPE html>
<html lang="en" ng-app="angularReusables">

<head>
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/smoothness/jquery-ui.css" />
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-controller="angular_reusables_controller">
  <nav class="navbar navbar-default" role="navigation">
    <div class="container-fluid">
      <div class="navbar-header">
        <a class="navbar-brand" href="#">AngularJS Re-usable Components</a>
      </div>
    </div>
  </nav>

  <div class="container-fluid">

    <!-- Angular, jQuery, jQuery UI Datepicker starts -->
    <h4>jQuery UI Datepicker</h4>
    <div class="component-info" role="tabpanel">
      <ul class="nav nav-tabs" role="tablist">
        <li role="presentation" class="active"><a href="#jud_about" role="tab" data-toggle="tab">About</a>
        </li>
        <li role="presentation"><a href="#jud_demo" role="tab" data-toggle="tab">Demo</a>
        </li>
        <li role="presentation"><a href="#jud_how_to_use" role="tab" data-toggle="tab">How to Use</a>
        </li>
      </ul>
      <div class="tab-content">
        <div role="tabpanel" class="tab-pane active" id="jud_about">
          <p>If you use AngularJS and jQuery UI in your application, this component will help you to implement the datepicker plugin.</p>
          <p><b>Dependencies: </b> AngularJS (>=1.2.0), jQuery (>=1.9.1), jQuery UI (>=1.9.2).</p>
          <p><b>Browser Support: </b> Chrome, Firefox, Safari, Opera, IE9+.</p>
        </div>

        <div role="tabpanel" class="tab-pane" id="jud_demo">
          <p><b>Simple Implementation:</b> It can be an optional field i.e., user can submit the form, even though the field is empty.</p>
          <datepicker data-name="date_picker_one" data-ng-model="datepicker.selected_value_one" data-title="Set date">
          </datepicker>

          <div class="clearfix">&nbsp;</div>

          <p><b>Additional Datepicker Setting:</b> You can provide additional datepicker options and methods like minDate, maxDate, etc. <a href="http://api.jqueryui.com/datepicker/" target="_blank">More information</a>
          </p>
          <datepicker data-name="date_picker_one" data-ng-model="datepicker.selected_value_three" data-settings="datepicker.add_settings" data-title="Set date" data-date-required="yes">
          </datepicker>

          <div class="clearfix">&nbsp;</div>

          <p><b>Datepicker Positioning &amp; Padding:</b> Positioning the datepicker on top right of the link.</p>
          <datepicker data-name="date_picker_one" data-ng-model="datepicker.selected_value_two" data-position="top_right" data-position-padding="20,15" data-title="Set date" data-date-required="yes">
          </datepicker>

          <div class="clearfix">&nbsp;</div>

          <p><b>Set Default Date:</b> You can provide a default date which will appear once the page is loaded.</p>
          <datepicker data-name="date_picker_two" data-ng-model="datepicker.selected_value_four" data-position="bottom_right" data-position-padding="20,15" data-title="Set date" data-date-required="yes">
          </datepicker>
        </div>

        <div role="tabpanel" class="tab-pane" id="jud_how_to_use">
          <p>Include the below scripts at the end of the HTML body.</p>
          <pre>
&lt;script src=&quot;//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js&quot;&gt;&lt;/script&gt;
</pre>
          <p>Include the CSS in the HTML head.</p>
          <pre>
&lt;style&gt;
/*-------------------AngularJS &amp; jQuery UI Datepicker starts-----------------------------*/
.datepicker-container{position: relative;padding: 6px;float: left;border-radius: 2px;margin-bottom: 8px;}
.datepicker-container.ng-invalid-datepicked{background-color: #F8C4C4;border: 1px solid #C28080;}
.datepicker-container.ng-valid-datepicked{background-color: #DDFBCD;border: 1px solid #A6C297;}
.datepicker-container .plugin{position: absolute;z-index: 1;}
.datepicker-container .date-picked{color: #5D7A4E;}
.datepicker-container .calendar-icon:before{content: &#39;Pick Date&#39;;}
/*-------------------AngularJS &amp; jQuery UI Datepicker ends-----------------------------*/
&lt;/style&gt;
</pre>
          <p>Add the below code inside the HTML body.</p>
          <pre>
&lt;datepicker 
    data-name=&quot;date_picker_two&quot; &lt;!-- Optional: It can be any name for the datepicker --&gt;
    data-ng-model=&quot;selected_value&quot; &lt;!-- Mandatory: $scope.selected_value - It will be used to hold the selected value --&gt;
    data-settings=&quot;picker_settings&quot; &lt;!-- Optional: $scope.picker_settings - Provide additional methods and options --&gt;
    data-position=&quot;bottom_right&quot; &lt;!-- Optional: Position of the datepicker. Possible values are top_left, top_right, bottom_left, bottom_right --&gt;
    data-position-padding=&quot;20,15&quot; &lt;!-- Optional: Provide additional padding for the position.--&gt;
    data-title=&quot;Set date&quot; &lt;!-- Optional: Help text on hover --&gt;
    data-date-required=&quot;yes&quot; &lt;!-- Optional: Make this field as mandatory or not. --&gt;
&lt;/datepicker&gt;
</pre>
          <p>Add the below code in any of your angular module.</p>
          <pre>
your_angular_module_name.directive('datepicker', ['$timeout', function($timeout){
    var template = '';
    template += '&lt;div class=&quot;datepicker-container&quot; ng-click=&quot;show_datepicker();&quot;&gt;';
        template += '&lt;div class=&quot;plugin&quot; /&gt;';
        template += '&lt;span class=&quot;calendar-icon&quot;&gt;&amp;nbsp;&lt;/span&gt;';
        template += '&lt;span class=&quot;date-picked&quot; ng-bind=&quot;value | date: \'dd-MMM-yyyy\'&quot;&gt;&lt;/span&gt;';
    template += '&lt;/div&gt;';

    return {
        require: 'ngModel',
        restrict: 'E',
        replace: true,
        template: template,
        scope: {
            settings: '=?', // optional: Datepicker settings or configurations as per jQuery UI documentation
            position: '@?', // optional: Position 'top_left', 'top_right', 'bottom_left', 'bottom_right'
            onselect: '=?', // optional: A callback scope after selecting a date
            position_padding: '@?positionPadding', //optional: position padding from the calendar icon
            required: '@?dateRequired', // optional: validation, 'yes' or 'no'
            value: '=ngModel'
        },
        link: function($scope, $element, $attrs, ngModel) {
            /*
            * Validating the arguments passed from the HTML attribute
            */
            var settings = $scope.settings || {},
                position = $scope.position || 'bottom_right',
                position_padding = $scope.position_padding || '0,0',
                position_padding = position_padding.split(','),
                required = $scope.required || 'no',
                value = $scope.value || '',
                plugin = $element.children('.plugin');
            /*
            * validation process
            */
            ngModel.$setValidity('datepicked', !(required === 'yes' &amp;&amp; value === ''));

            /*
            * Extending the default settings with the providing settings
            */
            default_settings = {
                dateFormat: &quot;dd-M-yy&quot;,
                onSelect: function(date){
                    ngModel.$setValidity('datepicked', true);
                    ngModel.$setViewValue(date);
                    ngModel.$render();

                    plugin.datepicker('destroy');
                    if(angular.isFunction($scope.onselect)){
                        $scope.onselect($scope.value);
                    }

                    $scope.$apply();
                }
            };
            settings = angular.extend(default_settings, settings);
            /*
            * Placing the datepicker position according to the configuration provided in the directive.
            */
            var get_position_style = function(){
                var element_height = $element.outerHeight(true),
                    element_width = $element.outerWidth(true),
                    picker_height = plugin.height(),
                    picker_width = plugin.width()
                    position_style = {
                        position: 'absolute', 
                        top: position_padding[0] ? parseInt(position_padding[0]) : 0, 
                        left: position_padding[1] ? parseInt(position_padding[1]) : 0
                    };

                var positions = {
                    'top_left': function(){
                        position_style.top = - picker_height;
                        position_style.left += - picker_width;
                    },
                    'top_right': function(){
                        position_style.top = - picker_height;
                        position_style.left = 0;
                    },
                    'bottom_left': function(){
                        position_style.top += 0;
                        position_style.left += - picker_width;
                    },
                    'bottom_right': function(){
                        position_style.top += 0;
                        position_style.left = 0;
                    }
                };

                positions[position]();

                return position_style;
            };

            /*
            * Datepicker will display on focusing the calendar icon.
            * Datepicker will hide on removing focus from the calendar icon.
            */
            $element.on('click', '.calendar-icon', function(){
                plugin.datepicker(settings);
                plugin.css(get_position_style());
                $element.find('.hasDatepicker').show();
            });

            $element.on('mouseleave', '.hasDatepicker', function(e){
                var _this = this;
                $timeout(function(){
                    $(_this).hide();
                }, 300);
            });

            $element.on('mouseleave', function(e){
                $timeout(function(){
                    $element.find('.hasDatepicker').hide();
                }, 300);
            });
        }
    };
}]);
</pre>
          <p>Thats it! You're done.</p>
        </div>
      </div>
    </div>
    <!-- Angular, jQuery, jQuery UI Datepicker ends -->

  </div>

  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>

  <script src="script.js"></script>
</body>

</html>
var angular_reusables = angular.module('angularReusables', []);

angular_reusables.controller('angular_reusables_controller', ['$rootScope', '$scope',
  function($rootScope, $scope) {
    $scope.datepicker = {
      selected_value_one: '',
      selected_value_two: '',
      selected_value_three: '',
      selected_value_four: new Date(),
      add_settings: {
        minDate: new Date()
      }
    };
  }
]);

/*
 * jQuery UI Datepicker plugin.
 */
angular_reusables.directive('datepicker', ['$timeout',
  function($timeout) {
    var template = '';
    template += '<div class="datepicker-container" ng-click="show_datepicker();">';
    template += '<div class="plugin" />';
    template += '<span class="calendar-icon">&nbsp;</span>';
    template += '<span class="date-picked" ng-bind="value | date: \'dd-MMM-yyyy\'"></span>';
    template += '</div>';

    return {
      require: 'ngModel',
      restrict: 'E',
      replace: true,
      template: template,
      scope: {
        settings: '=?', // optional: Datepicker settings or configurations as per jQuery UI documentation
        position: '@?', // optional: Position 'top_left', 'top_right', 'bottom_left', 'bottom_right'
        onselect: '=?', // optional: A callback scope after selecting a date
        position_padding: '@?positionPadding', //optional: position padding from the calendar icon
        required: '@?dateRequired', // optional: validation, 'yes' or 'no'
        value: '=ngModel'
      },
      link: function($scope, $element, $attrs, ngModel) {
        /*
         * Validating the arguments passed from the HTML attribute
         */
        var settings = $scope.settings || {},
          position = $scope.position || 'bottom_right',
          position_padding = $scope.position_padding || '0,0',
          required = $scope.required || 'no',
          value = $scope.value || '',
          plugin = $element.children('.plugin');
          
        position_padding = position_padding.split(',');
        /*
         * validation process
         */
        ngModel.$setValidity('datepicked', !(required === 'yes' && value === ''));

        /*
         * Extending the default settings with the providing settings
         */
        default_settings = {
          dateFormat: "dd-M-yy",
          onSelect: function(date) {
            ngModel.$setValidity('datepicked', true);
            ngModel.$setViewValue(date);
            ngModel.$render();

            plugin.datepicker('destroy');
            if (angular.isFunction($scope.onselect)) {
              $scope.onselect($scope.value);
            }

            $scope.$apply();
          }
        };
        settings = angular.extend(default_settings, settings);
        /*
         * Placing the datepicker position according to the configuration provided in the directive.
         */
        var get_position_style = function() {
          var element_height = $element.outerHeight(true),
            element_width = $element.outerWidth(true),
            picker_height = plugin.height(),
            picker_width = plugin.width()
            position_style = {
              position: 'absolute',
              top: position_padding[0] ? parseInt(position_padding[0]) : 0,
              left: position_padding[1] ? parseInt(position_padding[1]) : 0
            };

          var positions = {
            'top_left': function() {
              position_style.top = -picker_height;
              position_style.left += -picker_width;
            },
            'top_right': function() {
              position_style.top = -picker_height;
              position_style.left = 0;
            },
            'bottom_left': function() {
              position_style.top += 0;
              position_style.left += -picker_width;
            },
            'bottom_right': function() {
              position_style.top += 0;
              position_style.left = 0;
            }
          };

          positions[position]();

          return position_style;
        };

        /*
         * Datepicker will display on focusing the calendar icon.
         * Datepicker will hide on removing focus from the calendar icon.
         */
        $element.on('click', '.calendar-icon', function() {
          plugin.datepicker(settings);
          plugin.css(get_position_style());
          $element.find('.hasDatepicker').show();
        });

        $element.on('mouseleave', '.hasDatepicker', function(e) {
          var _this = this;
          $timeout(function() {
            $(_this).hide();
          }, 300);
        });

        $element.on('mouseleave', function(e) {
          $timeout(function() {
            $element.find('.hasDatepicker').hide();
          }, 300);
        });
      }
    };
  }
]);
.nav-tabs{margin-bottom: 15px;}

/*-------------------AngularJS & jQuery UI Datepicker starts-----------------------------*/
.datepicker-container{position: relative;padding: 6px;float: left;border-radius: 2px;margin-bottom: 8px;}
.datepicker-container.ng-invalid-datepicked{background-color: #F8C4C4;border: 1px solid #C28080;}
.datepicker-container.ng-valid-datepicked{background-color: #DDFBCD;border: 1px solid #A6C297;}
.datepicker-container .plugin{position: absolute;z-index: 1;}
.datepicker-container .date-picked{color: #5D7A4E;}
.datepicker-container .calendar-icon:before{content: 'Pick Date';}
/*-------------------AngularJS & jQuery UI Datepicker ends-----------------------------*/