diff --git a/README.md b/README.md index 8fb7dfe..dcd828f 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,15 @@ $scope.dates = moment().range("2012-11-05", "2013-01-25") ## Customizations +### Simple date picker + +You can also select only one date: + +```html + + +``` + ### Select range options ```js diff --git a/bower.json b/bower.json index ac04a28..6da9e21 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-date-range-picker", - "version": "0.3.4", + "version": "0.4", "authors": [ "Tymon Tobolski ", "Krzysztof Jung " diff --git a/build/angular-date-range-picker.css b/build/angular-date-range-picker.css index 81899e2..a7f4e09 100644 --- a/build/angular-date-range-picker.css +++ b/build/angular-date-range-picker.css @@ -125,9 +125,7 @@ position: absolute; top: 30px; left: -1px; - width: 700px; overflow: hidden; - height: 183px; background: #fff; z-index: 1000; border: 1px solid #ccc; @@ -136,6 +134,11 @@ box-sizing: content-box; } +.angular-date-range-picker--ranged { + width: 700px; + height: 183px; +} + .angular-date-range-picker__calendar-day:hover { background: #000; color: #fff; @@ -169,7 +172,7 @@ cursor: pointer; } -.angular-date-range-picker__buttons { +.angular-date-range-picker--ranged .angular-date-range-picker__buttons { position: absolute; bottom: 10px; } diff --git a/build/angular-date-range-picker.js b/build/angular-date-range-picker.js index f2fa023..dce6a77 100644 --- a/build/angular-date-range-picker.js +++ b/build/angular-date-range-picker.js @@ -4,15 +4,16 @@ angular.module("dateRangePicker").directive("dateRangePicker", [ "$compile", function($compile) { var CUSTOM, pickerTemplate; - pickerTemplate = "
\n
\n \n
\n
\n \n \n \n \n \n \n \n \n
\n
\n
\n \n
\n
\n
\n Select range: \n
\n
\n \n cancel\n
\n
\n
"; + pickerTemplate = "
\n
\n \n
\n
\n \n \n \n \n \n \n \n \n
\n
\n
\n \n
\n
\n
\n Select range: \n
\n
\n \n cancel\n
\n
\n
"; CUSTOM = "CUSTOM"; return { restrict: "AE", replace: true, - template: "\n {{ model.start.format(\"ll\") }} - {{ model.end.format(\"ll\") }}\n Select date range\n", + template: "\n \n {{ model.start.format(\"ll\") }} - {{ model.end.format(\"ll\") }}\n Select date range\n \n \n {{ model.format(\"ll\") }}\n Select date\n \n", scope: { model: "=ngModel", - customSelectOptions: "=" + customSelectOptions: "=", + ranged: "=" }, link: function($scope, element, attrs) { var documentClickFn, domEl, _calculateRange, _checkQuickList, _makeQuickList, _prepare; @@ -42,11 +43,15 @@ $scope.selecting = false; $scope.visible = false; $scope.start = null; + $scope.showRanged = $scope.ranged === void 0 ? true : $scope.ranged; _makeQuickList = function(includeCustom) { var e, _i, _len, _ref, _results; if (includeCustom == null) { includeCustom = false; } + if (!$scope.showRanged) { + return; + } $scope.quickList = []; if (includeCustom) { $scope.quickList.push({ @@ -64,10 +69,20 @@ }; _calculateRange = function() { var end, start; - return $scope.range = $scope.selection ? (start = $scope.selection.start.clone().startOf("month").startOf("day"), end = start.clone().add(2, "months").endOf("month").startOf("day"), moment().range(start, end)) : moment().range(moment().startOf("month").subtract(1, "month").startOf("day"), moment().endOf("month").add(1, "month").startOf("day")); + if ($scope.showRanged) { + return $scope.range = $scope.selection ? (start = $scope.selection.start.clone().startOf("month").startOf("day"), end = start.clone().add(2, "months").endOf("month").startOf("day"), moment().range(start, end)) : moment().range(moment().startOf("month").subtract(1, "month").startOf("day"), moment().endOf("month").add(1, "month").startOf("day")); + } else { + $scope.selection = false; + $scope.selection = $scope.model || false; + $scope.date = $scope.model || moment(); + return $scope.range = moment().range(moment($scope.date).startOf("month"), moment($scope.date).endOf("month")); + } }; _checkQuickList = function() { var e, _i, _len, _ref; + if (!$scope.showRanged) { + return; + } if (!$scope.selection) { return; } @@ -98,11 +113,15 @@ w = parseInt((7 + date.date() - d) / 7); sel = false; dis = false; - if ($scope.start) { - sel = date === $scope.start; - dis = date < $scope.start; + if ($scope.showRanged) { + if ($scope.start) { + sel = date === $scope.start; + dis = date < $scope.start; + } else { + sel = $scope.selection && $scope.selection.contains(date); + } } else { - sel = $scope.selection && $scope.selection.contains(date); + sel = date.isSame($scope.selection); } (_base = $scope.months)[m] || (_base[m] = { name: date.format("MMMM YYYY"), @@ -161,15 +180,18 @@ if (day.disabled) { return; } - $scope.selecting = !$scope.selecting; - if ($scope.selecting) { - $scope.start = day.date; - return _prepare(); + if ($scope.showRanged) { + $scope.selecting = !$scope.selecting; + if ($scope.selecting) { + $scope.start = day.date; + } else { + $scope.selection = moment().range($scope.start, day.date); + $scope.start = null; + } } else { - $scope.selection = moment().range($scope.start, day.date); - $scope.start = null; - return _prepare(); + $scope.selection = day.date; } + return _prepare(); }; $scope.move = function(n, $event) { if ($event != null) { @@ -177,7 +199,12 @@ $event.stopPropagation(); } } - $scope.range = moment().range($scope.range.start.add(n, 'months').startOf("month").startOf("day"), $scope.range.start.clone().add(2, "months").endOf("month").startOf("day")); + if ($scope.showRanged) { + $scope.range = moment().range($scope.range.start.add(n, 'months').startOf("month").startOf("day"), $scope.range.start.clone().add(2, "months").endOf("month").startOf("day")); + } else { + $scope.date = moment().month($scope.date.month() + n); + $scope.range = moment().range(moment($scope.date).startOf("month"), moment($scope.date).endOf("month")); + } return _prepare(); }; $scope.handlePickerClick = function($event) { @@ -194,6 +221,9 @@ return _prepare(); }); $scope.$watch("customSelectOptions", function(value) { + if (typeof customSelectOptions === "undefined" || customSelectOptions === null) { + return; + } return $scope.quickListDefinitions = value; }); domEl = $compile(angular.element(pickerTemplate))($scope); diff --git a/build/angular-date-range-picker.min.js b/build/angular-date-range-picker.min.js index 64e8441..bfd4397 100644 --- a/build/angular-date-range-picker.min.js +++ b/build/angular-date-range-picker.min.js @@ -1,2 +1,2 @@ -/*! angular-date-range-picker 2014-03-11 */ -(function(){angular.module("dateRangePicker",["pasvaz.bindonce"]),angular.module("dateRangePicker").directive("dateRangePicker",["$compile",function(a){var b,c;return c='
\n
\n \n
\n
\n \n \n \n \n \n \n \n \n
\n
\n
\n \n
\n
\n
\n Select range: \n
\n
\n \n cancel\n
\n
\n
',b="CUSTOM",{restrict:"AE",replace:!0,template:'\n {{ model.start.format("ll") }} - {{ model.end.format("ll") }}\n Select date range\n',scope:{model:"=ngModel",customSelectOptions:"="},link:function(d,e){var f,g,h,i,j,k;return d.quickListDefinitions=d.customSelectOptions,null==d.quickListDefinitions&&(d.quickListDefinitions=[{label:"This week",range:moment().range(moment().startOf("week").startOf("day"),moment().endOf("week").startOf("day"))},{label:"Next week",range:moment().range(moment().startOf("week").add(1,"week").startOf("day"),moment().add(1,"week").endOf("week").startOf("day"))},{label:"This fortnight",range:moment().range(moment().startOf("week").startOf("day"),moment().add(1,"week").endOf("week").startOf("day"))},{label:"This month",range:moment().range(moment().startOf("month").startOf("day"),moment().endOf("month").startOf("day"))},{label:"Next month",range:moment().range(moment().startOf("month").add(1,"month").startOf("day"),moment().add(1,"month").endOf("month").startOf("day"))}]),d.quick=null,d.range=null,d.selecting=!1,d.visible=!1,d.start=null,j=function(a){var c,e,f,g,h;for(null==a&&(a=!1),d.quickList=[],a&&d.quickList.push({label:"Custom",range:b}),g=d.quickListDefinitions,h=[],e=0,f=g.length;f>e;e++)c=g[e],h.push(d.quickList.push(c));return h},h=function(){var a,b;return d.range=d.selection?(b=d.selection.start.clone().startOf("month").startOf("day"),a=b.clone().add(2,"months").endOf("month").startOf("day"),moment().range(b,a)):moment().range(moment().startOf("month").subtract(1,"month").startOf("day"),moment().endOf("month").add(1,"month").startOf("day"))},i=function(){var a,c,e,f;if(d.selection){for(f=d.quickList,c=0,e=f.length;e>c;c++)if(a=f[c],a.range!==b&&d.selection.start.startOf("day").unix()===a.range.start.startOf("day").unix()&&d.selection.end.startOf("day").unix()===a.range.end.startOf("day").unix())return d.quick=a.range,void j();return d.quick=b,j(!0)}},k=function(){var a,b,c,e,f,g;for(d.months=[],c=12*d.range.start.year()+d.range.start.month(),b=moment().startOf("week").day(),d.range.by("days",function(a){var e,f,g,h,i,j,k;return e=a.day()-b,0>e&&(e=7+e),g=12*a.year()+a.month()-c,i=parseInt((7+a.date()-e)/7),h=!1,f=!1,d.start?(h=a===d.start,f=ae;e++)a=g[e],a.weeks[0]||a.weeks.splice(0,1);return i()},d.show=function(){return d.selection=d.model,h(),k(),d.visible=!0},d.hide=function(a){return null!=a&&"function"==typeof a.stopPropagation&&a.stopPropagation(),d.visible=!1,d.start=null},d.prevent_select=function(a){return null!=a?"function"==typeof a.stopPropagation?a.stopPropagation():void 0:void 0},d.ok=function(a){return null!=a&&"function"==typeof a.stopPropagation&&a.stopPropagation(),d.model=d.selection,d.hide()},d.select=function(a,b){return null!=b&&"function"==typeof b.stopPropagation&&b.stopPropagation(),a.disabled?void 0:(d.selecting=!d.selecting,d.selecting?(d.start=a.date,k()):(d.selection=moment().range(d.start,a.date),d.start=null,k()))},d.move=function(a,b){return null!=b&&"function"==typeof b.stopPropagation&&b.stopPropagation(),d.range=moment().range(d.range.start.add(a,"months").startOf("month").startOf("day"),d.range.start.clone().add(2,"months").endOf("month").startOf("day")),k()},d.handlePickerClick=function(a){return null!=a?"function"==typeof a.stopPropagation?a.stopPropagation():void 0:void 0},d.$watch("quick",function(a){return a&&a!==b?(d.selection=d.quick,d.selecting=!1,d.start=null,h(),k()):void 0}),d.$watch("customSelectOptions",function(a){return d.quickListDefinitions=a}),g=a(angular.element(c))(d),e.append(g),e.bind("click",function(a){return null!=a&&"function"==typeof a.stopPropagation&&a.stopPropagation(),d.$apply(function(){return d.visible?d.hide():d.show()})}),f=function(){return d.$apply(function(){return d.hide()}),!0},angular.element(document).bind("click",f),d.$on("$destroy",function(){return angular.element(document).unbind("click",f)}),j(),h(),k()}}}])}).call(this); \ No newline at end of file +/*! angular-date-range-picker 2014-03-17 */ +(function(){angular.module("dateRangePicker",["pasvaz.bindonce"]),angular.module("dateRangePicker").directive("dateRangePicker",["$compile",function(a){var b,c;return c='
\n
\n \n
\n
\n \n \n \n \n \n \n \n \n
\n
\n
\n \n
\n
\n
\n Select range: \n
\n
\n \n cancel\n
\n
\n
',b="CUSTOM",{restrict:"AE",replace:!0,template:'\n \n {{ model.start.format("ll") }} - {{ model.end.format("ll") }}\n Select date range\n \n \n {{ model.format("ll") }}\n Select date\n \n',scope:{model:"=ngModel",customSelectOptions:"=",ranged:"="},link:function(d,e){var f,g,h,i,j,k;return d.quickListDefinitions=d.customSelectOptions,null==d.quickListDefinitions&&(d.quickListDefinitions=[{label:"This week",range:moment().range(moment().startOf("week").startOf("day"),moment().endOf("week").startOf("day"))},{label:"Next week",range:moment().range(moment().startOf("week").add(1,"week").startOf("day"),moment().add(1,"week").endOf("week").startOf("day"))},{label:"This fortnight",range:moment().range(moment().startOf("week").startOf("day"),moment().add(1,"week").endOf("week").startOf("day"))},{label:"This month",range:moment().range(moment().startOf("month").startOf("day"),moment().endOf("month").startOf("day"))},{label:"Next month",range:moment().range(moment().startOf("month").add(1,"month").startOf("day"),moment().add(1,"month").endOf("month").startOf("day"))}]),d.quick=null,d.range=null,d.selecting=!1,d.visible=!1,d.start=null,d.showRanged=void 0===d.ranged?!0:d.ranged,j=function(a){var c,e,f,g,h;if(null==a&&(a=!1),d.showRanged){for(d.quickList=[],a&&d.quickList.push({label:"Custom",range:b}),g=d.quickListDefinitions,h=[],e=0,f=g.length;f>e;e++)c=g[e],h.push(d.quickList.push(c));return h}},h=function(){var a,b;return d.showRanged?d.range=d.selection?(b=d.selection.start.clone().startOf("month").startOf("day"),a=b.clone().add(2,"months").endOf("month").startOf("day"),moment().range(b,a)):moment().range(moment().startOf("month").subtract(1,"month").startOf("day"),moment().endOf("month").add(1,"month").startOf("day")):(d.selection=!1,d.selection=d.model||!1,d.date=d.model||moment(),d.range=moment().range(moment(d.date).startOf("month"),moment(d.date).endOf("month")))},i=function(){var a,c,e,f;if(d.showRanged&&d.selection){for(f=d.quickList,c=0,e=f.length;e>c;c++)if(a=f[c],a.range!==b&&d.selection.start.startOf("day").unix()===a.range.start.startOf("day").unix()&&d.selection.end.startOf("day").unix()===a.range.end.startOf("day").unix())return d.quick=a.range,void j();return d.quick=b,j(!0)}},k=function(){var a,b,c,e,f,g;for(d.months=[],c=12*d.range.start.year()+d.range.start.month(),b=moment().startOf("week").day(),d.range.by("days",function(a){var e,f,g,h,i,j,k;return e=a.day()-b,0>e&&(e=7+e),g=12*a.year()+a.month()-c,i=parseInt((7+a.date()-e)/7),h=!1,f=!1,d.showRanged?d.start?(h=a===d.start,f=ae;e++)a=g[e],a.weeks[0]||a.weeks.splice(0,1);return i()},d.show=function(){return d.selection=d.model,h(),k(),d.visible=!0},d.hide=function(a){return null!=a&&"function"==typeof a.stopPropagation&&a.stopPropagation(),d.visible=!1,d.start=null},d.prevent_select=function(a){return null!=a&&"function"==typeof a.stopPropagation?a.stopPropagation():void 0},d.ok=function(a){return null!=a&&"function"==typeof a.stopPropagation&&a.stopPropagation(),d.model=d.selection,d.hide()},d.select=function(a,b){return null!=b&&"function"==typeof b.stopPropagation&&b.stopPropagation(),a.disabled?void 0:(d.showRanged?(d.selecting=!d.selecting,d.selecting?d.start=a.date:(d.selection=moment().range(d.start,a.date),d.start=null)):d.selection=a.date,k())},d.move=function(a,b){return null!=b&&"function"==typeof b.stopPropagation&&b.stopPropagation(),d.showRanged?d.range=moment().range(d.range.start.add(a,"months").startOf("month").startOf("day"),d.range.start.clone().add(2,"months").endOf("month").startOf("day")):(d.date=moment().month(d.date.month()+a),d.range=moment().range(moment(d.date).startOf("month"),moment(d.date).endOf("month"))),k()},d.handlePickerClick=function(a){return null!=a&&"function"==typeof a.stopPropagation?a.stopPropagation():void 0},d.$watch("quick",function(a){return a&&a!==b?(d.selection=d.quick,d.selecting=!1,d.start=null,h(),k()):void 0}),d.$watch("customSelectOptions",function(a){return"undefined"!=typeof customSelectOptions&&null!==customSelectOptions?d.quickListDefinitions=a:void 0}),g=a(angular.element(c))(d),e.append(g),e.bind("click",function(a){return null!=a&&"function"==typeof a.stopPropagation&&a.stopPropagation(),d.$apply(function(){return d.visible?d.hide():d.show()})}),f=function(){return d.$apply(function(){return d.hide()}),!0},angular.element(document).bind("click",f),d.$on("$destroy",function(){return angular.element(document).unbind("click",f)}),j(),h(),k()}}}])}).call(this); \ No newline at end of file diff --git a/package.json b/package.json index 2282f9a..812b0b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-date-range-picker", - "version": "0.3.4", + "version": "0.4", "authors": [ "Tymon Tobolski ", "Krzysztof Jung " diff --git a/src/angular-date-range-picker.coffee b/src/angular-date-range-picker.coffee index a731988..5629a93 100644 --- a/src/angular-date-range-picker.coffee +++ b/src/angular-date-range-picker.coffee @@ -3,7 +3,9 @@ angular.module "dateRangePicker", ['pasvaz.bindonce'] angular.module("dateRangePicker").directive "dateRangePicker", ["$compile", ($compile) -> # constants pickerTemplate = """ -
+
@@ -29,7 +31,7 @@ angular.module("dateRangePicker").directive "dateRangePicker", ["$compile", ($co
-
+
Select range:
@@ -45,13 +47,20 @@ angular.module("dateRangePicker").directive "dateRangePicker", ["$compile", ($co replace: true template: """ - {{ model.start.format("ll") }} - {{ model.end.format("ll") }} - Select date range + + {{ model.start.format("ll") }} - {{ model.end.format("ll") }} + Select date range + + + {{ model.format("ll") }} + Select date + """ scope: model: "=ngModel" # can't use ngModelController, we need isolated scope customSelectOptions: "=" + ranged: "=" link: ($scope, element, attrs) -> $scope.quickListDefinitions = $scope.customSelectOptions @@ -97,25 +106,38 @@ angular.module("dateRangePicker").directive "dateRangePicker", ["$compile", ($co $scope.selecting = false $scope.visible = false $scope.start = null + # Backward compatibility - if $scope.ranged is not set in the html, it displays normal date range picker. + $scope.showRanged = if $scope.ranged == undefined then true else $scope.ranged _makeQuickList = (includeCustom = false) -> + return unless $scope.showRanged $scope.quickList = [] $scope.quickList.push(label: "Custom", range: CUSTOM) if includeCustom for e in $scope.quickListDefinitions $scope.quickList.push(e) _calculateRange = () -> - $scope.range = if $scope.selection - start = $scope.selection.start.clone().startOf("month").startOf("day") - end = start.clone().add(2, "months").endOf("month").startOf("day") - moment().range(start, end) + if $scope.showRanged + $scope.range = if $scope.selection + start = $scope.selection.start.clone().startOf("month").startOf("day") + end = start.clone().add(2, "months").endOf("month").startOf("day") + moment().range(start, end) + else + moment().range( + moment().startOf("month").subtract(1, "month").startOf("day"), + moment().endOf("month").add(1, "month").startOf("day") + ) else - moment().range( - moment().startOf("month").subtract(1, "month").startOf("day"), - moment().endOf("month").add(1, "month").startOf("day") + $scope.selection = false + $scope.selection = $scope.model || false + $scope.date = $scope.model || moment() + $scope.range = moment().range( + moment($scope.date).startOf("month"), + moment($scope.date).endOf("month") ) _checkQuickList = () -> + return unless $scope.showRanged return unless $scope.selection for e in $scope.quickList if e.range != CUSTOM and $scope.selection.start.startOf("day").unix() == e.range.start.startOf("day").unix() and @@ -142,11 +164,14 @@ angular.module("dateRangePicker").directive "dateRangePicker", ["$compile", ($co sel = false dis = false - if $scope.start - sel = date == $scope.start - dis = date < $scope.start + if $scope.showRanged + if $scope.start + sel = date == $scope.start + dis = date < $scope.start + else + sel = $scope.selection && $scope.selection.contains(date) else - sel = $scope.selection && $scope.selection.contains(date) + sel = date.isSame($scope.selection) $scope.months[m] ||= {name: date.format("MMMM YYYY"), weeks: []} $scope.months[m].weeks[w] ||= [] @@ -187,22 +212,33 @@ angular.module("dateRangePicker").directive "dateRangePicker", ["$compile", ($co $event?.stopPropagation?() return if day.disabled - $scope.selecting = !$scope.selecting + if $scope.showRanged + $scope.selecting = !$scope.selecting - if $scope.selecting - $scope.start = day.date - _prepare() + if $scope.selecting + $scope.start = day.date + else + $scope.selection = moment().range($scope.start, day.date) + $scope.start = null else - $scope.selection = moment().range($scope.start, day.date) - $scope.start = null - _prepare() + $scope.selection = day.date + + _prepare() $scope.move = (n, $event) -> $event?.stopPropagation?() - $scope.range = moment().range( - $scope.range.start.add(n, 'months').startOf("month").startOf("day"), - $scope.range.start.clone().add(2, "months").endOf("month").startOf("day") - ) + if $scope.showRanged + $scope.range = moment().range( + $scope.range.start.add(n, 'months').startOf("month").startOf("day"), + $scope.range.start.clone().add(2, "months").endOf("month").startOf("day") + ) + else + $scope.date = moment().month($scope.date.month() + n) + $scope.range = moment().range( + moment($scope.date).startOf("month"), + moment($scope.date).endOf("month") + ) + _prepare() $scope.handlePickerClick = ($event) -> @@ -217,6 +253,7 @@ angular.module("dateRangePicker").directive "dateRangePicker", ["$compile", ($co _prepare() $scope.$watch "customSelectOptions", (value) -> + return unless customSelectOptions? $scope.quickListDefinitions = value # create DOM and bind event diff --git a/src/angular-date-range-picker.less b/src/angular-date-range-picker.less index 9011305..aef1518 100644 --- a/src/angular-date-range-picker.less +++ b/src/angular-date-range-picker.less @@ -94,14 +94,18 @@ position: absolute; top: 30px; left: -1px; - width: 700px; overflow: hidden; - height: 183px; background: #fff; z-index: 1000; border: 1px solid #ccc; box-sizing: content-box; } + +.angular-date-range-picker--ranged { + width: 700px; + height: 183px; +} + .angular-date-range-picker__calendar-day:hover { background: #000; color: #fff; @@ -130,7 +134,7 @@ color: #000; cursor: pointer; } -.angular-date-range-picker__buttons { +.angular-date-range-picker--ranged .angular-date-range-picker__buttons { position: absolute; bottom: 10px; } diff --git a/test/index.html b/test/index.html index 58d3ef5..8ca9c85 100644 --- a/test/index.html +++ b/test/index.html @@ -15,6 +15,8 @@ $scope.change = function(){ $scope.range2 = moment().range("2012-11-15", "2012-12-25") } + + $scope.date = null }) @@ -27,10 +29,17 @@
- -
{{ range.start.toDate() }} - {{ range.end.toDate() }}
- - +
+

Date range picker

+ +
{{ range.start.toDate() }} - {{ range.end.toDate() }}
+ + +
+
+

Simple date picker

+ +