Created
March 18, 2013 18:23
-
-
Save grownseed/5189503 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app.directive('datetime', ['$timeout', function($timeout) { | |
'use strict'; | |
var DATE_REGEXP_MAP = { | |
'/' : '[\\/]', | |
'-' : '[-]', | |
'.' : '[.]', | |
dd: '(0?[1-9]|[1-2][0-9]|3[0-1])\\b', | |
MM: '(0?[1-9]|1[0-2])\\b', | |
yyyy: '(\\d{4})\\b', | |
yy: '(\\d{2})\\b', | |
HH: '(0?[0-9]|1[0-9]|2[0-3])\\b', | |
mm: '(0?[0-9]|[1-5][0-9])\\b', | |
ss: '(0?[0-9]|[1-5][0-9])\\b', | |
ms: '([0-9]{1,3})\\b', | |
hh: '(0?[1-9]|1[0-2])\\b', | |
PP: '(AM|PM|am|pm|Am|aM|Pm|pM)\\b' | |
}; | |
return { | |
restrict: 'A', | |
require: '?ngModel', | |
link: function postLink(scope, element, attrs, controller) { | |
var regexpForDateFormat = function(dateFormat, options) { | |
options || (options = {}); | |
var re = dateFormat, regexpMap = DATE_REGEXP_MAP; | |
angular.forEach(regexpMap, function(v, k) { re = re.split(k).join(v); }); | |
return new RegExp('^' + re + '$', ['i']); | |
}; | |
var dateFormat = attrs['datetime'] || 'dd/MM/yyyy HH:mm', | |
dateFormatRegexp = regexpForDateFormat(dateFormat); | |
//datetime picker hours format reversed from angular | |
var pickerFormat = dateFormat.split('HH'); | |
for (var i = 0; i < pickerFormat.length; i++) { | |
pickerFormat[i] = pickerFormat[i].replace(/h/g, 'H'); | |
} | |
pickerFormat = pickerFormat.join('hh'); | |
// Handle date validity according to dateFormat | |
if(controller) { | |
controller.$parsers.unshift(function(viewValue) { | |
var min = true, | |
max = true, | |
current_date = $(element).parent().data('datetimepicker').getLocalDate(); | |
current_date.setSeconds(0); | |
current_date.setMilliseconds(0); | |
scope.$emit('$validate'); | |
if (attrs['min']) { | |
var min_date = new Date(attrs['min']); | |
min_date.setSeconds(0); | |
min_date.setMilliseconds(0); | |
if (min_date.getTime() >= current_date.getTime()) { | |
controller.$setValidity('datetime_min', false); | |
return undefined; | |
}else{ | |
controller.$setValidity('datetime_min', true); | |
} | |
} | |
if (attrs['max']) { | |
var max_date = new Date(attrs['max']); | |
max_date.setSeconds(0); | |
max_date.setMilliseconds(0); | |
if (max_date.getTime() <= current_date.getTime()) { | |
controller.$setValidity('datetime_max', false); | |
return undefined; | |
}else{ | |
controller.$setValidity('datetime_max', true); | |
} | |
} | |
if ((!viewValue || dateFormatRegexp.test(viewValue)) && min && max) { | |
controller.$setValidity('datetime', true); | |
return current_date; | |
} else { | |
controller.$setValidity('datetime', false); | |
return undefined; | |
} | |
}); | |
} | |
var once = false; | |
scope.$watch($(element).attr('ng-model'), function(v) { | |
if (!v || once) | |
return; | |
once = true; | |
$(element).parent().data('datetimepicker').setLocalDate(new Date(v)); | |
}); | |
// If we have a controller (i.e. ngModelController) then wire it up | |
if(controller) { | |
$(element).parent().on('changeDate', function(ev) { | |
scope.$apply(function () { | |
controller.$setViewValue($(element).val()); | |
}); | |
}); | |
} | |
// Popover GarbageCollection | |
var $popover = $(element).closest('.popover'); | |
if($popover) { | |
$popover.on('hide', function(e) { | |
var datetimepicker = $(element).parent().data('datetimepicker'); | |
if(datetimepicker) { | |
datetimepicker.picker.remove(); | |
$(element).parent().data('datetimepicker', null); | |
} | |
}); | |
} | |
// Create datetimepicker | |
$(element).parent().datetimepicker({ | |
language: attrs.language || 'en', | |
format: pickerFormat | |
}); | |
} | |
}; | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment