<!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();
}
});
}
}
};
});