Skip to content

Instantly share code, notes, and snippets.

@blangenfeld
Last active November 22, 2017 09:40
Show Gist options
  • Save blangenfeld/6737936 to your computer and use it in GitHub Desktop.
Save blangenfeld/6737936 to your computer and use it in GitHub Desktop.
An AngularJS directive for creating (and optionally binding) a Kalendae datepicker.
/**
* @ngdoc directive
* @name kf.directives:kalendae
* @restrict A
*
* @description
* The `kalendae` directive is used to attach a Kalendae datepicker to an element.
*
* @element ANY
* @param {string} kalendae options passed to the Kalendae datepicker; see http://github.com/ChiperSoft/Kalendae
*/
angular.module('kf.directives', [])
.directive('kalendae', function($parse) {
return {
restrict: 'A',
require: '?ngModel',
link: function postLink(scope, element, attrs, model) {
var type = element[0].tagName.toLowerCase() === 'input' ? Kalendae.Input : Kalendae,
options = (attrs.kalendae === null || attrs.kalendae === "") ? {} : (new Function('return {' + attrs.kalendae + '};'))(),
cal = new type(element[0], options),
delimiter = cal.settings.rangeDelimiter;
if(model) {
// Formats a Date or Array of Dates, as appropriate for the calendar's settings.
var format = function(value) {
var dates = [].concat(value).map(function(date) {
return Kalendae.moment(date).format(cal.settings.format);
});
if(cal.settings.mode === 'range') { dates.splice(2); }
else { delimiter = cal.settings.multipleDelimiter; }
return dates.join(delimiter);
};
// Ensure the calendar starts off with the correct Date or Array of Dates.
model.$render = function() {
cal.setSelected(format(model.$modelValue));
};
// Ensure we're setting a single Date or an Array of Dates, as appropriate for the calendar's settings.
if(cal.settings.mode !== 'range' && cal.settings.mode !== 'multiple') {
model.$parsers.push(function(value) { return value[0]; });
}
// Going forward, whenever the calendar changes, so does the model.
cal.subscribe('change', function(value) {
var dates = cal.getSelectedAsDates();
if(cal.settings.mode !== 'range' || dates.length === 2)
if(!scope.$$phase) {
scope.$apply(function() {
model.$setViewValue(dates);
});
}
});
}
}
};
});
@blangenfeld
Copy link
Author

Much respect to ChiperSoft et al for delivering "a date picker that doesn't suck." Very nice work, guys.

Get Kalendae here: https://github.com/ChiperSoft/Kalendae
Fiddle showing the directive in action: http://jsfiddle.net/blangenfeld/hfz82/1/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment