<!DOCTYPE html>
<html ng-app="app">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
    <!--<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.min.js"></script>
    
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker3.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" />
    
    <script src="script.js"></script>
  </head>

  <body ng-controller="controller">
    <div class="container">
      
      <h1>Bootstrap date picker directive</h1>
      
      <h4 class="form-group">
        <span class="label label-primary">{{moment(date).format('MM/DD/YYYY')}}</span>
        <span class="label label-success">{{moment(date).format('h:mm:ss A')}}</span>
      </h4>
      
      <div class="form-group">
        <label>Pick from a textbox</label>
        <input type="text" class="form-control" ng-model="date" my-date-picker />
      </div>
      
      <div class="form-group">
        <label>Pick with a button</label>
        <div>
          <button class="btn" ng-model="date" my-date-picker><i class="fa fa-calendar"></i></button>
        </div>
      </div>
      
      <div class="form-group">
        <label>Pick with link</label>
        <div>
          <a href="" ng-model="date" my-date-picker>Link</a>
        </div>
      </div>
      
      <div class="form-group">
        <label>Time component operates independently</label>
        <div>
          <button class="btn" ng-click="addFifteen()">Add 15 minutes</button>
        </div>
      </div>
      
      <div class="form-group">
        <label>Always remains a JavaScript Date object</label>
        <div>{{date}}</div>
      </div>
      
      

    </div>
  </body>

</html>
angular.module('app', [])
  
  
  
    .controller('controller', function ($scope) {
        $scope.moment = moment;
        $scope.date = new Date();
        $scope.addFifteen = function () {
          $scope.date = new Date($scope.date.getTime() + (15 * 60000));
        }
    })
    
    
    
    .directive('myDatePicker', function () {
        return {
            restrict: 'A',
            require: '?ngModel',
            link: function (scope, element, attrs, ngModelController) {
      
                // Private variables
                var datepickerFormat = 'm/d/yyyy',
                    momentFormat = 'M/D/YYYY',
                    datepicker,
                    elPicker;
      
                // Init date picker and get objects http://bootstrap-datepicker.readthedocs.org/en/release/index.html
                datepicker = element.datepicker({
                    autoclose: true,
                    keyboardNavigation: false,
                    todayHighlight: true,
                    format: datepickerFormat
                });
                elPicker = datepicker.data('datepicker').picker;
      
                // Adjust offset on show
                datepicker.on('show', function (evt) {
                    elPicker.css('left', parseInt(elPicker.css('left')) + +attrs.offsetX);
                    elPicker.css('top', parseInt(elPicker.css('top')) + +attrs.offsetY);
                });
      
                // Only watch and format if ng-model is present https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
                if (ngModelController) {
                    // So we can maintain time
                    var lastModelValueMoment;
      
                    ngModelController.$formatters.push(function (modelValue) {
                        //
                        // Date -> String
                        //
      
                        // Get view value (String) from model value (Date)
                        var viewValue,
                            m = moment(modelValue);
                        if (modelValue && m.isValid()) {
                            // Valid date obj in model
                            lastModelValueMoment = m.clone(); // Save date (so we can restore time later)
                            viewValue = m.format(momentFormat);
                        } else {
                            // Invalid date obj in model
                            lastModelValueMoment = undefined;
                            viewValue = undefined;
                        }
      
                        // Update picker
                        element.datepicker('update', viewValue);
      
                        // Update view
                        return viewValue;
                    });
      
                    ngModelController.$parsers.push(function (viewValue) {
                        //
                        // String -> Date
                        //
      
                        // Get model value (Date) from view value (String)
                        var modelValue,
                            m = moment(viewValue, momentFormat, true);
                        if (viewValue && m.isValid()) {
                            // Valid date string in view
                            if (lastModelValueMoment) { // Restore time
                                m.hour(lastModelValueMoment.hour());
                                m.minute(lastModelValueMoment.minute());
                                m.second(lastModelValueMoment.second());
                                m.millisecond(lastModelValueMoment.millisecond());
                            }
                            modelValue = m.toDate();
                        } else {
                            // Invalid date string in view
                            modelValue = undefined;
                        }
      
                        // Update model
                        return modelValue;
                    });
      
                    datepicker.on('changeDate', function (evt) {
                        // Only update if it's NOT an <input> (if it's an <input> the datepicker plugin trys to cast the val to a Date)
                        if (evt.target.tagName !== 'INPUT') {
                            ngModelController.$setViewValue(moment(evt.date).format(momentFormat)); // $seViewValue basically calls the $parser above so we need to pass a string date value in
                            ngModelController.$render();
                        }
                    });
                }
      
            }
        };
    });