rails-angularstrap 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +89 -0
- data/Rakefile +2 -0
- data/lib/rails/angularstrap.rb +8 -0
- data/lib/rails/angularstrap/version.rb +5 -0
- data/vendor/assets/javascripts/angular-strap/LICENSE.md +21 -0
- data/vendor/assets/javascripts/angular-strap/README.md +112 -0
- data/vendor/assets/javascripts/angular-strap/angular-strap.nuspec +23 -0
- data/vendor/assets/javascripts/angular-strap/bower.json +53 -0
- data/vendor/assets/javascripts/angular-strap/dist/angular-strap.js +5014 -0
- data/vendor/assets/javascripts/angular-strap/dist/angular-strap.min.js +11 -0
- data/vendor/assets/javascripts/angular-strap/dist/angular-strap.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/angular-strap.tpl.js +89 -0
- data/vendor/assets/javascripts/angular-strap/dist/angular-strap.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/affix.js +249 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/affix.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/affix.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/alert.js +120 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/alert.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/alert.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/alert.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/alert.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/aside.js +96 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/aside.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/aside.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/aside.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/aside.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/button.js +177 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/button.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/button.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.js +273 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/collapse.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.js +61 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/date-formatter.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.js +273 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/date-parser.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.js +640 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/datepicker.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.js +62 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/debounce.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.js +156 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dimensions.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.js +149 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/dropdown.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/modal.js +349 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/modal.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/modal.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/modal.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/modal.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.js +72 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/navbar.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.js +76 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/parse-options.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/popover.js +112 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/popover.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/popover.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/popover.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/popover.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/raf.js +61 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/raf.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/raf.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.js +261 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/scrollspy.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/select.js +325 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/select.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/select.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/select.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/select.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tab.js +186 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tab.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tab.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tab.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tab.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.js +485 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/timepicker.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.js +690 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/tooltip.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.js +266 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/dist/modules/typeahead.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/gulpfile.js +489 -0
- data/vendor/assets/javascripts/angular-strap/package.json +73 -0
- data/vendor/assets/javascripts/angular-strap/src/affix/affix.js +258 -0
- data/vendor/assets/javascripts/angular-strap/src/alert/alert.js +113 -0
- data/vendor/assets/javascripts/angular-strap/src/alert/alert.tpl.html +4 -0
- data/vendor/assets/javascripts/angular-strap/src/aside/aside.js +89 -0
- data/vendor/assets/javascripts/angular-strap/src/aside/aside.tpl.html +14 -0
- data/vendor/assets/javascripts/angular-strap/src/button/button.js +174 -0
- data/vendor/assets/javascripts/angular-strap/src/collapse/collapse.js +266 -0
- data/vendor/assets/javascripts/angular-strap/src/datepicker/datepicker.js +633 -0
- data/vendor/assets/javascripts/angular-strap/src/datepicker/datepicker.tpl.html +33 -0
- data/vendor/assets/javascripts/angular-strap/src/dropdown/dropdown.js +143 -0
- data/vendor/assets/javascripts/angular-strap/src/dropdown/dropdown.tpl.html +6 -0
- data/vendor/assets/javascripts/angular-strap/src/helpers/date-formatter.js +54 -0
- data/vendor/assets/javascripts/angular-strap/src/helpers/date-parser.js +266 -0
- data/vendor/assets/javascripts/angular-strap/src/helpers/debounce.js +55 -0
- data/vendor/assets/javascripts/angular-strap/src/helpers/dimensions.js +212 -0
- data/vendor/assets/javascripts/angular-strap/src/helpers/parse-options.js +69 -0
- data/vendor/assets/javascripts/angular-strap/src/helpers/raf.js +54 -0
- data/vendor/assets/javascripts/angular-strap/src/modal/modal.js +348 -0
- data/vendor/assets/javascripts/angular-strap/src/modal/modal.tpl.html +14 -0
- data/vendor/assets/javascripts/angular-strap/src/module.js +19 -0
- data/vendor/assets/javascripts/angular-strap/src/navbar/navbar.js +65 -0
- data/vendor/assets/javascripts/angular-strap/src/popover/popover.js +111 -0
- data/vendor/assets/javascripts/angular-strap/src/popover/popover.tpl.html +5 -0
- data/vendor/assets/javascripts/angular-strap/src/scrollspy/scrollspy.js +254 -0
- data/vendor/assets/javascripts/angular-strap/src/select/select.js +321 -0
- data/vendor/assets/javascripts/angular-strap/src/select/select.tpl.html +14 -0
- data/vendor/assets/javascripts/angular-strap/src/tab/tab.js +183 -0
- data/vendor/assets/javascripts/angular-strap/src/tab/tab.tpl.html +7 -0
- data/vendor/assets/javascripts/angular-strap/src/timepicker/timepicker.js +493 -0
- data/vendor/assets/javascripts/angular-strap/src/timepicker/timepicker.tpl.html +62 -0
- data/vendor/assets/javascripts/angular-strap/src/tooltip/tooltip.js +806 -0
- data/vendor/assets/javascripts/angular-strap/src/tooltip/tooltip.tpl.html +4 -0
- data/vendor/assets/javascripts/angular-strap/src/typeahead/typeahead.js +262 -0
- data/vendor/assets/javascripts/angular-strap/src/typeahead/typeahead.tpl.html +5 -0
- data/vendor/assets/javascripts/angular/README.md +64 -0
- data/vendor/assets/javascripts/angular/angular-csp.css +13 -0
- data/vendor/assets/javascripts/angular/angular.js +26181 -0
- data/vendor/assets/javascripts/angular/angular.min.js +250 -0
- data/vendor/assets/javascripts/angular/angular.min.js.gzip +0 -0
- data/vendor/assets/javascripts/angular/angular.min.js.map +8 -0
- data/vendor/assets/javascripts/angular/bower.json +8 -0
- data/vendor/assets/javascripts/angular/index.js +2 -0
- data/vendor/assets/javascripts/angular/package.json +25 -0
- metadata +237 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
"use strict";angular.module("mgcrea.ngStrap.collapse",[]).provider("$collapse",function(){var e=this.defaults={animation:"am-collapse",disallowToggle:!1,activeClass:"in",startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,a,n){function i(e){for(var t=o.$targets.$active,a=0;a<t.length;a++)e<t[a]&&(t[a]=t[a]-1),t[a]===o.$targets.length&&(t[a]=o.$targets.length-1)}function s(e){var t=o.$targets.$active;return-1===t.indexOf(e)?!1:!0}function r(e){var t=o.$targets.$active.indexOf(e);-1!==t&&o.$targets.$active.splice(t,1)}function l(e){o.$options.allowMultiple||o.$targets.$active.splice(0,1),-1===o.$targets.$active.indexOf(e)&&o.$targets.$active.push(e)}var o=this;o.$options=angular.copy(e),angular.forEach(["animation","disallowToggle","activeClass","startCollapsed","allowMultiple"],function(e){angular.isDefined(n[e])&&(o.$options[e]=n[e])}),o.$toggles=[],o.$targets=[],o.$viewChangeListeners=[],o.$registerToggle=function(e){o.$toggles.push(e)},o.$registerTarget=function(e){o.$targets.push(e)},o.$unregisterToggle=function(e){var t=o.$toggles.indexOf(e);o.$toggles.splice(t,1)},o.$unregisterTarget=function(e){var t=o.$targets.indexOf(e);o.$targets.splice(t,1),o.$options.allowMultiple&&r(e),i(t),o.$viewChangeListeners.forEach(function(e){e()})},o.$targets.$active=o.$options.startCollapsed?[]:[0],o.$setActive=t.$setActive=function(e){angular.isArray(e)?o.$targets.$active=angular.copy(e):o.$options.disallowToggle?l(e):s(e)?r(e):l(e),o.$viewChangeListeners.forEach(function(e){e()})},o.$activeIndexes=function(){return o.$options.allowMultiple?o.$targets.$active:1===o.$targets.$active.length?o.$targets.$active[0]:-1}};this.$get=function(){var a={};return a.defaults=e,a.controller=t,a}}).directive("bsCollapse",["$window","$animate","$collapse",function(e,t,a){a.defaults;return{require:["?ngModel","bsCollapse"],controller:["$scope","$element","$attrs",a.controller],link:function(e,t,a,n){var i=n[0],s=n[1];i&&(s.$viewChangeListeners.push(function(){i.$setViewValue(s.$activeIndexes())}),i.$formatters.push(function(e){if(angular.isArray(e))s.$setActive(e);else{var t=s.$activeIndexes();angular.isArray(t)?-1===t.indexOf(1*e)&&s.$setActive(1*e):t!==1*e&&s.$setActive(1*e)}return e}))}}}]).directive("bsCollapseToggle",function(){return{require:["^?ngModel","^bsCollapse"],link:function(e,t,a,n){var i=(n[0],n[1]);t.attr("data-toggle","collapse"),i.$registerToggle(t),e.$on("$destroy",function(){i.$unregisterToggle(t)}),t.on("click",function(){var n=a.bsCollapseToggle||i.$toggles.indexOf(t);i.$setActive(1*n),e.$apply()})}}}).directive("bsCollapseTarget",["$animate",function(e){return{require:["^?ngModel","^bsCollapse"],link:function(t,a,n,i){function s(){var t=r.$targets.indexOf(a),n=r.$activeIndexes(),i="removeClass";angular.isArray(n)?-1!==n.indexOf(t)&&(i="addClass"):t===n&&(i="addClass"),e[i](a,r.$options.activeClass)}var r=(i[0],i[1]);a.addClass("collapse"),r.$options.animation&&a.addClass(r.$options.animation),r.$registerTarget(a),t.$on("$destroy",function(){r.$unregisterTarget(a)}),r.$viewChangeListeners.push(function(){s()}),s()}}}]);
|
|
9
|
+
//# sourceMappingURL=collapse.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["collapse/collapse.js"],"names":[],"mappings":"qBASM,OAAA,uCAEA,YAAe,gCAGjB,UAAI,cACF,gBAAW,qCAGX,eAAK,uDA2ED,yBAAI,EAAA,EAAA,EAAA,EAA0B,OAAS,IACrC,EAAA,EAAwB,kBAMxB,EAAc,KAAK,EAAS,SAAA,SAChC,EAAO,GAAY,EAAQ,SAAA,OAAgB,WAKvC,GAAW,MACb,GAAc,EAAA,SAAe,sCAIjC,QAAS,GAAa,GACpB,GAAI,GAAM,EAAA,SAAS,QAAe,QAAA,WAEhC,EAAK,SAAS,QAAQ,OAAO,EAAG,WAI3B,GAAS,4DAMG,KAAlB,EAAO,SAAA,QAAW,QAAA,IACjB,EAAA,SAAY,QAAA,KAAA,yCAnGhB,QAAK,SAAA,YAAuB,iBAAA,cAAA,iBAAA,iBAAA,SAAA,iEAK5B,EAAK,sCAIL,EAAK,gBAAA,SAAoB,GACvB,EAAI,SAAQ,KAAK,MAEjB,gBAAqB,SAAO,8IAU1B,GAAA,EAAe,SAAA,QAAA,oDAOf,EAAA,QAMJ,EAAK,qBAAoB,QAAA,SAAa,GACpC,SAKE,SAAS,QAAS,EAAA,SAAe,mBAAS,gBACrC,EAAA,WAAA,SAAA,GACL,QAAA,QAAa,sCAGV,EAAA,SAAA,qCAOH,qBAAsB,QAAA,SAAe,sCAMvC,MAAI,GAAA,SAAgB,cAAc,EAAA,SAAA,QACD,IAAjC,EAAI,SAAW,QAAI,OAAc,EAAQ,SAAK,QAAA,GAAA,kCAiDlD,OAFD,GAAU,SAAA,iBAEL,eAKI,cAAS,UAAgB,WAAS,YAAO,SAAa,EAAA,EAAA,GAEtD,EAAc,yBAGf,WAAa,+FAIZ,GAAY,EAAc,gBAMd,qBAAqB,KAAA,mDAK5B,YAAA,KAAA,SAAA,2BAKG,WAAc,yCAKX,QAAA,wBAIX,EAAO,WAAA,EAAA,yDAiBP,mBAAiB,2BAGb,YAAK,sCAGb,OAAe,EAAA,WAIb,KAAA,cAAe,YAGjB,EAAW,gBAAoB,KAG7B,IAAM,WAAA,yJAeJ,oBAAc,WAAY,SAAA,gHA4BnB,EAAkB,iBACzB,EAAS,qDAGX,EAAS,YAGX,IAAe,IACb,EAAA,2CA7BF,GACE,IADgB,EAAS,GACR,EAAA,iDAOnB,EAAU,SAAA,EAAuB,SAAA,WAIjC,EAAS,gBAAS,KAGZ,IAAA,WAAS,WACb,EAAY,kBAAiB,4CAoBlC","file":"collapse.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = angular.copy(value);\n }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes(index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for(var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive(value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) === -1 ? false : true;\n }\n\n function deactivateItem(value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem(value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function() {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function($window, $animate, $collapse) {\n\n var defaults = $collapse.defaults;\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n }\n else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function() {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function() {\n var index = attrs.bsCollapseToggle || bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if(bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render() {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n }\n else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
angular.module('mgcrea.ngStrap.helpers.dateFormatter', [])
|
|
11
|
+
|
|
12
|
+
.service('$dateFormatter', ["$locale", "dateFilter", function($locale, dateFilter) {
|
|
13
|
+
|
|
14
|
+
// The unused `lang` arguments are on purpose. The default implementation does not
|
|
15
|
+
// use them and it always uses the locale loaded into the `$locale` service.
|
|
16
|
+
// Custom implementations might use it, thus allowing different directives to
|
|
17
|
+
// have different languages.
|
|
18
|
+
|
|
19
|
+
this.getDefaultLocale = function() {
|
|
20
|
+
return $locale.id;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Format is either a data format name, e.g. "shortTime" or "fullDate", or a date format
|
|
24
|
+
// Return either the corresponding date format or the given date format.
|
|
25
|
+
this.getDatetimeFormat = function(format, lang) {
|
|
26
|
+
return $locale.DATETIME_FORMATS[format] || format;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
this.weekdaysShort = function(lang) {
|
|
30
|
+
return $locale.DATETIME_FORMATS.SHORTDAY;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function splitTimeFormat(format) {
|
|
34
|
+
return /(h+)([:\.])?(m+)[ ]?(a?)/i.exec(format).slice(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// h:mm a => h
|
|
38
|
+
this.hoursFormat = function(timeFormat) {
|
|
39
|
+
return splitTimeFormat(timeFormat)[0];
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// h:mm a => mm
|
|
43
|
+
this.minutesFormat = function(timeFormat) {
|
|
44
|
+
return splitTimeFormat(timeFormat)[2];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// h:mm a => :
|
|
48
|
+
this.timeSeparator = function(timeFormat) {
|
|
49
|
+
return splitTimeFormat(timeFormat)[1];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// h:mm a => true, H.mm => false
|
|
53
|
+
this.showAM = function(timeFormat) {
|
|
54
|
+
return !!splitTimeFormat(timeFormat)[3];
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
this.formatDate = function(date, format, lang){
|
|
58
|
+
return dateFilter(date, format);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
}]);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
"use strict";angular.module("mgcrea.ngStrap.helpers.dateFormatter",[]).service("$dateFormatter",["$locale","dateFilter",function(t,e){function r(t){return/(h+)([:\.])?(m+)[ ]?(a?)/i.exec(t).slice(1)}this.getDefaultLocale=function(){return t.id},this.getDatetimeFormat=function(e){return t.DATETIME_FORMATS[e]||e},this.weekdaysShort=function(){return t.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(t){return r(t)[0]},this.minutesFormat=function(t){return r(t)[2]},this.timeSeparator=function(t){return r(t)[1]},this.showAM=function(t){return!!r(t)[3]},this.formatDate=function(t,r){return e(t,r)}}]);
|
|
9
|
+
//# sourceMappingURL=date-formatter.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["helpers/date-formatter.js"],"names":[],"mappings":"+EAWS,kBAAmB,UAAW,aAAA,SAAA,EAAA,yEAOjC,iBAAe,2DAOjB,MAAS,GAAA,iBAAwB,IAAA,wOA4BhC,QAAA,EAAA,GAAA","file":"date-formatter.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[3];\n };\n\n this.formatDate = function(date, format, lang){\n return dateFilter(date, format);\n };\n\n });\n"],"sourceRoot":"/source/"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
angular.module('mgcrea.ngStrap.helpers.dateParser', [])
|
|
11
|
+
|
|
12
|
+
.provider('$dateParser', ["$localeProvider", function($localeProvider) {
|
|
13
|
+
|
|
14
|
+
// define a custom ParseDate object to use instead of native Date
|
|
15
|
+
// to avoid date values wrapping when setting date component values
|
|
16
|
+
function ParseDate() {
|
|
17
|
+
this.year = 1970;
|
|
18
|
+
this.month = 0;
|
|
19
|
+
this.day = 1;
|
|
20
|
+
this.hours = 0;
|
|
21
|
+
this.minutes = 0;
|
|
22
|
+
this.seconds = 0;
|
|
23
|
+
this.milliseconds = 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };
|
|
27
|
+
ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };
|
|
28
|
+
ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };
|
|
29
|
+
ParseDate.prototype.setHours = function(value) { this.hours = value; };
|
|
30
|
+
ParseDate.prototype.getHours = function() { return this.hours; };
|
|
31
|
+
ParseDate.prototype.setDate = function(value) { this.day = value; };
|
|
32
|
+
ParseDate.prototype.setMonth = function(value) { this.month = value; };
|
|
33
|
+
ParseDate.prototype.setFullYear = function(value) { this.year = value; };
|
|
34
|
+
ParseDate.prototype.fromDate = function(value) {
|
|
35
|
+
this.year = value.getFullYear();
|
|
36
|
+
this.month = value.getMonth();
|
|
37
|
+
this.day = value.getDate();
|
|
38
|
+
this.hours = value.getHours();
|
|
39
|
+
this.minutes = value.getMinutes();
|
|
40
|
+
this.seconds = value.getSeconds();
|
|
41
|
+
this.milliseconds = value.getMilliseconds();
|
|
42
|
+
return this;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
ParseDate.prototype.toDate = function() {
|
|
46
|
+
return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
var proto = ParseDate.prototype;
|
|
50
|
+
|
|
51
|
+
function noop() {
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function isNumeric(n) {
|
|
55
|
+
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function indexOfCaseInsensitive(array, value) {
|
|
59
|
+
var len = array.length, str=value.toString().toLowerCase();
|
|
60
|
+
for (var i=0; i<len; i++) {
|
|
61
|
+
if (array[i].toLowerCase() === str) { return i; }
|
|
62
|
+
}
|
|
63
|
+
return -1; // Return -1 per the "Array.indexOf()" method.
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var defaults = this.defaults = {
|
|
67
|
+
format: 'shortDate',
|
|
68
|
+
strict: false
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
this.$get = ["$locale", "dateFilter", function($locale, dateFilter) {
|
|
72
|
+
|
|
73
|
+
var DateParserFactory = function(config) {
|
|
74
|
+
|
|
75
|
+
var options = angular.extend({}, defaults, config);
|
|
76
|
+
|
|
77
|
+
var $dateParser = {};
|
|
78
|
+
|
|
79
|
+
var regExpMap = {
|
|
80
|
+
'sss' : '[0-9]{3}',
|
|
81
|
+
'ss' : '[0-5][0-9]',
|
|
82
|
+
's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',
|
|
83
|
+
'mm' : '[0-5][0-9]',
|
|
84
|
+
'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',
|
|
85
|
+
'HH' : '[01][0-9]|2[0-3]',
|
|
86
|
+
'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',
|
|
87
|
+
'hh' : '[0][1-9]|[1][012]',
|
|
88
|
+
'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',
|
|
89
|
+
'a' : 'AM|PM',
|
|
90
|
+
'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),
|
|
91
|
+
'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),
|
|
92
|
+
'dd' : '0[1-9]|[12][0-9]|3[01]',
|
|
93
|
+
'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',
|
|
94
|
+
'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),
|
|
95
|
+
'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),
|
|
96
|
+
'MM' : '0[1-9]|1[012]',
|
|
97
|
+
'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',
|
|
98
|
+
'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',
|
|
99
|
+
'yy' : '[0-9]{2}',
|
|
100
|
+
'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}',
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
var setFnMap = {
|
|
104
|
+
'sss' : proto.setMilliseconds,
|
|
105
|
+
'ss' : proto.setSeconds,
|
|
106
|
+
's' : proto.setSeconds,
|
|
107
|
+
'mm' : proto.setMinutes,
|
|
108
|
+
'm' : proto.setMinutes,
|
|
109
|
+
'HH' : proto.setHours,
|
|
110
|
+
'H' : proto.setHours,
|
|
111
|
+
'hh' : proto.setHours,
|
|
112
|
+
'h' : proto.setHours,
|
|
113
|
+
'EEEE' : noop,
|
|
114
|
+
'EEE' : noop,
|
|
115
|
+
'dd' : proto.setDate,
|
|
116
|
+
'd' : proto.setDate,
|
|
117
|
+
'a' : function(value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },
|
|
118
|
+
'MMMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },
|
|
119
|
+
'MMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },
|
|
120
|
+
'MM' : function(value) { return this.setMonth(1 * value - 1); },
|
|
121
|
+
'M' : function(value) { return this.setMonth(1 * value - 1); },
|
|
122
|
+
'yyyy' : proto.setFullYear,
|
|
123
|
+
'yy' : function(value) { return this.setFullYear(2000 + 1 * value); },
|
|
124
|
+
'y' : proto.setFullYear
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
var regex, setMap;
|
|
128
|
+
|
|
129
|
+
$dateParser.init = function() {
|
|
130
|
+
$dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;
|
|
131
|
+
regex = regExpForFormat($dateParser.$format);
|
|
132
|
+
setMap = setMapForFormat($dateParser.$format);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
$dateParser.isValid = function(date) {
|
|
136
|
+
if(angular.isDate(date)) return !isNaN(date.getTime());
|
|
137
|
+
return regex.test(date);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
$dateParser.parse = function(value, baseDate, format) {
|
|
141
|
+
// check for date format special names
|
|
142
|
+
if(format) format = $locale.DATETIME_FORMATS[format] || format;
|
|
143
|
+
if(angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format);
|
|
144
|
+
var formatRegex = format ? regExpForFormat(format) : regex;
|
|
145
|
+
var formatSetMap = format ? setMapForFormat(format) : setMap;
|
|
146
|
+
var matches = formatRegex.exec(value);
|
|
147
|
+
if(!matches) return false;
|
|
148
|
+
// use custom ParseDate object to set parsed values
|
|
149
|
+
var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));
|
|
150
|
+
for(var i = 0; i < matches.length - 1; i++) {
|
|
151
|
+
formatSetMap[i] && formatSetMap[i].call(date, matches[i+1]);
|
|
152
|
+
}
|
|
153
|
+
// convert back to native Date object
|
|
154
|
+
var newDate = date.toDate();
|
|
155
|
+
|
|
156
|
+
// check new native Date object for day values overflow
|
|
157
|
+
if (parseInt(date.day, 10) !== newDate.getDate()) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return newDate;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
$dateParser.getDateForAttribute = function(key, value) {
|
|
165
|
+
var date;
|
|
166
|
+
|
|
167
|
+
if(value === 'today') {
|
|
168
|
+
var today = new Date();
|
|
169
|
+
date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));
|
|
170
|
+
} else if(angular.isString(value) && value.match(/^".+"$/)) { // Support {{ dateObj }}
|
|
171
|
+
date = new Date(value.substr(1, value.length - 2));
|
|
172
|
+
} else if(isNumeric(value)) {
|
|
173
|
+
date = new Date(parseInt(value, 10));
|
|
174
|
+
} else if (angular.isString(value) && 0 === value.length) { // Reset date
|
|
175
|
+
date = key === 'minDate' ? -Infinity : +Infinity;
|
|
176
|
+
} else {
|
|
177
|
+
date = new Date(value);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return date;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
$dateParser.getTimeForAttribute = function(key, value) {
|
|
184
|
+
var time;
|
|
185
|
+
|
|
186
|
+
if(value === 'now') {
|
|
187
|
+
time = new Date().setFullYear(1970, 0, 1);
|
|
188
|
+
} else if(angular.isString(value) && value.match(/^".+"$/)) {
|
|
189
|
+
time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);
|
|
190
|
+
} else if(isNumeric(value)) {
|
|
191
|
+
time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);
|
|
192
|
+
} else if (angular.isString(value) && 0 === value.length) { // Reset time
|
|
193
|
+
time = key === 'minTime' ? -Infinity : +Infinity;
|
|
194
|
+
} else {
|
|
195
|
+
time = $dateParser.parse(value, new Date(1970, 0, 1, 0));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return time;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/* Handle switch to/from daylight saving.
|
|
202
|
+
* Hours may be non-zero on daylight saving cut-over:
|
|
203
|
+
* > 12 when midnight changeover, but then cannot generate
|
|
204
|
+
* midnight datetime, so jump to 1AM, otherwise reset.
|
|
205
|
+
* @param date (Date) the date to check
|
|
206
|
+
* @return (Date) the corrected date
|
|
207
|
+
*
|
|
208
|
+
* __ copied from jquery ui datepicker __
|
|
209
|
+
*/
|
|
210
|
+
$dateParser.daylightSavingAdjust = function(date) {
|
|
211
|
+
if (!date) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
|
|
215
|
+
return date;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Private functions
|
|
219
|
+
|
|
220
|
+
function setMapForFormat(format) {
|
|
221
|
+
var keys = Object.keys(setFnMap), i;
|
|
222
|
+
var map = [], sortedMap = [];
|
|
223
|
+
// Map to setFn
|
|
224
|
+
var clonedFormat = format;
|
|
225
|
+
for(i = 0; i < keys.length; i++) {
|
|
226
|
+
if(format.split(keys[i]).length > 1) {
|
|
227
|
+
var index = clonedFormat.search(keys[i]);
|
|
228
|
+
format = format.split(keys[i]).join('');
|
|
229
|
+
if(setFnMap[keys[i]]) {
|
|
230
|
+
map[index] = setFnMap[keys[i]];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Sort result map
|
|
235
|
+
angular.forEach(map, function(v) {
|
|
236
|
+
// conditional required since angular.forEach broke around v1.2.21
|
|
237
|
+
// related pr: https://github.com/angular/angular.js/pull/8525
|
|
238
|
+
if(v) sortedMap.push(v);
|
|
239
|
+
});
|
|
240
|
+
return sortedMap;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function escapeReservedSymbols(text) {
|
|
244
|
+
return text.replace(/\//g, '[\\/]').replace('/-/g', '[-]').replace(/\./g, '[.]').replace(/\\s/g, '[\\s]');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function regExpForFormat(format) {
|
|
248
|
+
var keys = Object.keys(regExpMap), i;
|
|
249
|
+
|
|
250
|
+
var re = format;
|
|
251
|
+
// Abstract replaces to avoid collisions
|
|
252
|
+
for(i = 0; i < keys.length; i++) {
|
|
253
|
+
re = re.split(keys[i]).join('${' + i + '}');
|
|
254
|
+
}
|
|
255
|
+
// Replace abstracted values
|
|
256
|
+
for(i = 0; i < keys.length; i++) {
|
|
257
|
+
re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');
|
|
258
|
+
}
|
|
259
|
+
format = escapeReservedSymbols(format);
|
|
260
|
+
|
|
261
|
+
return new RegExp('^' + re + '$', ['i']);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
$dateParser.init();
|
|
265
|
+
return $dateParser;
|
|
266
|
+
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
return DateParserFactory;
|
|
270
|
+
|
|
271
|
+
}];
|
|
272
|
+
|
|
273
|
+
}]);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
"use strict";angular.module("mgcrea.ngStrap.helpers.dateParser",[]).provider("$dateParser",["$localeProvider",function(){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function e(){}function s(t){return!isNaN(parseFloat(t))&&isFinite(t)}function n(t,e){for(var s=t.length,n=e.toString().toLowerCase(),r=0;s>r;r++)if(t[r].toLowerCase()===n)return r;return-1}t.prototype.setMilliseconds=function(t){this.milliseconds=t},t.prototype.setSeconds=function(t){this.seconds=t},t.prototype.setMinutes=function(t){this.minutes=t},t.prototype.setHours=function(t){this.hours=t},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(t){this.day=t},t.prototype.setMonth=function(t){this.month=t},t.prototype.setFullYear=function(t){this.year=t},t.prototype.fromDate=function(t){return this.year=t.getFullYear(),this.month=t.getMonth(),this.day=t.getDate(),this.hours=t.getHours(),this.minutes=t.getMinutes(),this.seconds=t.getSeconds(),this.milliseconds=t.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var r=t.prototype,i=this.defaults={format:"shortDate",strict:!1};this.$get=["$locale","dateFilter",function(o,a){var u=function(u){function h(t){var e,s=Object.keys(d),n=[],r=[],i=t;for(e=0;e<s.length;e++)if(t.split(s[e]).length>1){var o=i.search(s[e]);t=t.split(s[e]).join(""),d[s[e]]&&(n[o]=d[s[e]])}return angular.forEach(n,function(t){t&&r.push(t)}),r}function l(t){return t.replace(/\//g,"[\\/]").replace("/-/g","[-]").replace(/\./g,"[.]").replace(/\\s/g,"[\\s]")}function c(t){var e,s=Object.keys(m),n=t;for(e=0;e<s.length;e++)n=n.split(s[e]).join("${"+e+"}");for(e=0;e<s.length;e++)n=n.split("${"+e+"}").join("("+m[s[e]]+")");return t=l(t),new RegExp("^"+n+"$",["i"])}var M,f,g=angular.extend({},i,u),p={},m={sss:"[0-9]{3}",ss:"[0-5][0-9]",s:g.strict?"[1-5]?[0-9]":"[0-9]|[0-5][0-9]",mm:"[0-5][0-9]",m:g.strict?"[1-5]?[0-9]":"[0-9]|[0-5][0-9]",HH:"[01][0-9]|2[0-3]",H:g.strict?"1?[0-9]|2[0-3]":"[01]?[0-9]|2[0-3]",hh:"[0][1-9]|[1][012]",h:g.strict?"[1-9]|1[012]":"0?[1-9]|1[012]",a:"AM|PM",EEEE:o.DATETIME_FORMATS.DAY.join("|"),EEE:o.DATETIME_FORMATS.SHORTDAY.join("|"),dd:"0[1-9]|[12][0-9]|3[01]",d:g.strict?"[1-9]|[1-2][0-9]|3[01]":"0?[1-9]|[1-2][0-9]|3[01]",MMMM:o.DATETIME_FORMATS.MONTH.join("|"),MMM:o.DATETIME_FORMATS.SHORTMONTH.join("|"),MM:"0[1-9]|1[012]",M:g.strict?"[1-9]|1[012]":"0?[1-9]|1[012]",yyyy:"[1]{1}[0-9]{3}|[2]{1}[0-9]{3}",yy:"[0-9]{2}",y:g.strict?"-?(0|[1-9][0-9]{0,3})":"-?0*[0-9]{1,4}"},d={sss:r.setMilliseconds,ss:r.setSeconds,s:r.setSeconds,mm:r.setMinutes,m:r.setMinutes,HH:r.setHours,H:r.setHours,hh:r.setHours,h:r.setHours,EEEE:e,EEE:e,dd:r.setDate,d:r.setDate,a:function(t){var e=this.getHours()%12;return this.setHours(t.match(/pm/i)?e+12:e)},MMMM:function(t){return this.setMonth(n(o.DATETIME_FORMATS.MONTH,t))},MMM:function(t){return this.setMonth(n(o.DATETIME_FORMATS.SHORTMONTH,t))},MM:function(t){return this.setMonth(1*t-1)},M:function(t){return this.setMonth(1*t-1)},yyyy:r.setFullYear,yy:function(t){return this.setFullYear(2e3+1*t)},y:r.setFullYear};return p.init=function(){p.$format=o.DATETIME_FORMATS[g.format]||g.format,M=c(p.$format),f=h(p.$format)},p.isValid=function(t){return angular.isDate(t)?!isNaN(t.getTime()):M.test(t)},p.parse=function(e,s,n){n&&(n=o.DATETIME_FORMATS[n]||n),angular.isDate(e)&&(e=a(e,n||p.$format));var r=n?c(n):M,i=n?h(n):f,u=r.exec(e);if(!u)return!1;for(var l=(new t).fromDate(s&&!isNaN(s.getTime())?s:new Date(1970,0,1,0)),g=0;g<u.length-1;g++)i[g]&&i[g].call(l,u[g+1]);var m=l.toDate();return parseInt(l.day,10)!==m.getDate()?!1:m},p.getDateForAttribute=function(t,e){var n;if("today"===e){var r=new Date;n=new Date(r.getFullYear(),r.getMonth(),r.getDate()+("maxDate"===t?1:0),0,0,0,"minDate"===t?0:-1)}else n=angular.isString(e)&&e.match(/^".+"$/)?new Date(e.substr(1,e.length-2)):s(e)?new Date(parseInt(e,10)):angular.isString(e)&&0===e.length?"minDate"===t?-1/0:+1/0:new Date(e);return n},p.getTimeForAttribute=function(t,e){var n;return n="now"===e?(new Date).setFullYear(1970,0,1):angular.isString(e)&&e.match(/^".+"$/)?new Date(e.substr(1,e.length-2)).setFullYear(1970,0,1):s(e)?new Date(parseInt(e,10)).setFullYear(1970,0,1):angular.isString(e)&&0===e.length?"minTime"===t?-1/0:+1/0:p.parse(e,new Date(1970,0,1,0))},p.daylightSavingAdjust=function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},p.init(),p};return u}]}]);
|
|
9
|
+
//# sourceMappingURL=date-parser.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["helpers/date-parser.js"],"names":[],"mappings":"qBASI,OAAK,iDAEA,eAAM,kBAAA,mBAIN,iCAGP,KAAA,IAAU,EACV,KAAA,MAAU,EACV,KAAA,QAAU,EACV,KAAA,QAAU,EACV,KAAA,aAAoB,EA4BpB,QAAS,cAGD,GAAS,4DAMf,IAAA,GADE,GAAA,EAAW,OAAK,EAAA,EAAW,WAAA,cACrB,EAAA,EAAA,EAAA,EAAA,IACR,GAAA,EAAQ,GAAA,gBAAA,EAAA,MAAA,YAnCV,EAAU,UAAU,gBAAc,SAAS,GAAS,KAAK,aAAO,GAChE,EAAU,UAAU,WAAW,SAAS,GAAO,KAAA,QAAA,KACxC,UAAa,WAAA,SAAA,GAAA,KAAA,QAAA,KACb,UAAQ,SAAM,SAAA,GAAA,KAAA,MAAA,KACd,UAAY,SAAA,WAAA,MAAA,MAAA,SACZ,UAAQ,QAAM,SAAA,GAAA,KAAA,IAAA,KACd,UAAU,SAAM,SAAA,GAAA,KAAA,MAAA,KAChB,UAAU,YAAM,SAAA,GAAA,KAAA,KAAA,KAChB,UAAA,SAAqB,SAAA,GAQ5B,MAPE,MAAA,KAAO,EAAA,2DAGT,KAAA,MAAU,EAAU,WAClB,KAAA,QAAW,EAAU,+EAGnB,6JAwBF,EAAI,KAAA,qCAEE,sDAKF,GAAU,SAAA,WAmJN,GAAY,MACe,GAA3B,EAAA,OAAS,KAAO,GAChB,KAAG,+EAMP,GAAQ,EAAQ,MAAK,EAAS,IAAG,KAAA,4BAYnC,oDAAS,UAGH,GAAK,2IAOP,EAAK,CAEP,KAAA,EAAA,EAAS,EAAA,EAAA,OAAA,4DAKX,EAAA,EAAY,MAAA,KAAA,EAAA,KAAA,KAAA,IAAA,EAAA,EAAA,IAAA,uDAtLV,EAAU,QAAQ,UAAS,EAAA,GAE3B,KAEA,GACA,IAAU,WACV,GAAU,aACV,EAAU,EAAA,OAAA,cAAA,mBACV,GAAU,aACV,EAAU,EAAQ,OAAA,cAAiB,mBACnC,GAAU,mBACV,EAAU,EAAQ,OAAS,iBAAA,oBAC3B,GAAU,oBACV,EAAU,EAAQ,OAAA,eAAiB,iBACnC,EAAU,QACV,KAAU,EAAQ,iBAAS,IAAA,KAAiB,KAC5C,IAAU,EAAA,iBAAA,SAAA,KAAA,KACV,GAAU,yBACV,EAAU,EAAQ,OAAS,yBAA0B,+GAGvD,GAAI,gBACF,EAAU,EAAM,OAAA,eAAA,iBAChB,KAAU,gCACV,GAAU,WACV,EAAU,EAAM,OAAA,wBAAA,kBAGhB,GACA,IAAU,EAAM,gBAChB,GAAU,EAAM,WAChB,EAAU,EAAA,WACV,GAAU,EAAA,WACV,EAAU,EAAM,WAChB,GAAU,EAAM,SAChB,EAAU,EAAA,SACV,GAAU,EAAA,SACV,EAAU,EAAA,SACV,KAAU,EACV,IAAU,EACV,GAAU,EAAM,QAChB,EAAU,EAAA,QACV,EAAU,SAAM,GAAA,GAAA,GAAA,KAAA,WAAA,EAAA,OAAA,MAAA,SAAA,EAAA,MAAA,OAAA,EAAA,GAAA,oJAGlB,GAAW,SAAA,GAAA,MAAA,MAAA,SAAA,EAAA,EAAA,+CAEX,KAAY,EAAA,YACV,GAAA,SAAY,GAAU,MAAQ,MAAA,YAAiB,IAAQ,EAAA,IACvD,EAAQ,EAAA,sBAKL,KAAQ,WACX,EAAO,QAAW,EAAA,iBAAA,EAAA,SAAA,EAAA,wCAKf,QAAiB,SAAQ,GAC5B,MAAG,SAAQ,OAAO,IAAQ,MAAQ,EAAA,WAC9B,EAAA,KAAc,MAGd,MAAS,SAAO,EAAA,EAAA,GAEpB,IAAW,EAAA,EAAa,iBAAe,IAAiB,GACxD,QAAQ,OAAO,KAAI,EAAQ,EAAiB,EAAA,GAAA,EAAA,aAC1C,GAAa,EAAM,EAAqB,GAAM,wBAGhD,KAAI,EAAA,OAAe,CAGnB,KAAI,sEAAA,EAAA,EAAS,EAAK,EAAK,OAAQ,EAAQ,IACrC,EAAO,IAAA,EAAA,GAAA,KAAA,EAAA,EAAA,EAAA,GAGT,IAAA,GAAO,EAAA,QAGT,OAAA,UAAY,EAAA,IAAA,MAAA,EAAsB,WAC5B,EAGE,KAGG,oBAAsB,SAAS,EAAA,YAG7B,YAAQ,CACjB,GAAA,GAAO,GAAQ,QACV,GAAA,MAAA,EAAA,cAAA,EAAA,WAAA,EAAA,WAAA,YAAA,EAAA,EAAA,GAAA,EAAA,EAAA,EAAA,YAAA,EAAA,EAAA,WACE,QAAS,SAAA,IAAA,EAAA,MAAA,gDAGX,GAAA,MAAA,SAAA,EAAA,+DAIH,GAAA,MAAA,SAGF,MAGQ,oBAAkB,SAAA,EAAA,MAC1B,YAEO,QAAP,GACK,GAAA,OAAA,YAAA,KAAA,EAAA,GACE,QAAA,SAAkB,IAAO,EAAS,MAAM,sEAG1C,GAAA,MAAA,SAAA,EAAA,KAAA,YAAA,KAAA,EAAA,2IAuBP,EAAI,SAAO,EAAO,WAAK,GAAW,EAAA,WAAA,EAAA,GAC9B","file":"date-parser.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i<len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function($locale, dateFilter) {\n\n var DateParserFactory = function(config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}',\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function(value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function(value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function(value) { return this.setMonth(1 * value - 1); },\n 'M' : function(value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function(value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : proto.setFullYear\n };\n\n var regex, setMap;\n\n $dateParser.init = function() {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function(date) {\n if(angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function(value, baseDate, format) {\n // check for date format special names\n if(format) format = $locale.DATETIME_FORMATS[format] || format;\n if(angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if(!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for(var i = 0; i < matches.length - 1; i++) {\n formatSetMap[i] && formatSetMap[i].call(date, matches[i+1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function(key, value) {\n var date;\n\n if(value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if(angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if(isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && 0 === value.length) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function(key, value) {\n var time;\n\n if(value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if(angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if(isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && 0 === value.length) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n"],"sourceRoot":"/source/"}
|
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
angular.module('mgcrea.ngStrap.datepicker', [
|
|
11
|
+
'mgcrea.ngStrap.helpers.dateParser',
|
|
12
|
+
'mgcrea.ngStrap.helpers.dateFormatter',
|
|
13
|
+
'mgcrea.ngStrap.tooltip'])
|
|
14
|
+
|
|
15
|
+
.provider('$datepicker', function() {
|
|
16
|
+
|
|
17
|
+
var defaults = this.defaults = {
|
|
18
|
+
animation: 'am-fade',
|
|
19
|
+
prefixClass: 'datepicker',
|
|
20
|
+
placement: 'bottom-left',
|
|
21
|
+
template: 'datepicker/datepicker.tpl.html',
|
|
22
|
+
trigger: 'focus',
|
|
23
|
+
container: false,
|
|
24
|
+
keyboard: true,
|
|
25
|
+
html: false,
|
|
26
|
+
delay: 0,
|
|
27
|
+
// lang: $locale.id,
|
|
28
|
+
useNative: false,
|
|
29
|
+
dateType: 'date',
|
|
30
|
+
dateFormat: 'shortDate',
|
|
31
|
+
modelDateFormat: null,
|
|
32
|
+
dayFormat: 'dd',
|
|
33
|
+
monthFormat: 'MMM',
|
|
34
|
+
yearFormat: 'yyyy',
|
|
35
|
+
monthTitleFormat: 'MMMM yyyy',
|
|
36
|
+
yearTitleFormat: 'yyyy',
|
|
37
|
+
strictFormat: false,
|
|
38
|
+
autoclose: false,
|
|
39
|
+
minDate: -Infinity,
|
|
40
|
+
maxDate: +Infinity,
|
|
41
|
+
startView: 0,
|
|
42
|
+
minView: 0,
|
|
43
|
+
startWeek: 0,
|
|
44
|
+
daysOfWeekDisabled: '',
|
|
45
|
+
iconLeft: 'glyphicon glyphicon-chevron-left',
|
|
46
|
+
iconRight: 'glyphicon glyphicon-chevron-right'
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
this.$get = ["$window", "$document", "$rootScope", "$sce", "$dateFormatter", "datepickerViews", "$tooltip", "$timeout", function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {
|
|
50
|
+
|
|
51
|
+
var bodyEl = angular.element($window.document.body);
|
|
52
|
+
var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);
|
|
53
|
+
var isTouch = ('createTouch' in $window.document) && isNative;
|
|
54
|
+
if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();
|
|
55
|
+
|
|
56
|
+
function DatepickerFactory(element, controller, config) {
|
|
57
|
+
|
|
58
|
+
var $datepicker = $tooltip(element, angular.extend({}, defaults, config));
|
|
59
|
+
var parentScope = config.scope;
|
|
60
|
+
var options = $datepicker.$options;
|
|
61
|
+
var scope = $datepicker.$scope;
|
|
62
|
+
if(options.startView) options.startView -= options.minView;
|
|
63
|
+
|
|
64
|
+
// View vars
|
|
65
|
+
|
|
66
|
+
var pickerViews = datepickerViews($datepicker);
|
|
67
|
+
$datepicker.$views = pickerViews.views;
|
|
68
|
+
var viewDate = pickerViews.viewDate;
|
|
69
|
+
scope.$mode = options.startView;
|
|
70
|
+
scope.$iconLeft = options.iconLeft;
|
|
71
|
+
scope.$iconRight = options.iconRight;
|
|
72
|
+
var $picker = $datepicker.$views[scope.$mode];
|
|
73
|
+
|
|
74
|
+
// Scope methods
|
|
75
|
+
|
|
76
|
+
scope.$select = function(date) {
|
|
77
|
+
$datepicker.select(date);
|
|
78
|
+
};
|
|
79
|
+
scope.$selectPane = function(value) {
|
|
80
|
+
$datepicker.$selectPane(value);
|
|
81
|
+
};
|
|
82
|
+
scope.$toggleMode = function() {
|
|
83
|
+
$datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Public methods
|
|
87
|
+
|
|
88
|
+
$datepicker.update = function(date) {
|
|
89
|
+
// console.warn('$datepicker.update() newValue=%o', date);
|
|
90
|
+
if(angular.isDate(date) && !isNaN(date.getTime())) {
|
|
91
|
+
$datepicker.$date = date;
|
|
92
|
+
$picker.update.call($picker, date);
|
|
93
|
+
}
|
|
94
|
+
// Build only if pristine
|
|
95
|
+
$datepicker.$build(true);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
$datepicker.updateDisabledDates = function(dateRanges) {
|
|
99
|
+
options.disabledDateRanges = dateRanges;
|
|
100
|
+
for(var i = 0, l = scope.rows.length; i < l; i++) {
|
|
101
|
+
angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
$datepicker.select = function(date, keep) {
|
|
106
|
+
// console.warn('$datepicker.select', date, scope.$mode);
|
|
107
|
+
if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);
|
|
108
|
+
if(!scope.$mode || keep) {
|
|
109
|
+
controller.$setViewValue(angular.copy(date));
|
|
110
|
+
controller.$render();
|
|
111
|
+
if(options.autoclose && !keep) {
|
|
112
|
+
$timeout(function() { $datepicker.hide(true); });
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});
|
|
116
|
+
$datepicker.setMode(scope.$mode - 1);
|
|
117
|
+
$datepicker.$build();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
$datepicker.setMode = function(mode) {
|
|
122
|
+
// console.warn('$datepicker.setMode', mode);
|
|
123
|
+
scope.$mode = mode;
|
|
124
|
+
$picker = $datepicker.$views[scope.$mode];
|
|
125
|
+
$datepicker.$build();
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Protected methods
|
|
129
|
+
|
|
130
|
+
$datepicker.$build = function(pristine) {
|
|
131
|
+
// console.warn('$datepicker.$build() viewDate=%o', viewDate);
|
|
132
|
+
if(pristine === true && $picker.built) return;
|
|
133
|
+
if(pristine === false && !$picker.built) return;
|
|
134
|
+
$picker.build.call($picker);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
$datepicker.$updateSelected = function() {
|
|
138
|
+
for(var i = 0, l = scope.rows.length; i < l; i++) {
|
|
139
|
+
angular.forEach(scope.rows[i], updateSelected);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
$datepicker.$isSelected = function(date) {
|
|
144
|
+
return $picker.isSelected(date);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
$datepicker.$setDisabledEl = function(el) {
|
|
148
|
+
el.disabled = $picker.isDisabled(el.date);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
$datepicker.$selectPane = function(value) {
|
|
152
|
+
var steps = $picker.steps;
|
|
153
|
+
// set targetDate to first day of month to avoid problems with
|
|
154
|
+
// date values rollover. This assumes the viewDate does not
|
|
155
|
+
// depend on the day of the month
|
|
156
|
+
var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));
|
|
157
|
+
angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});
|
|
158
|
+
$datepicker.$build();
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
$datepicker.$onMouseDown = function(evt) {
|
|
162
|
+
// Prevent blur on mousedown on .dropdown-menu
|
|
163
|
+
evt.preventDefault();
|
|
164
|
+
evt.stopPropagation();
|
|
165
|
+
// Emulate click for mobile devices
|
|
166
|
+
if(isTouch) {
|
|
167
|
+
var targetEl = angular.element(evt.target);
|
|
168
|
+
if(targetEl[0].nodeName.toLowerCase() !== 'button') {
|
|
169
|
+
targetEl = targetEl.parent();
|
|
170
|
+
}
|
|
171
|
+
targetEl.triggerHandler('click');
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
$datepicker.$onKeyDown = function(evt) {
|
|
176
|
+
if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;
|
|
177
|
+
evt.preventDefault();
|
|
178
|
+
evt.stopPropagation();
|
|
179
|
+
|
|
180
|
+
if(evt.keyCode === 13) {
|
|
181
|
+
if(!scope.$mode) {
|
|
182
|
+
return $datepicker.hide(true);
|
|
183
|
+
} else {
|
|
184
|
+
return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Navigate with keyboard
|
|
189
|
+
$picker.onKeyDown(evt);
|
|
190
|
+
parentScope.$digest();
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Private
|
|
194
|
+
|
|
195
|
+
function updateSelected(el) {
|
|
196
|
+
el.selected = $datepicker.$isSelected(el.date);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function focusElement() {
|
|
200
|
+
element[0].focus();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Overrides
|
|
204
|
+
|
|
205
|
+
var _init = $datepicker.init;
|
|
206
|
+
$datepicker.init = function() {
|
|
207
|
+
if(isNative && options.useNative) {
|
|
208
|
+
element.prop('type', 'date');
|
|
209
|
+
element.css('-webkit-appearance', 'textfield');
|
|
210
|
+
return;
|
|
211
|
+
} else if(isTouch) {
|
|
212
|
+
element.prop('type', 'text');
|
|
213
|
+
element.attr('readonly', 'true');
|
|
214
|
+
element.on('click', focusElement);
|
|
215
|
+
}
|
|
216
|
+
_init();
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
var _destroy = $datepicker.destroy;
|
|
220
|
+
$datepicker.destroy = function() {
|
|
221
|
+
if(isNative && options.useNative) {
|
|
222
|
+
element.off('click', focusElement);
|
|
223
|
+
}
|
|
224
|
+
_destroy();
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
var _show = $datepicker.show;
|
|
228
|
+
$datepicker.show = function() {
|
|
229
|
+
_show();
|
|
230
|
+
// use timeout to hookup the events to prevent
|
|
231
|
+
// event bubbling from being processed imediately.
|
|
232
|
+
$timeout(function() {
|
|
233
|
+
// if $datepicker is no longer showing, don't setup events
|
|
234
|
+
if(!$datepicker.$isShown) return;
|
|
235
|
+
$datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);
|
|
236
|
+
if(options.keyboard) {
|
|
237
|
+
element.on('keydown', $datepicker.$onKeyDown);
|
|
238
|
+
}
|
|
239
|
+
}, 0, false);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
var _hide = $datepicker.hide;
|
|
243
|
+
$datepicker.hide = function(blur) {
|
|
244
|
+
if(!$datepicker.$isShown) return;
|
|
245
|
+
$datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);
|
|
246
|
+
if(options.keyboard) {
|
|
247
|
+
element.off('keydown', $datepicker.$onKeyDown);
|
|
248
|
+
}
|
|
249
|
+
_hide(blur);
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
return $datepicker;
|
|
253
|
+
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
DatepickerFactory.defaults = defaults;
|
|
257
|
+
return DatepickerFactory;
|
|
258
|
+
|
|
259
|
+
}];
|
|
260
|
+
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
.directive('bsDatepicker', ["$window", "$parse", "$q", "$dateFormatter", "$dateParser", "$datepicker", function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {
|
|
264
|
+
|
|
265
|
+
var defaults = $datepicker.defaults;
|
|
266
|
+
var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
restrict: 'EAC',
|
|
270
|
+
require: 'ngModel',
|
|
271
|
+
link: function postLink(scope, element, attr, controller) {
|
|
272
|
+
|
|
273
|
+
// Directive options
|
|
274
|
+
var options = {scope: scope, controller: controller};
|
|
275
|
+
angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', 'autoclose', 'dateType', 'dateFormat', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id'], function(key) {
|
|
276
|
+
if(angular.isDefined(attr[key])) options[key] = attr[key];
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Visibility binding support
|
|
280
|
+
attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {
|
|
281
|
+
if(!datepicker || !angular.isDefined(newValue)) return;
|
|
282
|
+
if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);
|
|
283
|
+
newValue === true ? datepicker.show() : datepicker.hide();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Initialize datepicker
|
|
287
|
+
var datepicker = $datepicker(element, controller, options);
|
|
288
|
+
options = datepicker.$options;
|
|
289
|
+
// Set expected iOS format
|
|
290
|
+
if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';
|
|
291
|
+
|
|
292
|
+
var lang = options.lang;
|
|
293
|
+
|
|
294
|
+
var formatDate = function(date, format) {
|
|
295
|
+
return $dateFormatter.formatDate(date, format, lang);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});
|
|
299
|
+
|
|
300
|
+
// Observe attributes for changes
|
|
301
|
+
angular.forEach(['minDate', 'maxDate'], function(key) {
|
|
302
|
+
// console.warn('attr.$observe(%s)', key, attr[key]);
|
|
303
|
+
angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {
|
|
304
|
+
// console.warn('attr.$observe(%s)=%o', key, newValue);
|
|
305
|
+
datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);
|
|
306
|
+
// Build only if dirty
|
|
307
|
+
!isNaN(datepicker.$options[key]) && datepicker.$build(false);
|
|
308
|
+
validateAgainstMinMaxDate(controller.$dateValue);
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Watch model for changes
|
|
313
|
+
scope.$watch(attr.ngModel, function(newValue, oldValue) {
|
|
314
|
+
datepicker.update(controller.$dateValue);
|
|
315
|
+
}, true);
|
|
316
|
+
|
|
317
|
+
// Normalize undefined/null/empty array,
|
|
318
|
+
// so that we don't treat changing from undefined->null as a change.
|
|
319
|
+
function normalizeDateRanges(ranges) {
|
|
320
|
+
if (!ranges || !ranges.length) return null;
|
|
321
|
+
return ranges;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (angular.isDefined(attr.disabledDates)) {
|
|
325
|
+
scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {
|
|
326
|
+
disabledRanges = normalizeDateRanges(disabledRanges);
|
|
327
|
+
previousValue = normalizeDateRanges(previousValue);
|
|
328
|
+
|
|
329
|
+
if (disabledRanges) {
|
|
330
|
+
datepicker.updateDisabledDates(disabledRanges);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function validateAgainstMinMaxDate(parsedDate) {
|
|
336
|
+
if (!angular.isDate(parsedDate)) return;
|
|
337
|
+
var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;
|
|
338
|
+
var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;
|
|
339
|
+
var isValid = isMinValid && isMaxValid;
|
|
340
|
+
controller.$setValidity('date', isValid);
|
|
341
|
+
controller.$setValidity('min', isMinValid);
|
|
342
|
+
controller.$setValidity('max', isMaxValid);
|
|
343
|
+
// Only update the model when we have a valid date
|
|
344
|
+
if(isValid) controller.$dateValue = parsedDate;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// viewValue -> $parsers -> modelValue
|
|
348
|
+
controller.$parsers.unshift(function(viewValue) {
|
|
349
|
+
// console.warn('$parser("%s"): viewValue=%o', element.attr('ng-model'), viewValue);
|
|
350
|
+
// Null values should correctly reset the model value & validity
|
|
351
|
+
if(!viewValue) {
|
|
352
|
+
controller.$setValidity('date', true);
|
|
353
|
+
// BREAKING CHANGE:
|
|
354
|
+
// return null (not undefined) when input value is empty, so angularjs 1.3
|
|
355
|
+
// ngModelController can go ahead and run validators, like ngRequired
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
var parsedDate = dateParser.parse(viewValue, controller.$dateValue);
|
|
359
|
+
if(!parsedDate || isNaN(parsedDate.getTime())) {
|
|
360
|
+
controller.$setValidity('date', false);
|
|
361
|
+
// return undefined, causes ngModelController to
|
|
362
|
+
// invalidate model value
|
|
363
|
+
return;
|
|
364
|
+
} else {
|
|
365
|
+
validateAgainstMinMaxDate(parsedDate);
|
|
366
|
+
}
|
|
367
|
+
if(options.dateType === 'string') {
|
|
368
|
+
return formatDate(parsedDate, options.modelDateFormat || options.dateFormat);
|
|
369
|
+
} else if(options.dateType === 'number') {
|
|
370
|
+
return controller.$dateValue.getTime();
|
|
371
|
+
} else if(options.dateType === 'unix') {
|
|
372
|
+
return controller.$dateValue.getTime() / 1000;
|
|
373
|
+
} else if(options.dateType === 'iso') {
|
|
374
|
+
return controller.$dateValue.toISOString();
|
|
375
|
+
} else {
|
|
376
|
+
return new Date(controller.$dateValue);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// modelValue -> $formatters -> viewValue
|
|
381
|
+
controller.$formatters.push(function(modelValue) {
|
|
382
|
+
// console.warn('$formatter("%s"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);
|
|
383
|
+
var date;
|
|
384
|
+
if(angular.isUndefined(modelValue) || modelValue === null) {
|
|
385
|
+
date = NaN;
|
|
386
|
+
} else if(angular.isDate(modelValue)) {
|
|
387
|
+
date = modelValue;
|
|
388
|
+
} else if(options.dateType === 'string') {
|
|
389
|
+
date = dateParser.parse(modelValue, null, options.modelDateFormat);
|
|
390
|
+
} else if(options.dateType === 'unix') {
|
|
391
|
+
date = new Date(modelValue * 1000);
|
|
392
|
+
} else {
|
|
393
|
+
date = new Date(modelValue);
|
|
394
|
+
}
|
|
395
|
+
// Setup default value?
|
|
396
|
+
// if(isNaN(date.getTime())) {
|
|
397
|
+
// var today = new Date();
|
|
398
|
+
// date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);
|
|
399
|
+
// }
|
|
400
|
+
controller.$dateValue = date;
|
|
401
|
+
return getDateFormattedString();
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// viewValue -> element
|
|
405
|
+
controller.$render = function() {
|
|
406
|
+
// console.warn('$render("%s"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);
|
|
407
|
+
element.val(getDateFormattedString());
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
function getDateFormattedString() {
|
|
411
|
+
return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Garbage collection
|
|
415
|
+
scope.$on('$destroy', function() {
|
|
416
|
+
if(datepicker) datepicker.destroy();
|
|
417
|
+
options = null;
|
|
418
|
+
datepicker = null;
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
}])
|
|
425
|
+
|
|
426
|
+
.provider('datepickerViews', function() {
|
|
427
|
+
|
|
428
|
+
var defaults = this.defaults = {
|
|
429
|
+
dayFormat: 'dd',
|
|
430
|
+
daySplit: 7
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
// Split array into smaller arrays
|
|
434
|
+
function split(arr, size) {
|
|
435
|
+
var arrays = [];
|
|
436
|
+
while(arr.length > 0) {
|
|
437
|
+
arrays.push(arr.splice(0, size));
|
|
438
|
+
}
|
|
439
|
+
return arrays;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Modulus operator
|
|
443
|
+
function mod(n, m) {
|
|
444
|
+
return ((n % m) + m) % m;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
this.$get = ["$dateFormatter", "$dateParser", "$sce", function($dateFormatter, $dateParser, $sce) {
|
|
448
|
+
|
|
449
|
+
return function(picker) {
|
|
450
|
+
|
|
451
|
+
var scope = picker.$scope;
|
|
452
|
+
var options = picker.$options;
|
|
453
|
+
|
|
454
|
+
var lang = options.lang;
|
|
455
|
+
var formatDate = function(date, format) {
|
|
456
|
+
return $dateFormatter.formatDate(date, format, lang);
|
|
457
|
+
};
|
|
458
|
+
var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});
|
|
459
|
+
|
|
460
|
+
var weekDaysMin = $dateFormatter.weekdaysShort(lang);
|
|
461
|
+
var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));
|
|
462
|
+
var weekDaysLabelsHtml = $sce.trustAsHtml('<th class="dow text-center">' + weekDaysLabels.join('</th><th class="dow text-center">') + '</th>');
|
|
463
|
+
|
|
464
|
+
var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());
|
|
465
|
+
var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};
|
|
466
|
+
var timezoneOffset = startDate.getTimezoneOffset() * 6e4;
|
|
467
|
+
|
|
468
|
+
var views = [{
|
|
469
|
+
format: options.dayFormat,
|
|
470
|
+
split: 7,
|
|
471
|
+
steps: { month: 1 },
|
|
472
|
+
update: function(date, force) {
|
|
473
|
+
if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {
|
|
474
|
+
angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});
|
|
475
|
+
picker.$build();
|
|
476
|
+
} else if(date.getDate() !== viewDate.date) {
|
|
477
|
+
viewDate.date = picker.$date.getDate();
|
|
478
|
+
picker.$updateSelected();
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
build: function() {
|
|
482
|
+
var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();
|
|
483
|
+
var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();
|
|
484
|
+
var today = new Date().toDateString();
|
|
485
|
+
// Handle daylight time switch
|
|
486
|
+
if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);
|
|
487
|
+
var days = [], day;
|
|
488
|
+
for(var i = 0; i < 42; i++) { // < 7 * 6
|
|
489
|
+
day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));
|
|
490
|
+
days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});
|
|
491
|
+
}
|
|
492
|
+
scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);
|
|
493
|
+
scope.showLabels = true;
|
|
494
|
+
scope.labels = weekDaysLabelsHtml;
|
|
495
|
+
scope.rows = split(days, this.split);
|
|
496
|
+
this.built = true;
|
|
497
|
+
},
|
|
498
|
+
isSelected: function(date) {
|
|
499
|
+
return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();
|
|
500
|
+
},
|
|
501
|
+
isDisabled: function(date) {
|
|
502
|
+
var time = date.getTime();
|
|
503
|
+
|
|
504
|
+
// Disabled because of min/max date.
|
|
505
|
+
if (time < options.minDate || time > options.maxDate) return true;
|
|
506
|
+
|
|
507
|
+
// Disabled due to being a disabled day of the week
|
|
508
|
+
if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;
|
|
509
|
+
|
|
510
|
+
// Disabled because of disabled date range.
|
|
511
|
+
if (options.disabledDateRanges) {
|
|
512
|
+
for (var i = 0; i < options.disabledDateRanges.length; i++) {
|
|
513
|
+
if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return false;
|
|
520
|
+
},
|
|
521
|
+
onKeyDown: function(evt) {
|
|
522
|
+
if (!picker.$date) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
var actualTime = picker.$date.getTime();
|
|
526
|
+
var newDate;
|
|
527
|
+
|
|
528
|
+
if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);
|
|
529
|
+
else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);
|
|
530
|
+
else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);
|
|
531
|
+
else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);
|
|
532
|
+
|
|
533
|
+
if (!this.isDisabled(newDate)) picker.select(newDate, true);
|
|
534
|
+
}
|
|
535
|
+
}, {
|
|
536
|
+
name: 'month',
|
|
537
|
+
format: options.monthFormat,
|
|
538
|
+
split: 4,
|
|
539
|
+
steps: { year: 1 },
|
|
540
|
+
update: function(date, force) {
|
|
541
|
+
if(!this.built || date.getFullYear() !== viewDate.year) {
|
|
542
|
+
angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});
|
|
543
|
+
picker.$build();
|
|
544
|
+
} else if(date.getMonth() !== viewDate.month) {
|
|
545
|
+
angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});
|
|
546
|
+
picker.$updateSelected();
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
build: function() {
|
|
550
|
+
var firstMonth = new Date(viewDate.year, 0, 1);
|
|
551
|
+
var months = [], month;
|
|
552
|
+
for (var i = 0; i < 12; i++) {
|
|
553
|
+
month = new Date(viewDate.year, i, 1);
|
|
554
|
+
months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});
|
|
555
|
+
}
|
|
556
|
+
scope.title = formatDate(month, options.yearTitleFormat);
|
|
557
|
+
scope.showLabels = false;
|
|
558
|
+
scope.rows = split(months, this.split);
|
|
559
|
+
this.built = true;
|
|
560
|
+
},
|
|
561
|
+
isSelected: function(date) {
|
|
562
|
+
return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();
|
|
563
|
+
},
|
|
564
|
+
isDisabled: function(date) {
|
|
565
|
+
var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
|
566
|
+
return lastDate < options.minDate || date.getTime() > options.maxDate;
|
|
567
|
+
},
|
|
568
|
+
onKeyDown: function(evt) {
|
|
569
|
+
if (!picker.$date) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
var actualMonth = picker.$date.getMonth();
|
|
573
|
+
var newDate = new Date(picker.$date);
|
|
574
|
+
|
|
575
|
+
if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);
|
|
576
|
+
else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);
|
|
577
|
+
else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);
|
|
578
|
+
else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);
|
|
579
|
+
|
|
580
|
+
if (!this.isDisabled(newDate)) picker.select(newDate, true);
|
|
581
|
+
}
|
|
582
|
+
}, {
|
|
583
|
+
name: 'year',
|
|
584
|
+
format: options.yearFormat,
|
|
585
|
+
split: 4,
|
|
586
|
+
steps: { year: 12 },
|
|
587
|
+
update: function(date, force) {
|
|
588
|
+
if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {
|
|
589
|
+
angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});
|
|
590
|
+
picker.$build();
|
|
591
|
+
} else if(date.getFullYear() !== viewDate.year) {
|
|
592
|
+
angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});
|
|
593
|
+
picker.$updateSelected();
|
|
594
|
+
}
|
|
595
|
+
},
|
|
596
|
+
build: function() {
|
|
597
|
+
var firstYear = viewDate.year - viewDate.year % (this.split * 3);
|
|
598
|
+
var years = [], year;
|
|
599
|
+
for (var i = 0; i < 12; i++) {
|
|
600
|
+
year = new Date(firstYear + i, 0, 1);
|
|
601
|
+
years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});
|
|
602
|
+
}
|
|
603
|
+
scope.title = years[0].label + '-' + years[years.length - 1].label;
|
|
604
|
+
scope.showLabels = false;
|
|
605
|
+
scope.rows = split(years, this.split);
|
|
606
|
+
this.built = true;
|
|
607
|
+
},
|
|
608
|
+
isSelected: function(date) {
|
|
609
|
+
return picker.$date && date.getFullYear() === picker.$date.getFullYear();
|
|
610
|
+
},
|
|
611
|
+
isDisabled: function(date) {
|
|
612
|
+
var lastDate = +new Date(date.getFullYear() + 1, 0, 0);
|
|
613
|
+
return lastDate < options.minDate || date.getTime() > options.maxDate;
|
|
614
|
+
},
|
|
615
|
+
onKeyDown: function(evt) {
|
|
616
|
+
if (!picker.$date) {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
var actualYear = picker.$date.getFullYear(),
|
|
620
|
+
newDate = new Date(picker.$date);
|
|
621
|
+
|
|
622
|
+
if(evt.keyCode === 37) newDate.setYear(actualYear - 1);
|
|
623
|
+
else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);
|
|
624
|
+
else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);
|
|
625
|
+
else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);
|
|
626
|
+
|
|
627
|
+
if (!this.isDisabled(newDate)) picker.select(newDate, true);
|
|
628
|
+
}
|
|
629
|
+
}];
|
|
630
|
+
|
|
631
|
+
return {
|
|
632
|
+
views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,
|
|
633
|
+
viewDate: viewDate
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
}];
|
|
639
|
+
|
|
640
|
+
});
|