├── .gitignore ├── README.md ├── bower.json ├── dist └── ionic-multi-date-picker.bundle.min.js ├── gulpfile.js ├── images ├── imdp-android.jpg ├── imdp-calendarNames.jpg ├── imdp-ios-2.jpg ├── mdp-ios-name-convention.jpg └── mdp-ios-year-month-select.jpg ├── package.json └── src ├── ionic-multi-date-picker-modal.html ├── ionic-multi-date-picker-plain.html ├── ionic-multi-date-picker-popup.html ├── ionic-multi-date-picker.app.js ├── ionic-multi-date-picker.css ├── ionic-multi-date-picker.directive.js ├── ionic-multi-date-picker.scss ├── ionic-multi-date-picker.service.js └── template-body.html /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | node_modules/ 3 | bower_components/ 4 | .DS_Store/ 5 | ionic-datepicker.js 6 | ionic-multi-date-picker.js 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##Introduction: 2 | 3 | This is an `ionic-multi-date-picker` bower component, which can be used in any Ionic framework's application. No additional plugins required for this component. 4 | 5 | Forked from https://github.com/rajeshwarpatlolla/ionic-datepicker 6 | and fully rewrited. 7 | 8 | [Repo with simple ionic-application](https://github.com/DenniLa2/ionic-datepicker-sample-project) 9 | 10 | [Home Ionic-multi-date-picker](https://github.com/DenniLa2/ionic-datepicker) 11 | 12 | ##Screenshots: 13 | 14 | ![ios popup](https://github.com/DenniLa2/ionic-datepicker/blob/master/images/imdp-android.jpg) 15 | ![ios popup dateselector](https://github.com/DenniLa2/ionic-datepicker/blob/master/images/imdp-calendarNames.jpg) 16 | 17 | ![android modal](https://github.com/DenniLa2/ionic-datepicker/blob/master/images/imdp-ios-2.jpg) 18 | ![android modal dateselector](https://github.com/DenniLa2/ionic-datepicker/blob/master/images/mdp-ios-name-convention.jpg) 19 | ![calendar-convention section and "select by week" mode](https://github.com/DenniLa2/ionic-datepicker/blob/master/images/mdp-ios-year-month-select.jpg) 20 | 21 | ##Video: 22 | [YouTube](https://youtu.be/RxW628a9U-M) 23 | 24 | [YouTube - select by week and calendar-convention section](https://youtu.be/Bg0YctJVCME) 25 | 26 | ##Prerequisites. 27 | 28 | * node.js 29 | * npm 30 | * bower 31 | * gulp 32 | 33 | ##How to use: 34 | 35 | 1) In your project repository install the ionic-datepicker using bower 36 | 37 | `bower install ionic-multi-date-picker --save` 38 | 39 | This will install the latest version released. 40 | 41 | 2) Give the path of `ionic-multi-date-picker.bundle.min.js` in your `index.html` file. 42 | 43 | ````html 44 | 45 | 46 | ```` 47 | 48 | 3) In your application module inject the dependency `ionic-multi-date-picker`, in order to work with the ionic time picker 49 | ````javascript 50 | angular.module('mainModuleName', ['ionic', 'ionic-multi-date-picker']){ 51 | // 52 | } 53 | ```` 54 | 55 | 4) Use the below format in your template's corresponding controller. All parameters are optional. 56 | 57 | ````javascript 58 | $scope.datepickerObject = { 59 | templateType: 'POPUP', // POPUP | MODAL 60 | header: "Select Dates", 61 | headerClass: "royal-bg light", 62 | btnsIsNative: false, 63 | btnOk: 'OK', 64 | btnOkClass: 'button-clear cal-green', 65 | btnCancel: 'CLOSE', 66 | btnCancelClass: 'button-clear button-dark', 67 | btnTodayShow: false, 68 | btnToday: 'TODAY', 69 | btnTodayClass: 'button-positive', 70 | btnClearShow: false, 71 | btnClear: 'CLEAR', 72 | btnClearClass: 'button-royal', 73 | selectType: 'PERIOD', // SINGLE | PERIOD | MULTI 74 | tglSelectByWeekShow: true, // true | false (default) 75 | tglSelectByWeek: 'Select by week', 76 | isSelectByWeek: true, // true (default) | false 77 | selectByWeekMode: 'NORMAL', // INVERSION (default), NORMAL 78 | tglSelectByWeekClass: 'toggle-positive', // true | false (default) 79 | titleSelectByWeekClass: 'positive positive-border', // true | false (default) 80 | accessType: 'WRITE', // READ | WRITE 81 | showErrors: true, // true (default), false 82 | errorLanguage: 'RU', // EN | RU 83 | fromDate: new Date(2015, 9), 84 | toDate: new Date(2016, 1), 85 | selectedDates: $scope.selectedDates, 86 | viewMonth: $scope.selectedDates, 87 | disabledDates: disabledDates, 88 | calendar0: holidays, 89 | calendar0Class: '', 90 | calendar0Name: 'holidays', 91 | calendar1: holidays, 92 | calendar1Class: '', 93 | calendar1Name: 'my days', 94 | calendar2: calendar, 95 | calendar2Class: '', 96 | calendar2Name: 'other days', 97 | calendar3: calendar, 98 | calendar3Class: '', 99 | calendar3Name: 'red days', 100 | calendar4: calendar, 101 | calendar4Class: 'cal-color-black', 102 | calendar4Name: 'vacations', 103 | calendar5: calendar, 104 | calendar5Class: '', 105 | calendar5Name: 'etc days', 106 | calendar6: calendar, 107 | calendar6Class: '', 108 | calendar6Name: 'same days', 109 | calendar7: calendar, 110 | calendar7Class: '', 111 | calendar7Name: 'same days', 112 | conflictSelectedDisabled: 'DISABLED', // SELECTED | DISABLED 113 | closeOnSelect: false, 114 | mondayFirst: true, 115 | weekDaysList: weekDaysList, 116 | monthList: monthList, 117 | modalHeaderColor: 'bar-positive', 118 | modalFooterColor: 'bar-positive', 119 | callback: function (dates) { 120 | retSelectedDates(dates); 121 | } 122 | }; 123 | ```` 124 | 125 | **$scope.datepickerObject** is the main object, that we need to pass to the directive. The properties of this object are as follows. 126 | 127 | **1. templateType** - the type of dialog. Default is `MODAL`. 128 | 129 | **2. header** 130 | 131 | **3. headerClass** - ionic css classes. 132 | 133 | **4. modalFooterClass** - ionic css classes. 134 | 135 | **5. btnsIsNative** - use ionic-popup-native buttons. Default: true. 136 | 137 | **6. btnOk** - title on Ok button. 138 | 139 | **7. btnOkClass** - ionic css classes. 140 | 141 | **8. btnCancel** - title on Cancel button. 142 | 143 | **9. btnCancelClass** - ionic css classes. 144 | 145 | **10. btnTodayShow** - Default false. 146 | 147 | **11. btnToday** - title. 148 | 149 | **12. btnTodayClass** - ionic css classes. 150 | 151 | **13. btnClearShow** - default false. 152 | 153 | **14. btnClear** - title. 154 | 155 | **15. btnClearClass** - ionic css classes. 156 | 157 | **16. selectType** - SINGLE - one date per calendar, PERIOD - continuous date period, MULTI - random dates. Default `MULTI`. 158 | 159 | **17. tglSelectByWeekShow** - 'select by week' toggle, Default false. 160 | 161 | **18. tglSelectByWeek** - title. 162 | 163 | **19. isSelectByWeek** - start value, default true. 164 | 165 | **20. selectByWeekMode** - INVERSION (default), NORMAL. 166 | 167 | **21. tglSelectByWeekClass** - ionic css classes. 168 | 169 | **22. titleSelectByWeekClass** - ionic css classes. 170 | 171 | **23. accessType** - READ | WRITE. Default - `WRITE`. 172 | 173 | **24. showErrors** - true (default), false. 174 | 175 | **25. errorLanguage** - language of user errors. EN | RU. Default `EN`. 176 | 177 | **26. fromDate:** new Date(2015, 9), 178 | 179 | **27. toDate:** new Date(2016, 1), 180 | 181 | **28. selectedDates** - array with javascript dates. 182 | 183 | **29. viewMonth** - first viewed month. Default: current or nearest next month with date. 184 | 185 | **30. disabledDates** - array with javascript dates of disabled dates. 186 | 187 | **31. calendar0 - calendar7** - named arrays with javascript dates, where the number is only fixed position around date. 188 | 189 | ![cal0-cal7](https://github.com/DenniLa2/ionic-datepicker/blob/master/images/imdp-calendarNames.jpg) 190 | 191 | **32. calendar0Class - calendar7Class** - classes to customise. Availables classes: cal-color-red, cal-color-yellow, cal-color-orange, cal-color-violet, cal-color-saha, cal-color-coral, cal-color-blue, cal-color-skyey, cal-color-green, cal-color-ggreen, cal-color-holiday, cal-color-black. 192 | 193 | **33. holidaysName, calendar1Name - calendar7Name** - shown names of custom calendars in calendar-convention section. If all names are empty - calendar-convention section is hidden. 194 | 195 | **34. conflictSelectedDisabled** - if selecled dates and disabled dates have the same date - one of them will deleted. `SELECTED` - selected date will store, disabled - deleted. `DISABLED` - disabled date will store, selected - deleted. Default `DISABLED`. 196 | 197 | **35. closeOnSelect** - default false. 198 | 199 | **36. mondayFirst** - default true, 200 | 201 | **37. weekDaysList** 202 | 203 | **38. monthList** 204 | 205 | **39. callback**(Mandatory) - This the callback function, which will get array of the selected dates in to the controller. You can define this function as follows. 206 | ````javascript 207 | var retSelectedDates = function (dates) { 208 | $scope.selectedDates.length = 0; 209 | for (var i = 0; i < dates.length; i++) { 210 | $scope.selectedDates.push(angular.copy(dates[i])); 211 | } 212 | }; 213 | ```` 214 | 215 | 216 | **1. ionic-multi-date-picker** is the directive, to which we can pass required vales. 217 | 218 | **2. input-obj**(Mandatory) - This is an object. We have to pass an object as shown above. 219 | 220 | ##Versions: 221 | 222 | 0.1.0 - forked from https://github.com/rajeshwarpatlolla 223 | 224 | 1.0.0 - fully rewrited. 225 | 226 | 1.1.0 - added: calendars 1-7 to popup. 227 | 228 | 1.2.0 - added: 'select by week' toggle. 229 | 230 | 1.2.1 - added: calendars 1-7 to modal, added modalFooterClass. 231 | 232 | 1.2.2 - 2 mode of "select by week": inverse and normal. 233 | 234 | 1.2.3 - title of tglSelectByWeek. 235 | 236 | 1.2.4 - fix. 237 | 238 | 1.2.5 - added: 'fromDate' and 'toDate', holidaysClass, calendars names and calendar-convention section. 239 | 240 | 1.2.6 - stylized. 241 | 242 | 1.2.7 - added: on-hold - day details. 243 | 244 | 1.2.8 - fix css. 245 | 246 | 2.0.0 - refactoring. Holiday calendar renamed to calendar0. 247 | 248 | ##Contact: 249 | gmail: dennila2@gmail.com 250 | 251 | github: https://github.com/dennila2 252 | 253 | Comment and Rate it : http://market.ionic.io/plugins/ionic-multi-date-picker -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-multi-date-picker", 3 | "version": "2.0.0", 4 | "authors": [ 5 | "Denni Adam " 6 | ], 7 | "description": "A multiple date picker component for Ionic framework", 8 | "main": [ 9 | "./dist/ionic-multi-date-picker.bundle.min.js" 10 | ], 11 | "keywords": [ 12 | "ionic-datepicker", 13 | "ionic-multi-date-picker", 14 | "multi-date", 15 | "multi-datepicker", 16 | "multi-date-picker", 17 | "multidate", 18 | "multidatepicker", 19 | "multidate-picker", 20 | "ionic", 21 | "datepicker", 22 | "datepicker for ionic", 23 | "datepicker for ionic framework" 24 | ], 25 | "license": "MIT", 26 | "homepage": "https://github.com/dennila2", 27 | "ignore": [ 28 | "**/.*", 29 | "node_modules", 30 | "bower_components", 31 | "test", 32 | "tests", 33 | ".gitignore" 34 | ], 35 | "dependencies": { 36 | "ionic": ">=1.0.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dist/ionic-multi-date-picker.bundle.min.js: -------------------------------------------------------------------------------- 1 | (function (doc, cssText) { 2 | var styleEl = doc.createElement("style"); 3 | doc.getElementsByTagName("head")[0].appendChild(styleEl); 4 | if (styleEl.styleSheet) { 5 | if (!styleEl.styleSheet.disabled) { 6 | styleEl.styleSheet.cssText = cssText; 7 | } 8 | } else { 9 | try { 10 | styleEl.innerHTML = cssText; 11 | } catch (ignore) { 12 | styleEl.innerText = cssText; 13 | } 14 | } 15 | }(document, ".cal-color-red:before{background-color:#f66d67}.cal-color-yellow:before{background-color:#f6e800}.cal-color-4:before,.cal-color-orange:before{background-color:#f68200}.cal-color-2:before,.cal-color-violet:before{background-color:#f600c7}.cal-color-6:before,.cal-color-saha:before{background-color:#9f00f6}.cal-color-coral:before{background-color:#ff8579}.cal-color-3:before,.cal-color-blue:before{background-color:#3a81c5}.cal-color-7:before,.cal-color-skyey:before{background-color:#53a7ff}.cal-color-green:before{background-color:#9bd659}.cal-color-5:before,.cal-color-ggreen:before{background-color:#00d66c}.cal-color-0:before,.cal-color-holiday:before{background-color:red}.cal-color-1:before,.cal-color-black:before{background-color:#000}.picker-body{height:inherit}.picker-body .popup-head{padding:0;border:0}.picker-body .popup-body{overflow:inherit!important;padding:0}.cal-green{color:#9bd659!important}.cal-green-bg{background-color:#9bd659;z-index:-2}.ionic-datepicker{background-color:#fff}.ionic-datepicker .no-padding{padding:0}.ionic-datepicker .clear{clear:both}.ionic-datepicker .title{color:#3a81c5}.ionic-datepicker .title h3{font-size:2em;text-align:center!important;margin:0;padding:10px;width:100%}.ionic-datepicker .title div{font-size:21px;text-align:center!important;margin:0;padding:5px;width:100%}.ionic-datepicker .navigator{background-color:#3a81c5;min-height:50px}.ionic-datepicker .icon-chevron{position:relative}.ionic-datepicker .icon-chevron:before{background-color:#fff;width:24px;height:24px;border-radius:50%;padding:5px 3px;position:absolute;top:-7px;z-index:1}.ionic-datepicker .icon-chevron-left:before{left:2px}.ionic-datepicker .icon-chevron-right:before{left:-25px}.ionic-datepicker .month-year-selector{position:fixed;right:60px;top:0;left:60px;background-color:transparent;color:transparent;border-width:0;max-width:40%}.ionic-datepicker .month-year-selector input{color:transparent}.ionic-datepicker .calendar-grid{margin:0 auto;max-width:260px}.ionic-datepicker .week-days{text-transform:uppercase;text-align:center}.ionic-datepicker .weekend{color:#f66d67}.ionic-datepicker .calendar-0,.ionic-datepicker .calendar-1,.ionic-datepicker .calendar-2,.ionic-datepicker .calendar-3,.ionic-datepicker .calendar-4,.ionic-datepicker .calendar-5,.ionic-datepicker .calendar-6,.ionic-datepicker .calendar-7{position:absolute;top:0;left:0;color:transparent}.ionic-datepicker .calendar-0:before,.ionic-datepicker .calendar-1:before,.ionic-datepicker .calendar-2:before,.ionic-datepicker .calendar-3:before,.ionic-datepicker .calendar-4:before,.ionic-datepicker .calendar-5:before,.ionic-datepicker .calendar-6:before,.ionic-datepicker .calendar-7:before{position:absolute;content:'';z-index:0;width:8px;height:8px;border:2px solid #fff;border-radius:50%}.ionic-datepicker .calendar-0:before{top:3px;left:5px}.ionic-datepicker .calendar-1:before{top:-1px;left:14px}.ionic-datepicker .calendar-2:before{top:3px;left:23px}.ionic-datepicker .calendar-3:before{top:12px;left:27px}.ionic-datepicker .calendar-4:before{top:22px;left:24px}.ionic-datepicker .calendar-5:before{top:25px;left:14px}.ionic-datepicker .calendar-6:before{top:22px;left:5px}.ionic-datepicker .calendar-7:before{top:12px;left:1px}.ionic-datepicker .disabledDate{color:#868686!important}.ionic-datepicker .disabledDate:after{position:absolute;content:'';top:4px;left:5px;z-index:-1;width:25px;height:25px;border-radius:50%;background-color:#e7e7e7}.ionic-datepicker .not-cur-month{color:#ccc}.ionic-datepicker .today{font-weight:bolder}.ionic-datepicker .today:after{content:'';position:absolute;top:4px;left:5px;z-index:-1;width:25px;height:25px;border-radius:50%;border:2px solid #53a7ff}.ionic-datepicker .not-empty:after{content:'';position:absolute;top:4px;left:5px;z-index:-1;width:25px;height:25px;border-radius:50%;border:1px solid #ccc}.ionic-datepicker .selected,.ionic-datepicker .selected-light{color:#fff!important}.ionic-datepicker .selected-light:after,.ionic-datepicker .selected:after{content:'';position:absolute;top:4px;left:5px;z-index:-1;width:25px;height:25px;border-radius:50%}.ionic-datepicker .selected:after{background-color:#f66d67}.ionic-datepicker .selected-light:after{background-color:#ff8579}.ionic-datepicker .date-grid{height:200px}.ionic-datepicker .date-grid .date-row{text-align:center}.ionic-datepicker .date-grid .date-row .date-col{position:relative;z-index:1;width:44px}.ionic-datepicker .date-grid .date-row .date-col:active,.ionic-datepicker .date-grid .date-row .date-col:hover{cursor:pointer}.ionic-datepicker .date-grid .date-row .date-col .date-cell{padding:5px;margin:1px}.ionic-datepicker .calendar-names{position:relative;max-width:260px;height:87px;margin:0 auto}.ionic-datepicker .calendar-names .calendars-point{width:29px;text-align:center;position:absolute;left:110px;top:31px;z-index:1}.ionic-datepicker .calendar-names .calendars-point:before{position:absolute;content:'';left:-10px;top:-12px;width:47px;height:47px;border-radius:50%;z-index:-1}.ionic-datepicker .calendar-names .calendars-point-today:before{border:2px solid #53a7ff}.ionic-datepicker .calendar-names .calendars-point-selected{color:#fff}.ionic-datepicker .calendar-names .calendars-point-selected:before{background-color:#ff8579}.ionic-datepicker .calendar-names .calendars-point-disabled{color:#868686}.ionic-datepicker .calendar-names .calendars-point-disabled:before{background-color:#e7e7e7}.ionic-datepicker .calendar-names .calendars-point-contour:before{border:1px solid #ccc}.ionic-datepicker .calendar-names .calendar-0-name,.ionic-datepicker .calendar-names .calendar-1-name,.ionic-datepicker .calendar-names .calendar-2-name,.ionic-datepicker .calendar-names .calendar-3-name,.ionic-datepicker .calendar-names .calendar-4-name,.ionic-datepicker .calendar-names .calendar-5-name,.ionic-datepicker .calendar-names .calendar-6-name,.ionic-datepicker .calendar-names .calendar-7-name{position:absolute;width:40%;text-align:center}.ionic-datepicker .calendar-names .calendar-0-name{top:16px;left:5px}.ionic-datepicker .calendar-names .calendar-1-name{top:0;left:74px}.ionic-datepicker .calendar-names .calendar-2-name{top:16px;left:144px}.ionic-datepicker .calendar-names .calendar-3-name{top:32px;left:149px}.ionic-datepicker .calendar-names .calendar-4-name{top:48px;left:144px}.ionic-datepicker .calendar-names .calendar-5-name{top:64px;left:74px}.ionic-datepicker .calendar-names .calendar-6-name{top:48px;left:5px}.ionic-datepicker .calendar-names .calendar-7-name{top:32px;left:0}.ionic-datepicker .calendar-names .calendar-0-point,.ionic-datepicker .calendar-names .calendar-1-point,.ionic-datepicker .calendar-names .calendar-2-point,.ionic-datepicker .calendar-names .calendar-3-point,.ionic-datepicker .calendar-names .calendar-4-point,.ionic-datepicker .calendar-names .calendar-5-point,.ionic-datepicker .calendar-names .calendar-6-point,.ionic-datepicker .calendar-names .calendar-7-point{position:absolute;color:transparent}.ionic-datepicker .calendar-names .calendar-0-point:before,.ionic-datepicker .calendar-names .calendar-1-point:before,.ionic-datepicker .calendar-names .calendar-2-point:before,.ionic-datepicker .calendar-names .calendar-3-point:before,.ionic-datepicker .calendar-names .calendar-4-point:before,.ionic-datepicker .calendar-names .calendar-5-point:before,.ionic-datepicker .calendar-names .calendar-6-point:before,.ionic-datepicker .calendar-names .calendar-7-point:before{position:absolute;content:'';width:12px;height:12px;border:3px solid #fff;border-radius:50%;z-index:2}.ionic-datepicker .calendar-names .calendar-0-point{top:20px;left:100px}.ionic-datepicker .calendar-names .calendar-1-point{top:14px;left:118px}.ionic-datepicker .calendar-names .calendar-2-point:before{top:20px;left:136px}.ionic-datepicker .calendar-names .calendar-3-point:before{top:37px;left:143px}.ionic-datepicker .calendar-names .calendar-4-point:before{top:53px;left:136px}.ionic-datepicker .calendar-names .calendar-5-point:before{top:59px;left:119px}.ionic-datepicker .calendar-names .calendar-6-point:before{top:53px;left:100px}.ionic-datepicker .calendar-names .calendar-7-point:before{top:37px;left:93px}.ionic-datepicker .errors{max-width:260px;padding:10px;margin:0 auto;color:#f66d67}.ionic-datepicker .tgl-period div{margin:0}.ionic-datepicker .view-month{color:#fff;padding:14px}.ionic-datepicker .pointer_events_none{pointer-events:none!important}.ionic-datepicker .select_section{padding:0}.ionic-datepicker .select_section label{padding:12px}.ionic-datepicker .select_section select{font-size:12px;font-weight:700;padding:2px 10px;direction:ltr;left:0;width:100%;max-width:100%}.ionic-datepicker .select_section .item-select:after{right:4px;border-top:4px solid;border-right:4px solid #000;border-left:4px solid #000}.ionic-datepicker .left-arrow{direction:rtl}.ionic-datepicker .font_22px{font-size:22px}.ionic-datepicker .btns-right-popup{float:right}.ionic-datepicker .btns-right-modal{direction:rtl}.ionic_datepicker_modal_content{padding-top:10%}.ionic_datepicker_modal_content .ionic-datepicker .selected_date_full{font-size:20px;padding:20px}.ionic_datepicker_modal_content .cal-button{padding:0!important;font-size:14px!important}@media (min-width:680px){.ionic_datepicker_modal_content{padding-top:0}.ionic_datepicker_modal_content .ionic-datepicker .selected_date_full{font-size:inherit;padding:10px 0 0}}")); 16 | 17 | (function(module) { 18 | try { 19 | module = angular.module('ionic-multi-date-picker.templates'); 20 | } catch (e) { 21 | module = angular.module('ionic-multi-date-picker.templates', []); 22 | } 23 | module.run(['$templateCache', function($templateCache) { 24 | $templateCache.put('ionic-multi-date-picker-modal.html', 25 | '
'); 26 | }]); 27 | })(); 28 | 29 | (function(module) { 30 | try { 31 | module = angular.module('ionic-multi-date-picker.templates'); 32 | } catch (e) { 33 | module = angular.module('ionic-multi-date-picker.templates', []); 34 | } 35 | module.run(['$templateCache', function($templateCache) { 36 | $templateCache.put('ionic-multi-date-picker-plain.html', 37 | '
{{ inputObj.header }}
'); 38 | }]); 39 | })(); 40 | 41 | (function(module) { 42 | try { 43 | module = angular.module('ionic-multi-date-picker.templates'); 44 | } catch (e) { 45 | module = angular.module('ionic-multi-date-picker.templates', []); 46 | } 47 | module.run(['$templateCache', function($templateCache) { 48 | $templateCache.put('ionic-multi-date-picker-popup.html', 49 | '

'); 50 | }]); 51 | })(); 52 | 53 | (function(module) { 54 | try { 55 | module = angular.module('ionic-multi-date-picker.templates'); 56 | } catch (e) { 57 | module = angular.module('ionic-multi-date-picker.templates', []); 58 | } 59 | module.run(['$templateCache', function($templateCache) { 60 | $templateCache.put('template-body.html', 61 | '
{{ dayList[row + col].date }}
{{ holded.date }}
.
.
.
.
.
.
.
.
{{ calendar[0].name.title }}
{{ calendar[1].name.title }}
{{ calendar[2].name.title }}
{{ calendar[3].name.title }}
{{ calendar[4].name.title }}
{{ calendar[5].name.title }}
{{ calendar[6].name.title }}
{{ calendar[7].name.title }}
{{ error[errorLanguage] }}
{{ tglSelectByWeek }}
'); 62 | }]); 63 | })(); 64 | 65 | //By Rajeshwar Patlolla - rajeshwar.patlolla@gmail.com 66 | //https://github.com/rajeshwarpatlolla 67 | 68 | // forked and edited by Denni Adam - dennila2@gmail.com 69 | // https://github.com/dennila2 70 | (function(){ 71 | 'use strict'; 72 | 73 | angular.module('ionic-multi-date-picker', ['ionic','ionic-multi-date-picker.templates']); 74 | 75 | })(); 76 | //By Rajeshwar Patlolla - rajeshwar.patlolla@gmail.com 77 | 78 | // forked and rewrited by Denni Adam - dennila2@gmail.com 79 | // https://github.com/dennila2 80 | 81 | (function () { 82 | 'use strict'; 83 | 84 | angular.module('ionic-multi-date-picker') 85 | .directive('ionicMultiDatePicker', IonicMultiDatePicker); 86 | 87 | IonicMultiDatePicker.$inject = ['$ionicGesture', '$ionicModal', '$ionicPopup', '$timeout', 'IonicMultiDatePickerService']; 88 | 89 | function IonicMultiDatePicker($ionicGesture, $ionicModal, $ionicPopup, $timeout, IonicMultiDatePickerService) { 90 | return { 91 | restrict: 'AE', 92 | replace: false, 93 | /*template: function (elem, attrs) { 94 | console.log('elem'); 95 | console.log(elem); 96 | if (attrs.calendar === 'true') { 97 | return '
date-picker
{{ inputObj.header }}
' 98 | } 99 | return ''; 100 | },*/ 101 | scope: { 102 | inputObj: "=inputObj" 103 | }, 104 | link: function (scope, element, attrs) { 105 | // IDE definitions 106 | var ERRORS = { 107 | INPUT_PERIOD__SINGLE_NOT_PERIOD: { 108 | CODE: 'INPUT_PERIOD__SINGLE_NOT_PERIOD', 109 | EN: 'Date is not single', 110 | RU: 'Должно быть не больше одной даты' 111 | }, 112 | INPUT_PERIOD__DATES_NOT_PERIOD: { 113 | CODE: 'INPUT_PERIOD__DATES_NOT_PERIOD', 114 | EN: 'Dates is not period', 115 | RU: 'Даты не являются периодом' 116 | }, 117 | UNKNOWN_ERROR: { 118 | CODE: 'UNKNOWN_ERROR', 119 | EN: 'Unknown error', 120 | RU: 'Неизвестная ошибка' 121 | }, 122 | ERROR_DELETING_UNKNOWN_ERROR: { 123 | CODE: 'ERROR_DELETING_UNKNOWN_ERROR', 124 | EN: 'Error deleting unknown error', 125 | RU: 'Ошибка удаления неизвестной ошибки' 126 | } 127 | }; 128 | var SELECT_TYPE = {MULTI: 'MULTI', PERIOD: 'PERIOD', SINGLE: 'SINGLE'}; 129 | var ACCESS_TYPE = {WRITE: 'WRITE', READ: 'READ'}; 130 | var ERROR_LANGUAGE = {EN: 'EN', RU: 'RU'}; 131 | var TEMPLATE_TYPE = {POPUP: 'POPUP', MODAL: 'MODAL'}; 132 | var CONFLICT_S_D = {DISABLED: 'DISABLED', SELECTED: 'SELECTED'}; 133 | var SELECT_BY_WEEK_MODE = {INVERSION: 'INVERSION', NORMAL: 'NORMAL'}; 134 | 135 | function start() { 136 | initErrors(); 137 | initView(); 138 | initDates(); 139 | initCalendarDates(); 140 | initBtns(); 141 | setViewMonth(); 142 | refreshDateList(); 143 | } 144 | 145 | initModal(); 146 | 147 | var errors; 148 | 149 | function initErrors() { 150 | scope.errors = {len: 0}; 151 | Object.defineProperty(scope.errors, "len", {enumerable: false}); 152 | 153 | errors = (function () { 154 | 155 | return { 156 | add: function (code) { 157 | if (!scope.errors.hasOwnProperty(code) && ERRORS.hasOwnProperty(code)) { 158 | console.debug('code+: ' + code); 159 | var err = ERRORS[code]; 160 | scope.errors[code] = ERRORS[code]; 161 | } else if (!scope.errors.hasOwnProperty(code) && !ERRORS.hasOwnProperty(code)) { 162 | console.debug('code: ' + code); 163 | err = ERRORS.UNKNOWN_ERROR; 164 | scope.errors.UNKNOWN_ERROR = ERRORS.UNKNOWN_ERROR; 165 | } else { 166 | // error already in array 167 | } 168 | this.length(); 169 | }, 170 | remove: function (code) { 171 | if (scope.errors.hasOwnProperty(code) && ERRORS.hasOwnProperty(code)) { 172 | delete scope.errors[code]; 173 | } else if (scope.errors.hasOwnProperty(code) && !ERRORS.hasOwnProperty(code)) { 174 | scope.errors.ERROR_DELETING_UNKNOWN_ERROR = ERRORS.ERROR_DELETING_UNKNOWN_ERROR; 175 | } 176 | this.length(); 177 | }, 178 | 179 | length: function () { 180 | scope.errors.len = 0; 181 | for (var err in scope.errors) { 182 | scope.errors.len++; 183 | } 184 | } 185 | } 186 | })(); 187 | } 188 | 189 | function initView() { 190 | //Setting the title, today, close and set strings for the date picker 191 | scope.templateType = (scope.inputObj.templateType && TEMPLATE_TYPE.hasOwnProperty(scope.inputObj.templateType) > -1) ? (scope.inputObj.templateType) : TEMPLATE_TYPE.POPUP; 192 | 193 | 194 | scope.currentMonth = ''; 195 | scope.currentYear = ''; 196 | scope.monthYear = { 197 | select: new Date() 198 | }; 199 | 200 | scope.header = (scope.inputObj.header && scope.inputObj.header.length > 0) ? scope.inputObj.header : ''; 201 | if (scope.templateType === TEMPLATE_TYPE.MODAL && scope.header === '') scope.header = 'Datepicker'; 202 | scope.headerClass = scope.inputObj.headerClass; 203 | 204 | scope.btnsIsNative = !!scope.inputObj.btnsIsNative; 205 | 206 | scope.btnOk = scope.inputObj.btnOk ? scope.inputObj.btnOk : 'Ok'; 207 | scope.btnOkClass = scope.inputObj.btnOkClass ? scope.inputObj.btnOkClass : 'button-stable cal-button'; 208 | 209 | scope.btnCancel = scope.inputObj.btnCancel ? scope.inputObj.btnCancel : 'Close'; 210 | scope.btnCancelClass = scope.inputObj.btnCancelClass ? scope.inputObj.btnCancelClass : 'button-stable cal-button'; 211 | 212 | scope.btnTodayShow = !!scope.inputObj.btnTodayShow; 213 | if (scope.btnTodayShow) { 214 | scope.btnToday = scope.inputObj.btnToday ? scope.inputObj.btnToday : 'Today'; 215 | scope.btnTodayClass = scope.inputObj.btnTodayClass ? scope.inputObj.btnTodayClass : 'button-stable cal-button'; 216 | } 217 | 218 | scope.btnClearShow = !!scope.inputObj.btnClearShow; 219 | if (scope.btnClearShow) { 220 | scope.btnClear = scope.inputObj.btnClear ? scope.inputObj.btnClear : 'Clear'; 221 | scope.btnClearClass = scope.inputObj.btnClearClass ? scope.inputObj.btnClearClass : 'button-stable cal-button'; 222 | } 223 | scope.selectType = (scope.inputObj.selectType && SELECT_TYPE.hasOwnProperty(scope.inputObj.selectType) > -1 ) ? scope.inputObj.selectType : SELECT_TYPE.MULTI; 224 | 225 | scope.tglSelectByWeekShow = scope.inputObj.tglSelectByWeekShow === true; 226 | scope.tglSelectByWeek = scope.inputObj.tglSelectByWeek ? scope.inputObj.tglSelectByWeek : 'Select by week'; 227 | scope.selectByWeekMode = (scope.inputObj.selectByWeekMode && scope.inputObj.selectByWeekMode === SELECT_BY_WEEK_MODE.INVERSION) ? SELECT_BY_WEEK_MODE.INVERSION : SELECT_BY_WEEK_MODE.NORMAL; 228 | scope.selectByWeekMode = (scope.inputObj.selectByWeekMode && scope.inputObj.selectByWeekMode === SELECT_BY_WEEK_MODE.INVERSION) ? SELECT_BY_WEEK_MODE.INVERSION : SELECT_BY_WEEK_MODE.NORMAL; 229 | scope.selectByWeek = {is: !!(scope.inputObj.isSelectByWeek === true && scope.tglSelectByWeekShow === true)}; 230 | scope.tglSelectByWeekClass = scope.inputObj.tglSelectByWeekClass ? scope.inputObj.tglSelectByWeekClass : 'toggle-energized'; 231 | scope.titleSelectByWeekClass = scope.inputObj.titleSelectByWeekClass ? scope.inputObj.titleSelectByWeekClass : 'energized energized-border'; 232 | 233 | scope.accessType = (scope.inputObj.accessType && ACCESS_TYPE.hasOwnProperty(scope.inputObj.accessType) > -1) ? scope.inputObj.accessType : ACCESS_TYPE.WRITE; 234 | scope.showErrors = (scope.inputObj.showErrors && scope.inputObj.showErrors !== true) ? false : true; 235 | scope.errorLanguage = (scope.inputObj.errorLanguage && ERROR_LANGUAGE.hasOwnProperty(scope.inputObj.errorLanguage)) ? scope.inputObj.errorLanguage : ERROR_LANGUAGE.EN; 236 | 237 | if (scope.inputObj.fromDate && Date.prototype.isPrototypeOf(scope.inputObj.fromDate)) { 238 | scope.fromYearMonth = scope.inputObj.fromDate.getFullYear() * 100 + scope.inputObj.fromDate.getMonth(); 239 | } else { 240 | scope.fromYearMonth = undefined; 241 | } 242 | 243 | if (scope.inputObj.toDate && Date.prototype.isPrototypeOf(scope.inputObj.toDate)) { 244 | scope.toYearMonth = scope.inputObj.toDate.getFullYear() * 100 + scope.inputObj.toDate.getMonth(); 245 | } else { 246 | scope.toYearMonth = undefined; 247 | } 248 | 249 | scope.conflictSD = (scope.inputObj.conflictSelectedDisabled && CONFLICT_S_D.hasOwnProperty(scope.inputObj.conflictSelectedDisabled)) ? scope.inputObj.conflictSelectedDisabled : CONFLICT_S_D.DISABLED; 250 | 251 | scope.closeOnSelect = !!scope.inputObj.closeOnSelect; 252 | 253 | scope.modalFooterClass = scope.inputObj.modalFooterClass ? scope.inputObj.modalFooterClass : 'bar-light'; 254 | 255 | // Setting the months list. This is useful, if the component needs to use some other language. 256 | scope.monthsList = []; 257 | if (scope.inputObj.monthList && scope.inputObj.monthList.length === 12) { 258 | scope.monthsList = scope.inputObj.monthList; 259 | } else { 260 | scope.monthsList = IonicMultiDatePickerService.monthsList; 261 | } 262 | // weaklist 263 | if (scope.inputObj.weekDaysList && scope.inputObj.weekDaysList.length === 7) { 264 | scope.weekNames = scope.inputObj.weekDaysList; 265 | } else { 266 | scope.weekNames = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; 267 | } 268 | 269 | // Setting whether to show Monday as the first day of the week or not. 270 | scope.mondayFirst = !!scope.inputObj.mondayFirst; 271 | 272 | if (scope.mondayFirst === true) { 273 | var lastWeekDay = scope.weekNames.shift(); 274 | scope.weekNames.push(lastWeekDay); 275 | } 276 | } 277 | 278 | function glueDate(date) { 279 | if (date instanceof Date) { 280 | return date.getFullYear() * 10000 + date.getMonth() * 100 + date.getDate(); 281 | } else { 282 | return date.year * 10000 + date.month * 100 + date.date; 283 | } 284 | } 285 | 286 | function initDates() { 287 | 288 | // INPUT DATES: 289 | // work copy & cancel copy 290 | if (scope.inputObj.selectedDates && scope.inputObj.selectedDates.length > 0) { 291 | scope.selectedDates = angular.copy(scope.inputObj.selectedDates); 292 | scope.inputDates = angular.copy(scope.inputObj.selectedDates); 293 | } else { 294 | scope.selectedDates = []; 295 | scope.inputDates = []; 296 | } 297 | 298 | // disabled dates 299 | scope.disabledDates = []; 300 | if (scope.inputObj.disabledDates && scope.inputObj.disabledDates instanceof Array) { 301 | scope.disabledDates = scope.inputObj.disabledDates; 302 | } 303 | 304 | 305 | // calendars 0 - 7 306 | scope.calendar = []; 307 | scope.calendarNamesCount = 0; 308 | 309 | for (var i = 0; i < 8; i++) { 310 | scope.calendar[i] = {dates: []}; 311 | var cn = 'calendar' + i; 312 | if (scope.inputObj[cn] && scope.inputObj[cn] instanceof Array) { 313 | 314 | scope.calendar[i].dates = scope.inputObj[cn]; 315 | /* 316 | for (var d = 0; d < scope.inputObj[cn].length; d++) { 317 | if (Date.prototype.isPrototypeOf()) { 318 | 319 | 320 | } 321 | } 322 | */ 323 | 324 | 325 | scope.calendar[i].class = scope.inputObj[cn + 'Class'] && scope.inputObj[cn + 'Class'].length > 0 ? scope.inputObj[cn + 'Class'] : 'cal-color-' + i; 326 | scope.calendar[i].name = { 327 | isShow: scope.inputObj[cn + 'Name'] && scope.inputObj[cn + 'Name'].length > 0, 328 | class: scope[cn + 'Class'], 329 | title: scope.inputObj[cn + 'Name'] 330 | }; 331 | if (scope.calendar[i].name.isShow) scope.calendarNamesCount++; 332 | } 333 | } 334 | 335 | scope.onRelease(); 336 | 337 | // methods: 338 | scope.selectedDates.findDate = function (year, month, date) { 339 | if (this.length > 0) { 340 | for (var i = 0; i < this.length; i++) { 341 | var d = this[i]; 342 | if (d.getFullYear() === year && d.getMonth() === month && d.getDate() === date) { 343 | return {isPresent: true, i: i}; 344 | } 345 | } 346 | } 347 | return {isPresent: false}; 348 | }; 349 | 350 | scope.selectedDates.addRemove = function (year, month, date, state) { 351 | var find = this.findDate(year, month, date); 352 | 353 | switch (scope.selectType) { 354 | case SELECT_TYPE.SINGLE: 355 | this.length = 0; 356 | if (find.isPresent) { 357 | //scope.selectedDates.length = 0; 358 | } else { 359 | this.push(new Date(year, month, date)); 360 | } 361 | break; 362 | 363 | default: 364 | if (state === undefined) { 365 | if (find.isPresent) { 366 | this.splice(find.i, 1); 367 | } else { 368 | this.push(new Date(year, month, date)); 369 | } 370 | } else { 371 | if (find.isPresent && !state) { 372 | this.splice(find.i, 1); 373 | } else if (!find.isPresent && state) { 374 | this.push(new Date(year, month, date)); 375 | } 376 | } 377 | } 378 | }; 379 | 380 | scope.selectedDates.clear = function () { 381 | this.length = 0; 382 | }; 383 | 384 | scope.selectedDates.sortByDate = function (direction) { 385 | 386 | direction = (direction && direction === 'desc') ? -1 : 1; 387 | if (this.length > 0) { 388 | for (var i = 0; i < this.length; i++) { 389 | this[i].sortField = glueDate(this[i]); 390 | } 391 | } 392 | 393 | this.sort(function (a, b) { 394 | return (a.sortField - b.sortField) * direction; 395 | }); 396 | }; 397 | 398 | scope.selectedDates.checkDisabledConflicts = function () { 399 | var d = 0; 400 | var s = 0; 401 | var dis = scope.disabledDates; 402 | 403 | if (scope.conflictSD === CONFLICT_S_D.DISABLED) { 404 | 405 | while (d < dis.length) { 406 | s = 0; 407 | while (s < this.length) { 408 | if (dis[d].sortField === this[s].sortField) { 409 | this.splice(s, 1); 410 | } else { 411 | s++; 412 | } 413 | } 414 | d++; 415 | } 416 | 417 | } else { 418 | 419 | while (s < this.length) { 420 | d = 0; 421 | while (d < dis.length) { 422 | if (dis[d].sortField === this[s].sortField) { 423 | dis.splice(d, 1); 424 | } else { 425 | d++; 426 | } 427 | } 428 | s++; 429 | } 430 | } 431 | 432 | }; 433 | 434 | scope.selectedDates.getNearestFutureMonth = function () { 435 | var today = new Date(); 436 | var curYear = today.getFullYear(); 437 | var curMonth = today.getMonth(); 438 | 439 | this.sortByDate(); 440 | 441 | if (this.length > 0) { 442 | for (var i = 0; i < this.length; i++) { 443 | var d = this[i]; 444 | var dYear = d.getFullYear(), dMonth = d.getMonth(); 445 | if ((dYear == curYear && dMonth >= curMonth) || dYear > curYear) { 446 | return {year: dYear, month: dMonth} 447 | } 448 | } 449 | return {year: curYear, month: curMonth}; 450 | } else { 451 | return {year: curYear, month: curMonth}; 452 | } 453 | }; 454 | 455 | scope.selectedDates.checkPeriod = function () { 456 | 457 | if (scope.selectType === SELECT_TYPE.SINGLE) { 458 | var isTruePeriod = this.length <= 1; 459 | if (isTruePeriod) { 460 | errors.remove(ERRORS.INPUT_PERIOD__SINGLE_NOT_PERIOD.CODE); 461 | } else { 462 | errors.add(ERRORS.INPUT_PERIOD__SINGLE_NOT_PERIOD.CODE); 463 | } 464 | return isTruePeriod; 465 | } 466 | 467 | if (scope.selectType === SELECT_TYPE.MULTI) { 468 | isTruePeriod = true; 469 | return isTruePeriod; 470 | } 471 | 472 | // 'period': 473 | if (this.length > 1) { 474 | 475 | this.sortByDate(); 476 | 477 | for (var i = 0; i < this.length - 1; i++) { 478 | if (this[i + 1].sortField - this[i].sortField !== 1) { 479 | var d1 = new Date(this[i].getFullYear(), this[i].getMonth(), this[i].getDate()); 480 | var d2 = new Date(this[i + 1].getFullYear(), this[i + 1].getMonth(), this[i + 1].getDate()); 481 | var diff = (d2.getTime() - d1.getTime()) / (24 * 60 * 60 * 1000); 482 | 483 | if (diff != 1) { 484 | isTruePeriod = false; 485 | errors.add(ERRORS.INPUT_PERIOD__DATES_NOT_PERIOD.CODE); 486 | return isTruePeriod; 487 | } 488 | } 489 | } 490 | } 491 | 492 | isTruePeriod = true; 493 | errors.remove(ERRORS.INPUT_PERIOD__DATES_NOT_PERIOD.CODE); 494 | return isTruePeriod; 495 | }; 496 | 497 | scope.selectedDates.checkClones = function () { 498 | 499 | scope.selectedDates.sortByDate.call(this); 500 | 501 | var i = 0; 502 | while (i < this.length - 1) { 503 | if (this[i].sortField === this[i + 1].sortField) { 504 | this.splice(i + 1, 1); 505 | } else { 506 | i++; 507 | } 508 | } 509 | }; 510 | 511 | // checking input period 512 | scope.selectedDates.checkClones(); 513 | scope.selectedDates.checkPeriod(); 514 | 515 | scope.selectedDates.checkClones.call(scope.disabledDates); 516 | for (var c = 0; c < 8; c++) { 517 | scope.selectedDates.checkClones.call(scope.calendar[c].dates); 518 | } 519 | 520 | scope.selectedDates.checkDisabledConflicts(); 521 | } 522 | 523 | function initCalendarDates() { 524 | 525 | 526 | // VIEWED DATES: 527 | scope.dayList = []; 528 | // methods: 529 | scope.dayList.zero = function () { 530 | this.length = 0; 531 | }; 532 | 533 | scope.dayList.findDay = function (year, month, date) { 534 | for (var i = 0; i < this.length; i++) { 535 | if (this[i].year === year && this[i].month === month && this[i].date === date) { 536 | return i; 537 | } 538 | } 539 | }; 540 | 541 | scope.dayList.repaint = function () { 542 | var viewMonthDates = []; 543 | scope.selectedDates.sortByDate(); 544 | 545 | var firstDay = glueDate(this[0]); 546 | var lastDay = glueDate(this[this.length - 1]); 547 | 548 | var sd = scope.selectedDates; 549 | for (var i = 0; i < sd.length; i++) { 550 | if (sd[i].sortField >= firstDay && sd[i].sortField <= lastDay) { 551 | viewMonthDates.push(sd[i].sortField); 552 | } else if (sd[i].sortField > lastDay) { 553 | break; 554 | } 555 | } 556 | 557 | i = 0; 558 | while (i < this.length) { 559 | this[i].style.isSelected = viewMonthDates.indexOf(glueDate(this[i])) >= 0; 560 | i++; 561 | } 562 | }; 563 | 564 | scope.dayList.repaintDay = function (year, month, date) { 565 | scope.dayList.repaint(); 566 | var i = this.findDay(year, month, date); 567 | this[i].style.isSelected = !this[i].style.isSelected; 568 | }; 569 | } 570 | 571 | function initBtns() { 572 | // BUTTONS: 573 | scope.btns = []; 574 | 575 | if (scope.btnClearShow && scope.accessType === ACCESS_TYPE.WRITE) { 576 | scope.btns.push({ 577 | text: scope.btnClear, 578 | type: scope.btnClearClass, 579 | sType: 'clear', 580 | onClickModal: function () { 581 | btnClear(); 582 | }, 583 | onTap: function (e) { 584 | btnClear(); 585 | if (scope.btnsIsNative) { 586 | e.preventDefault(); 587 | } 588 | } 589 | }); 590 | } 591 | 592 | if (scope.btnTodayShow) { 593 | scope.btns.push({ 594 | text: scope.btnToday, 595 | type: scope.btnTodayClass, 596 | sType: 'today', 597 | onClickModal: function () { 598 | btnToday(); 599 | }, 600 | onTap: function (e) { 601 | btnToday(); 602 | if (scope.btnsIsNative) { 603 | e.preventDefault(); 604 | } 605 | } 606 | }); 607 | } 608 | 609 | scope.btns.push({ 610 | text: scope.btnCancel, 611 | type: scope.btnCancelClass, 612 | sType: 'cancel', 613 | onClickModal: function () { 614 | btnCancel(); 615 | scope.closeModal(); 616 | }, 617 | onTap: function () { 618 | btnCancel(); 619 | if (!scope.btnsIsNative) { 620 | scope.popup.close(); 621 | } 622 | } 623 | }); 624 | 625 | if (scope.accessType === ACCESS_TYPE.WRITE) { 626 | scope.btns.push({ 627 | text: scope.btnOk, 628 | type: scope.btnOkClass, 629 | sType: 'ok', 630 | onClickModal: function () { 631 | btnOk(); 632 | scope.closeModal(); 633 | }, 634 | onTap: function () { 635 | btnOk(); 636 | if (!scope.btnsIsNative) { 637 | scope.popup.close(); 638 | } 639 | } 640 | }); 641 | } 642 | 643 | if (scope.templateType === TEMPLATE_TYPE.MODAL) scope.btns.reverse() 644 | } 645 | 646 | function setViewMonth() { 647 | // select viewed month(current || nearest next) 648 | if (scope.inputObj.viewMonth && scope.inputObj.viewMonth.length > 0) { 649 | scope.viewYear = scope.inputObj.viewMonth[0].getFullYear(); 650 | scope.viewMonth = scope.inputObj.viewMonth[0].getMonth(); 651 | } else if (scope.selectedDates && scope.selectedDates.length > 0) { 652 | var date = scope.selectedDates.getNearestFutureMonth(); 653 | scope.viewYear = date.year; 654 | scope.viewMonth = date.month; 655 | } else { 656 | scope.viewYear = new Date().getFullYear(); 657 | scope.viewMonth = new Date().getMonth(); 658 | } 659 | } 660 | 661 | function refreshDateList() { 662 | 663 | var today = new Date(); 664 | var viewYear = scope.viewYear; 665 | var viewMonth = scope.viewMonth; 666 | var nowDay = today.getDate(); 667 | var isCurMonthNow = (viewYear === today.getFullYear() && viewMonth === today.getMonth()); 668 | 669 | var lastDay = new Date(viewYear, viewMonth + 1, 0).getDate(); 670 | 671 | scope.dayList.zero(); 672 | 673 | // current month 674 | for (var i = 1; i <= lastDay; i++) { 675 | var isViewMonth = true; 676 | 677 | var isToday = isCurMonthNow && nowDay === i; 678 | var isCalendar = []; 679 | for (var c = 0; c < 8; c++) { 680 | isCalendar[c] = scope.selectedDates.findDate.call(scope.calendar[c].dates, viewYear, viewMonth, i).isPresent; 681 | } 682 | 683 | var isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, viewYear, viewMonth, i, true).isPresent; 684 | var isSelected = scope.selectedDates.findDate(viewYear, viewMonth, i).isPresent && !isDisabled; 685 | 686 | var iDate = new Date(viewYear, viewMonth, i); 687 | 688 | scope.dayList.push({ 689 | year: viewYear, 690 | month: viewMonth, 691 | date: i, 692 | day: iDate.getDay(), 693 | style: { 694 | isSelected: isSelected, 695 | isToday: isToday, 696 | isDisabled: isDisabled, 697 | isCalendar0: isCalendar[0], 698 | isCalendar1: isCalendar[1], 699 | isCalendar2: isCalendar[2], 700 | isCalendar3: isCalendar[3], 701 | isCalendar4: isCalendar[4], 702 | isCalendar5: isCalendar[5], 703 | isCalendar6: isCalendar[6], 704 | isCalendar7: isCalendar[7], 705 | isViewMonth: isViewMonth 706 | } 707 | }); 708 | } 709 | 710 | // set Monday as the first day of the week. 711 | var insertDays = scope.dayList[0].day - scope.mondayFirst; 712 | insertDays = (insertDays < 0) ? 6 : insertDays; 713 | lastDay = new Date(viewYear, viewMonth, 0).getDate(); 714 | 715 | // end of preview month 716 | var date = monthShift(viewYear, viewMonth, '-'); 717 | isViewMonth = false; 718 | isToday = false; 719 | 720 | 721 | for (var j = 0; j < insertDays; j++) { 722 | 723 | 724 | for (c = 0; c < 8; c++) { 725 | isCalendar[c] = scope.selectedDates.findDate.call(scope.calendar[c].dates, date.year, date.month, lastDay - j).isPresent; 726 | } 727 | 728 | isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, date.year, date.month, lastDay - j).isPresent; 729 | isSelected = scope.selectedDates.findDate(date.year, date.month, lastDay - j).isPresent && !isDisabled; 730 | 731 | iDate = new Date(date.year, date.month, lastDay - j); 732 | 733 | scope.dayList.unshift({ 734 | year: date.year, 735 | month: date.month, 736 | date: lastDay - j, 737 | day: iDate.getDay(), 738 | style: { 739 | isSelected: isSelected, 740 | isToday: isToday, 741 | isDisabled: isDisabled, 742 | isCalendar0: isCalendar[0], 743 | isCalendar1: isCalendar[1], 744 | isCalendar2: isCalendar[2], 745 | isCalendar3: isCalendar[3], 746 | isCalendar4: isCalendar[4], 747 | isCalendar5: isCalendar[5], 748 | isCalendar6: isCalendar[6], 749 | isCalendar7: isCalendar[7], 750 | isViewMonth: isViewMonth 751 | } 752 | }); 753 | } 754 | 755 | scope.rows = [0, 7, 14, 21, 28]; 756 | if (scope.dayList.length / 7 > 5) { 757 | scope.rows.push(35); // = [0, 7, 14, 21, 28, 35]; 758 | } 759 | 760 | var daysLeft = 7 - scope.dayList.length % 7; 761 | // start of next month 762 | date = monthShift(scope.viewYear, scope.viewMonth, '+'); 763 | for (i = 1; i <= daysLeft; i++) { 764 | for (c = 0; c < 8; c++) { 765 | isCalendar[c] = scope.selectedDates.findDate.call(scope.calendar[c].dates, date.year, date.month, i).isPresent; 766 | } 767 | 768 | isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, date.year, date.month, i).isPresent; 769 | isSelected = scope.selectedDates.findDate(date.year, date.month, i).isPresent && !isDisabled; 770 | iDate = new Date(date.year, date.month, i); 771 | 772 | scope.dayList.push({ 773 | year: date.year, 774 | month: date.month, 775 | date: i, 776 | day: iDate.getDay(), 777 | style: { 778 | isSelected: isSelected, 779 | isToday: isToday, 780 | isDisabled: isDisabled, 781 | isCalendar0: isCalendar[0], 782 | isCalendar1: isCalendar[1], 783 | isCalendar2: isCalendar[2], 784 | isCalendar3: isCalendar[3], 785 | isCalendar4: isCalendar[4], 786 | isCalendar5: isCalendar[5], 787 | isCalendar6: isCalendar[6], 788 | isCalendar7: isCalendar[7], 789 | isViewMonth: isViewMonth 790 | } 791 | }); 792 | } 793 | 794 | scope.cols = [0, 1, 2, 3, 4, 5, 6]; 795 | 796 | } 797 | 798 | scope.prevMonth = function () { 799 | var date = monthShift(scope.viewYear, scope.viewMonth, '-'); 800 | if (scope.fromYearMonth === undefined || date.year * 100 + date.month >= scope.fromYearMonth) { 801 | scope.viewYear = date.year; 802 | scope.viewMonth = date.month; 803 | 804 | refreshDateList(); 805 | } 806 | }; 807 | 808 | scope.nextMonth = function () { 809 | var date = monthShift(scope.viewYear, scope.viewMonth, '+'); 810 | if (scope.toYearMonth === undefined || date.year * 100 + date.month <= scope.toYearMonth) { 811 | scope.viewYear = date.year; 812 | scope.viewMonth = date.month; 813 | refreshDateList(); 814 | } 815 | }; 816 | 817 | scope.monthYearSelect = function () { 818 | var year = scope.monthYear.select.getFullYear(); 819 | var month = scope.monthYear.select.getMonth(); 820 | if ((scope.toYearMonth === undefined || year * 100 + month <= scope.toYearMonth) && (scope.fromYearMonth === undefined || year * 100 + month >= scope.fromYearMonth)) { 821 | 822 | scope.viewYear = year; 823 | scope.viewMonth = month; 824 | 825 | refreshDateList(); 826 | } else { 827 | 828 | } 829 | }; 830 | 831 | // date-cell ng-click: 832 | scope.onTap = function (date, row) { 833 | if (scope.accessType == ACCESS_TYPE.WRITE) { 834 | if (!scope.selectByWeek.is) { 835 | selectDay(date) 836 | } else { 837 | if (scope.selectByWeekMode === SELECT_BY_WEEK_MODE.NORMAL) { 838 | var state = !scope.selectedDates.findDate(date.year, date.month, date.date).isPresent; 839 | } 840 | for (var i = 0; i < 7; i++) { 841 | var d = scope.dayList[row + i]; 842 | selectDay(d, state); 843 | } 844 | } 845 | 846 | if (scope.closeOnSelect) { 847 | btnOk(); 848 | if (scope.templateType === TEMPLATE_TYPE.POPUP) { 849 | $timeout(scope.popup.close, 300); 850 | } else { 851 | $timeout(scope.closeModal, 300); 852 | } 853 | } 854 | } 855 | }; 856 | 857 | scope.onHold = function (date) { 858 | scope.holded = { 859 | is: true, 860 | isSelected: date.style.isSelected, 861 | isDisabled: date.style.isDisabled, 862 | isToday: date.style.isToday, 863 | isCalendar0: date.style.isCalendar0, 864 | isCalendar1: date.style.isCalendar1, 865 | isCalendar2: date.style.isCalendar2, 866 | isCalendar3: date.style.isCalendar3, 867 | isCalendar4: date.style.isCalendar4, 868 | isCalendar5: date.style.isCalendar5, 869 | isCalendar6: date.style.isCalendar6, 870 | isCalendar7: date.style.isCalendar7, 871 | date: date.date 872 | }; 873 | }; 874 | 875 | scope.onRelease = function (date) { 876 | scope.holded = { 877 | is: false, 878 | date: 'date' 879 | }; 880 | }; 881 | 882 | function selectDay(date, state) { 883 | var isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, date.year, date.month, date.date).isPresent; 884 | if (!isDisabled) { 885 | scope.selectedDates.addRemove(date.year, date.month, date.date, state); 886 | scope.dayList.repaint(); 887 | scope.selectedDates.checkPeriod(); 888 | 889 | } 890 | } 891 | 892 | function monthShift(year, month, direction) { 893 | switch (direction) { 894 | case '+': 895 | if (month === 11) { 896 | year++; 897 | month = 0; 898 | } else { 899 | month++; 900 | } 901 | break; 902 | 903 | case '-': 904 | if (month === 0) { 905 | year--; 906 | month = 11; 907 | } else { 908 | month--; 909 | } 910 | break; 911 | } 912 | 913 | return {year: year, month: month}; 914 | } 915 | 916 | function btnOk() { 917 | scope.inputObj.callback(scope.selectedDates); 918 | } 919 | 920 | function btnCancel() { 921 | scope.inputObj.callback(scope.inputDates); 922 | } 923 | 924 | function btnClear() { 925 | scope.selectedDates.clear(); 926 | scope.dayList.repaint(); 927 | scope.selectedDates.checkPeriod(); 928 | } 929 | 930 | function btnToday() { 931 | var d = new Date(); 932 | 933 | scope.viewYear = d.getFullYear(); 934 | scope.viewMonth = d.getMonth(); 935 | 936 | refreshDateList(); 937 | } 938 | 939 | function initModal() { 940 | // reference for the 'ionic-multi-date-picker' modal. 941 | $ionicModal.fromTemplateUrl('ionic-multi-date-picker-modal.html', { 942 | scope: scope, 943 | animation: 'slide-in-up' 944 | }).then(function (modal) { 945 | scope.modal = modal; 946 | }); 947 | scope.openModal = function () { 948 | scope.modal.show(); 949 | }; 950 | scope.closeModal = function () { 951 | scope.modal.hide(); 952 | }; 953 | } 954 | 955 | //Called when the user clicks on the button to invoke the 'ionic-multi-date-picker' 956 | element.on("click", function () { 957 | //This code is added to set passed date from datepickerObject 958 | start(); 959 | 960 | if (scope.templateType === TEMPLATE_TYPE.MODAL) { 961 | scope.openModal(); 962 | } else { 963 | //Getting the reference for the 'ionic-multi-date-picker' popup. 964 | var buttons = scope.btns; 965 | if (!scope.btnsIsNative) { 966 | buttons = []; 967 | } 968 | scope.popup = $ionicPopup.show({ 969 | templateUrl: 'ionic-multi-date-picker-popup.html', 970 | cssClass: 'picker-body', 971 | scope: scope, 972 | buttons: buttons 973 | }); 974 | } 975 | }); 976 | } 977 | }; 978 | } 979 | 980 | })(); 981 | //By Rajeshwar Patlolla - rajeshwar.patlolla@gmail.com 982 | //https://github.com/rajeshwarpatlolla 983 | 984 | // forked and edited by Denni Adam - dennila2@gmail.com 985 | // https://github.com/dennila2 986 | (function(){ 987 | 'use strict'; 988 | 989 | angular.module('ionic-multi-date-picker') 990 | .service('IonicMultiDatePickerService', IonicMultiDatePickerService); 991 | 992 | IonicMultiDatePickerService.$inject = []; 993 | function IonicMultiDatePickerService(){ 994 | this.monthsList = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; 995 | 996 | } 997 | 998 | })(); -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var del = require('del'); 3 | var concat = require('gulp-concat'); 4 | var uglify = require('gulp-uglify'); 5 | var ngHtml2Js = require("gulp-ng-html2js"); 6 | var minifyHtml = require("gulp-minify-html"); 7 | 8 | var sass = require('gulp-sass'); 9 | var minifyCss = require('gulp-minify-css'); 10 | var css2js = require("gulp-css2js"); 11 | 12 | var path = { 13 | src: ['./src/*.*'] 14 | }; 15 | 16 | gulp.task('html2js', function () { 17 | return gulp.src(['./src/*.html']) 18 | .pipe(minifyHtml()) 19 | .pipe(ngHtml2Js({ 20 | moduleName: "ionic-multi-date-picker.templates" 21 | })) 22 | .pipe(concat("templates.js")) 23 | //.pipe(uglify()) 24 | .pipe(gulp.dest("./dist")); 25 | }); 26 | 27 | gulp.task('scss', function () { 28 | gulp.src('./src/ionic-multi-date-picker.scss') 29 | .pipe(sass()) 30 | .on('error', sass.logError) 31 | .pipe(gulp.dest('./src/')); 32 | /*.pipe(minifyCss({ 33 | keepSpecialComments: 0 34 | })) 35 | .pipe(rename({ extname: '.min.css' })) 36 | .pipe(gulp.dest('./www/css/')) 37 | .on('end', done);*/ 38 | }); 39 | 40 | gulp.task('css2js', function () { 41 | return gulp.src('./src/ionic-multi-date-picker.scss') 42 | .pipe(sass()) 43 | .pipe(minifyCss({ 44 | keepSpecialComments: 0 45 | })) 46 | .pipe(css2js()) 47 | //.pipe(uglify()) 48 | .pipe(gulp.dest("./dist/")); 49 | }); 50 | 51 | gulp.task('make-bundle', ['del', 'html2js', 'css2js'], function () { 52 | return gulp.src(['dist/*.js', './src/*.js']) 53 | .pipe(concat('ionic-multi-date-picker.bundle.min.js')) 54 | //.pipe(uglify()) 55 | .pipe(gulp.dest('dist/')); 56 | }); 57 | 58 | gulp.task('del-temp-files', ['make-bundle'], function () { 59 | return del(['dist/templates.js', 'dist/ionic-multi-date-picker.styles.js']); 60 | }); 61 | 62 | gulp.task('del', function () { 63 | return del(['dist/*']); 64 | }); 65 | 66 | gulp.task('build', ['del-temp-files']); 67 | 68 | 69 | gulp.task('watch', function () { 70 | gulp.watch(path.src, ['build']); 71 | }); 72 | 73 | gulp.task('default', ['watch']); -------------------------------------------------------------------------------- /images/imdp-android.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DenniLa2/ionic-datepicker/8a206e4b160964b4c538bfa8e365d46ea5b940ae/images/imdp-android.jpg -------------------------------------------------------------------------------- /images/imdp-calendarNames.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DenniLa2/ionic-datepicker/8a206e4b160964b4c538bfa8e365d46ea5b940ae/images/imdp-calendarNames.jpg -------------------------------------------------------------------------------- /images/imdp-ios-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DenniLa2/ionic-datepicker/8a206e4b160964b4c538bfa8e365d46ea5b940ae/images/imdp-ios-2.jpg -------------------------------------------------------------------------------- /images/mdp-ios-name-convention.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DenniLa2/ionic-datepicker/8a206e4b160964b4c538bfa8e365d46ea5b940ae/images/mdp-ios-name-convention.jpg -------------------------------------------------------------------------------- /images/mdp-ios-year-month-select.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DenniLa2/ionic-datepicker/8a206e4b160964b4c538bfa8e365d46ea5b940ae/images/mdp-ios-year-month-select.jpg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-multi-date-picker", 3 | "version": "2.0.0", 4 | "description": "A multi date picker for Ionic framework", 5 | "main": [ 6 | "./dist/ionic-multi-date-picker.bundle.min.js" 7 | ], 8 | "scripts": {}, 9 | "author": "https://github.com/dennila2, dennila2@gmail.com", 10 | "fork": "https://github.com/rajeshwarpatlolla, rajeshwar.patlolla@gmail.com", 11 | "license": "MIT", 12 | "dependencies": {}, 13 | "devDependencies": { 14 | "gulp": "^3.9.0", 15 | "del": "^1.2.1", 16 | "gulp-concat": "^2.6.0", 17 | "gulp-css2js": "^1.0.2", 18 | "gulp-minify-html": "^1.0.4", 19 | "gulp-ng-html2js": "^0.2.0", 20 | "gulp-uglify": "^1.2.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ionic-multi-date-picker-modal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 |
7 | 8 | 9 | 10 |
11 | 12 |
13 | 14 | 15 |
16 | 23 |
24 |
25 | 26 |
27 | -------------------------------------------------------------------------------- /src/ionic-multi-date-picker-plain.html: -------------------------------------------------------------------------------- 1 |
{{ inputObj.header }}
2 | 3 | 6 | 7 | 18 | -------------------------------------------------------------------------------- /src/ionic-multi-date-picker-popup.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |

6 |
7 | 8 | 9 | 10 |
11 | 18 |
19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /src/ionic-multi-date-picker.app.js: -------------------------------------------------------------------------------- 1 | //By Rajeshwar Patlolla - rajeshwar.patlolla@gmail.com 2 | //https://github.com/rajeshwarpatlolla 3 | 4 | // forked and edited by Denni Adam - dennila2@gmail.com 5 | // https://github.com/dennila2 6 | (function(){ 7 | 'use strict'; 8 | 9 | angular.module('ionic-multi-date-picker', ['ionic','ionic-multi-date-picker.templates']); 10 | 11 | })(); -------------------------------------------------------------------------------- /src/ionic-multi-date-picker.css: -------------------------------------------------------------------------------- 1 | .picker-body { 2 | height: inherit; } 3 | .picker-body .popup-head { 4 | padding: 0; 5 | border: 0; } 6 | .picker-body .weekend { 7 | color: #2b33ff; } 8 | .picker-body .not-cur-month { 9 | color: gray; } 10 | .picker-body .today { 11 | font-weight: bolder; 12 | text-decoration: underline; } 13 | .picker-body .popup-body { 14 | overflow: inherit !important; 15 | padding: 0; } 16 | 17 | .ionic-datepicker { 18 | /*.today { 19 | background-color: rgba(186, 186, 186, 1); 20 | }*/ } 21 | .ionic-datepicker .selected_date_full { 22 | color: #387EF5; 23 | font-weight: bold; 24 | text-align: center; 25 | padding-bottom: 5px; } 26 | .ionic-datepicker .color_blue { 27 | color: #387ef5; } 28 | .ionic-datepicker .bg_color_blue { 29 | background-color: #387ef5; } 30 | .ionic-datepicker .date_col:hover { 31 | /* background-color: rgba(56, 126, 245, 0.5);*/ 32 | cursor: pointer; } 33 | .ionic-datepicker .date_col:active { 34 | background-color: #c0f5c6; 35 | cursor: pointer; } 36 | .ionic-datepicker .no_padding { 37 | padding: 0; } 38 | .ionic-datepicker .date_cell { 39 | padding: 5px; } 40 | .ionic-datepicker .date-selected { 41 | background-color: #50f53a; 42 | border-radius: 50%; 43 | color: white !important; } 44 | .ionic-datepicker .header { 45 | background-color: #007aff; 46 | min-height: 50px; 47 | border-bottom: 1px solid #4c48ff; } 48 | .ionic-datepicker .icon-chevron:before { 49 | background-color: white; 50 | width: 24px; 51 | height: 24px; 52 | border-radius: 50%; 53 | padding: 5px 3px; 54 | position: absolute; 55 | top: 10px; } 56 | .ionic-datepicker .icon-chevron-left:before { 57 | left: 10px; } 58 | .ionic-datepicker .icon-chevron-right:before { 59 | right: 10px; } 60 | .ionic-datepicker .view-month { 61 | color: white; 62 | padding: 14px; } 63 | .ionic-datepicker .pointer_events_none { 64 | pointer-events: none !important; 65 | color: #AAAAAA; } 66 | .ionic-datepicker .select_section { 67 | padding: 0; } 68 | .ionic-datepicker .select_section label { 69 | padding: 12px; } 70 | .ionic-datepicker .select_section select { 71 | font-size: 12px; 72 | font-weight: bold; 73 | padding: 2px 10px; 74 | direction: ltr; 75 | left: 0; 76 | width: 100%; 77 | max-width: 100%; } 78 | .ionic-datepicker .select_section .item-select:after { 79 | right: 4px; 80 | border-top: 4px solid; 81 | border-right: 4px solid transparent; 82 | border-left: 4px solid transparent; } 83 | .ionic-datepicker .left_arrow { 84 | direction: rtl; } 85 | .ionic-datepicker .font_22px { 86 | font-size: 22px; } 87 | .ionic-datepicker .btns { 88 | float: right; } 89 | .ionic-datepicker .clear { 90 | clear: both; } 91 | 92 | .ionic_datepicker_modal_content { 93 | padding-top: 10%; } 94 | .ionic_datepicker_modal_content .ionic-datepicker .selected_date_full { 95 | font-size: 20px; 96 | padding: 20px; } 97 | .ionic_datepicker_modal_content .cal-button { 98 | padding: 0 !important; 99 | font-size: 14px !important; } 100 | 101 | @media (min-width: 680px) { 102 | .ionic_datepicker_modal_content { 103 | padding-top: 0; } 104 | .ionic_datepicker_modal_content .ionic-datepicker .selected_date_full { 105 | font-size: inherit; } 106 | .ionic_datepicker_modal_content .ionic-datepicker .selected_date_full { 107 | padding: 10px 0 0 0; } } 108 | 109 | /* 110 | .ionic_datepicker_popup_btn_cancel { 111 | position: fixed; 112 | top: 10px; 113 | right: 10px; 114 | padding-top: 3px; 115 | padding-left: 8px; 116 | font-size: 17px; 117 | width: 30px; 118 | height: 30px; 119 | border: 2px solid rgba(235, 71, 60, 0.95); 120 | color: white; 121 | border-radius: 15px; 122 | background-color: rgba(235, 71, 60, 0.95); 123 | }*/ 124 | -------------------------------------------------------------------------------- /src/ionic-multi-date-picker.directive.js: -------------------------------------------------------------------------------- 1 | //By Rajeshwar Patlolla - rajeshwar.patlolla@gmail.com 2 | 3 | // forked and rewrited by Denni Adam - dennila2@gmail.com 4 | // https://github.com/dennila2 5 | 6 | (function () { 7 | 'use strict'; 8 | 9 | angular.module('ionic-multi-date-picker') 10 | .directive('ionicMultiDatePicker', IonicMultiDatePicker); 11 | 12 | IonicMultiDatePicker.$inject = ['$ionicGesture', '$ionicModal', '$ionicPopup', '$timeout', 'IonicMultiDatePickerService']; 13 | 14 | function IonicMultiDatePicker($ionicGesture, $ionicModal, $ionicPopup, $timeout, IonicMultiDatePickerService) { 15 | return { 16 | restrict: 'AE', 17 | replace: false, 18 | /*template: function (elem, attrs) { 19 | console.log('elem'); 20 | console.log(elem); 21 | if (attrs.calendar === 'true') { 22 | return '
date-picker
{{ inputObj.header }}
' 23 | } 24 | return ''; 25 | },*/ 26 | scope: { 27 | inputObj: "=inputObj" 28 | }, 29 | link: function (scope, element, attrs) { 30 | // IDE definitions 31 | var ERRORS = { 32 | INPUT_PERIOD__SINGLE_NOT_PERIOD: { 33 | CODE: 'INPUT_PERIOD__SINGLE_NOT_PERIOD', 34 | EN: 'Date is not single', 35 | RU: 'Должно быть не больше одной даты' 36 | }, 37 | INPUT_PERIOD__DATES_NOT_PERIOD: { 38 | CODE: 'INPUT_PERIOD__DATES_NOT_PERIOD', 39 | EN: 'Dates is not period', 40 | RU: 'Даты не являются периодом' 41 | }, 42 | UNKNOWN_ERROR: { 43 | CODE: 'UNKNOWN_ERROR', 44 | EN: 'Unknown error', 45 | RU: 'Неизвестная ошибка' 46 | }, 47 | ERROR_DELETING_UNKNOWN_ERROR: { 48 | CODE: 'ERROR_DELETING_UNKNOWN_ERROR', 49 | EN: 'Error deleting unknown error', 50 | RU: 'Ошибка удаления неизвестной ошибки' 51 | } 52 | }; 53 | var SELECT_TYPE = {MULTI: 'MULTI', PERIOD: 'PERIOD', SINGLE: 'SINGLE'}; 54 | var ACCESS_TYPE = {WRITE: 'WRITE', READ: 'READ'}; 55 | var ERROR_LANGUAGE = {EN: 'EN', RU: 'RU'}; 56 | var TEMPLATE_TYPE = {POPUP: 'POPUP', MODAL: 'MODAL'}; 57 | var CONFLICT_S_D = {DISABLED: 'DISABLED', SELECTED: 'SELECTED'}; 58 | var SELECT_BY_WEEK_MODE = {INVERSION: 'INVERSION', NORMAL: 'NORMAL'}; 59 | 60 | function start() { 61 | initErrors(); 62 | initView(); 63 | initDates(); 64 | initCalendarDates(); 65 | initBtns(); 66 | setViewMonth(); 67 | refreshDateList(); 68 | } 69 | 70 | initModal(); 71 | 72 | var errors; 73 | 74 | function initErrors() { 75 | scope.errors = {len: 0}; 76 | Object.defineProperty(scope.errors, "len", {enumerable: false}); 77 | 78 | errors = (function () { 79 | 80 | return { 81 | add: function (code) { 82 | if (!scope.errors.hasOwnProperty(code) && ERRORS.hasOwnProperty(code)) { 83 | console.debug('code+: ' + code); 84 | var err = ERRORS[code]; 85 | scope.errors[code] = ERRORS[code]; 86 | } else if (!scope.errors.hasOwnProperty(code) && !ERRORS.hasOwnProperty(code)) { 87 | console.debug('code: ' + code); 88 | err = ERRORS.UNKNOWN_ERROR; 89 | scope.errors.UNKNOWN_ERROR = ERRORS.UNKNOWN_ERROR; 90 | } else { 91 | // error already in array 92 | } 93 | this.length(); 94 | }, 95 | remove: function (code) { 96 | if (scope.errors.hasOwnProperty(code) && ERRORS.hasOwnProperty(code)) { 97 | delete scope.errors[code]; 98 | } else if (scope.errors.hasOwnProperty(code) && !ERRORS.hasOwnProperty(code)) { 99 | scope.errors.ERROR_DELETING_UNKNOWN_ERROR = ERRORS.ERROR_DELETING_UNKNOWN_ERROR; 100 | } 101 | this.length(); 102 | }, 103 | 104 | length: function () { 105 | scope.errors.len = 0; 106 | for (var err in scope.errors) { 107 | scope.errors.len++; 108 | } 109 | } 110 | } 111 | })(); 112 | } 113 | 114 | function initView() { 115 | //Setting the title, today, close and set strings for the date picker 116 | scope.templateType = (scope.inputObj.templateType && TEMPLATE_TYPE.hasOwnProperty(scope.inputObj.templateType) > -1) ? (scope.inputObj.templateType) : TEMPLATE_TYPE.POPUP; 117 | 118 | 119 | scope.currentMonth = ''; 120 | scope.currentYear = ''; 121 | scope.monthYear = { 122 | select: new Date() 123 | }; 124 | 125 | scope.header = (scope.inputObj.header && scope.inputObj.header.length > 0) ? scope.inputObj.header : ''; 126 | if (scope.templateType === TEMPLATE_TYPE.MODAL && scope.header === '') scope.header = 'Datepicker'; 127 | scope.headerClass = scope.inputObj.headerClass; 128 | 129 | scope.btnsIsNative = !!scope.inputObj.btnsIsNative; 130 | 131 | scope.btnOk = scope.inputObj.btnOk ? scope.inputObj.btnOk : 'Ok'; 132 | scope.btnOkClass = scope.inputObj.btnOkClass ? scope.inputObj.btnOkClass : 'button-stable cal-button'; 133 | 134 | scope.btnCancel = scope.inputObj.btnCancel ? scope.inputObj.btnCancel : 'Close'; 135 | scope.btnCancelClass = scope.inputObj.btnCancelClass ? scope.inputObj.btnCancelClass : 'button-stable cal-button'; 136 | 137 | scope.btnTodayShow = !!scope.inputObj.btnTodayShow; 138 | if (scope.btnTodayShow) { 139 | scope.btnToday = scope.inputObj.btnToday ? scope.inputObj.btnToday : 'Today'; 140 | scope.btnTodayClass = scope.inputObj.btnTodayClass ? scope.inputObj.btnTodayClass : 'button-stable cal-button'; 141 | } 142 | 143 | scope.btnClearShow = !!scope.inputObj.btnClearShow; 144 | if (scope.btnClearShow) { 145 | scope.btnClear = scope.inputObj.btnClear ? scope.inputObj.btnClear : 'Clear'; 146 | scope.btnClearClass = scope.inputObj.btnClearClass ? scope.inputObj.btnClearClass : 'button-stable cal-button'; 147 | } 148 | scope.selectType = (scope.inputObj.selectType && SELECT_TYPE.hasOwnProperty(scope.inputObj.selectType) > -1 ) ? scope.inputObj.selectType : SELECT_TYPE.MULTI; 149 | 150 | scope.tglSelectByWeekShow = scope.inputObj.tglSelectByWeekShow === true; 151 | scope.tglSelectByWeek = scope.inputObj.tglSelectByWeek ? scope.inputObj.tglSelectByWeek : 'Select by week'; 152 | scope.selectByWeekMode = (scope.inputObj.selectByWeekMode && scope.inputObj.selectByWeekMode === SELECT_BY_WEEK_MODE.INVERSION) ? SELECT_BY_WEEK_MODE.INVERSION : SELECT_BY_WEEK_MODE.NORMAL; 153 | scope.selectByWeekMode = (scope.inputObj.selectByWeekMode && scope.inputObj.selectByWeekMode === SELECT_BY_WEEK_MODE.INVERSION) ? SELECT_BY_WEEK_MODE.INVERSION : SELECT_BY_WEEK_MODE.NORMAL; 154 | scope.selectByWeek = {is: !!(scope.inputObj.isSelectByWeek === true && scope.tglSelectByWeekShow === true)}; 155 | scope.tglSelectByWeekClass = scope.inputObj.tglSelectByWeekClass ? scope.inputObj.tglSelectByWeekClass : 'toggle-energized'; 156 | scope.titleSelectByWeekClass = scope.inputObj.titleSelectByWeekClass ? scope.inputObj.titleSelectByWeekClass : 'energized energized-border'; 157 | 158 | scope.accessType = (scope.inputObj.accessType && ACCESS_TYPE.hasOwnProperty(scope.inputObj.accessType) > -1) ? scope.inputObj.accessType : ACCESS_TYPE.WRITE; 159 | scope.showErrors = (scope.inputObj.showErrors && scope.inputObj.showErrors !== true) ? false : true; 160 | scope.errorLanguage = (scope.inputObj.errorLanguage && ERROR_LANGUAGE.hasOwnProperty(scope.inputObj.errorLanguage)) ? scope.inputObj.errorLanguage : ERROR_LANGUAGE.EN; 161 | 162 | if (scope.inputObj.fromDate && Date.prototype.isPrototypeOf(scope.inputObj.fromDate)) { 163 | scope.fromYearMonth = scope.inputObj.fromDate.getFullYear() * 100 + scope.inputObj.fromDate.getMonth(); 164 | } else { 165 | scope.fromYearMonth = undefined; 166 | } 167 | 168 | if (scope.inputObj.toDate && Date.prototype.isPrototypeOf(scope.inputObj.toDate)) { 169 | scope.toYearMonth = scope.inputObj.toDate.getFullYear() * 100 + scope.inputObj.toDate.getMonth(); 170 | } else { 171 | scope.toYearMonth = undefined; 172 | } 173 | 174 | scope.conflictSD = (scope.inputObj.conflictSelectedDisabled && CONFLICT_S_D.hasOwnProperty(scope.inputObj.conflictSelectedDisabled)) ? scope.inputObj.conflictSelectedDisabled : CONFLICT_S_D.DISABLED; 175 | 176 | scope.closeOnSelect = !!scope.inputObj.closeOnSelect; 177 | 178 | scope.modalFooterClass = scope.inputObj.modalFooterClass ? scope.inputObj.modalFooterClass : 'bar-light'; 179 | 180 | // Setting the months list. This is useful, if the component needs to use some other language. 181 | scope.monthsList = []; 182 | if (scope.inputObj.monthList && scope.inputObj.monthList.length === 12) { 183 | scope.monthsList = scope.inputObj.monthList; 184 | } else { 185 | scope.monthsList = IonicMultiDatePickerService.monthsList; 186 | } 187 | // weaklist 188 | if (scope.inputObj.weekDaysList && scope.inputObj.weekDaysList.length === 7) { 189 | scope.weekNames = scope.inputObj.weekDaysList; 190 | } else { 191 | scope.weekNames = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; 192 | } 193 | 194 | // Setting whether to show Monday as the first day of the week or not. 195 | scope.mondayFirst = !!scope.inputObj.mondayFirst; 196 | 197 | if (scope.mondayFirst === true) { 198 | var lastWeekDay = scope.weekNames.shift(); 199 | scope.weekNames.push(lastWeekDay); 200 | } 201 | } 202 | 203 | function glueDate(date) { 204 | if (date instanceof Date) { 205 | return date.getFullYear() * 10000 + date.getMonth() * 100 + date.getDate(); 206 | } else { 207 | return date.year * 10000 + date.month * 100 + date.date; 208 | } 209 | } 210 | 211 | function initDates() { 212 | 213 | // INPUT DATES: 214 | // work copy & cancel copy 215 | if (scope.inputObj.selectedDates && scope.inputObj.selectedDates.length > 0) { 216 | scope.selectedDates = angular.copy(scope.inputObj.selectedDates); 217 | scope.inputDates = angular.copy(scope.inputObj.selectedDates); 218 | } else { 219 | scope.selectedDates = []; 220 | scope.inputDates = []; 221 | } 222 | 223 | // disabled dates 224 | scope.disabledDates = []; 225 | if (scope.inputObj.disabledDates && scope.inputObj.disabledDates instanceof Array) { 226 | scope.disabledDates = scope.inputObj.disabledDates; 227 | } 228 | 229 | 230 | // calendars 0 - 7 231 | scope.calendar = []; 232 | scope.calendarNamesCount = 0; 233 | 234 | for (var i = 0; i < 8; i++) { 235 | scope.calendar[i] = {dates: []}; 236 | var cn = 'calendar' + i; 237 | if (scope.inputObj[cn] && scope.inputObj[cn] instanceof Array) { 238 | 239 | scope.calendar[i].dates = scope.inputObj[cn]; 240 | /* 241 | for (var d = 0; d < scope.inputObj[cn].length; d++) { 242 | if (Date.prototype.isPrototypeOf()) { 243 | 244 | 245 | } 246 | } 247 | */ 248 | 249 | 250 | scope.calendar[i].class = scope.inputObj[cn + 'Class'] && scope.inputObj[cn + 'Class'].length > 0 ? scope.inputObj[cn + 'Class'] : 'cal-color-' + i; 251 | scope.calendar[i].name = { 252 | isShow: scope.inputObj[cn + 'Name'] && scope.inputObj[cn + 'Name'].length > 0, 253 | class: scope[cn + 'Class'], 254 | title: scope.inputObj[cn + 'Name'] 255 | }; 256 | if (scope.calendar[i].name.isShow) scope.calendarNamesCount++; 257 | } 258 | } 259 | 260 | scope.onRelease(); 261 | 262 | // methods: 263 | scope.selectedDates.findDate = function (year, month, date) { 264 | if (this.length > 0) { 265 | for (var i = 0; i < this.length; i++) { 266 | var d = this[i]; 267 | if (d.getFullYear() === year && d.getMonth() === month && d.getDate() === date) { 268 | return {isPresent: true, i: i}; 269 | } 270 | } 271 | } 272 | return {isPresent: false}; 273 | }; 274 | 275 | scope.selectedDates.addRemove = function (year, month, date, state) { 276 | var find = this.findDate(year, month, date); 277 | 278 | switch (scope.selectType) { 279 | case SELECT_TYPE.SINGLE: 280 | this.length = 0; 281 | if (find.isPresent) { 282 | //scope.selectedDates.length = 0; 283 | } else { 284 | this.push(new Date(year, month, date)); 285 | } 286 | break; 287 | 288 | default: 289 | if (state === undefined) { 290 | if (find.isPresent) { 291 | this.splice(find.i, 1); 292 | } else { 293 | this.push(new Date(year, month, date)); 294 | } 295 | } else { 296 | if (find.isPresent && !state) { 297 | this.splice(find.i, 1); 298 | } else if (!find.isPresent && state) { 299 | this.push(new Date(year, month, date)); 300 | } 301 | } 302 | } 303 | }; 304 | 305 | scope.selectedDates.clear = function () { 306 | this.length = 0; 307 | }; 308 | 309 | scope.selectedDates.sortByDate = function (direction) { 310 | 311 | direction = (direction && direction === 'desc') ? -1 : 1; 312 | if (this.length > 0) { 313 | for (var i = 0; i < this.length; i++) { 314 | this[i].sortField = glueDate(this[i]); 315 | } 316 | } 317 | 318 | this.sort(function (a, b) { 319 | return (a.sortField - b.sortField) * direction; 320 | }); 321 | }; 322 | 323 | scope.selectedDates.checkDisabledConflicts = function () { 324 | var d = 0; 325 | var s = 0; 326 | var dis = scope.disabledDates; 327 | 328 | if (scope.conflictSD === CONFLICT_S_D.DISABLED) { 329 | 330 | while (d < dis.length) { 331 | s = 0; 332 | while (s < this.length) { 333 | if (dis[d].sortField === this[s].sortField) { 334 | this.splice(s, 1); 335 | } else { 336 | s++; 337 | } 338 | } 339 | d++; 340 | } 341 | 342 | } else { 343 | 344 | while (s < this.length) { 345 | d = 0; 346 | while (d < dis.length) { 347 | if (dis[d].sortField === this[s].sortField) { 348 | dis.splice(d, 1); 349 | } else { 350 | d++; 351 | } 352 | } 353 | s++; 354 | } 355 | } 356 | 357 | }; 358 | 359 | scope.selectedDates.getNearestFutureMonth = function () { 360 | var today = new Date(); 361 | var curYear = today.getFullYear(); 362 | var curMonth = today.getMonth(); 363 | 364 | this.sortByDate(); 365 | 366 | if (this.length > 0) { 367 | for (var i = 0; i < this.length; i++) { 368 | var d = this[i]; 369 | var dYear = d.getFullYear(), dMonth = d.getMonth(); 370 | if ((dYear == curYear && dMonth >= curMonth) || dYear > curYear) { 371 | return {year: dYear, month: dMonth} 372 | } 373 | } 374 | return {year: curYear, month: curMonth}; 375 | } else { 376 | return {year: curYear, month: curMonth}; 377 | } 378 | }; 379 | 380 | scope.selectedDates.checkPeriod = function () { 381 | 382 | if (scope.selectType === SELECT_TYPE.SINGLE) { 383 | var isTruePeriod = this.length <= 1; 384 | if (isTruePeriod) { 385 | errors.remove(ERRORS.INPUT_PERIOD__SINGLE_NOT_PERIOD.CODE); 386 | } else { 387 | errors.add(ERRORS.INPUT_PERIOD__SINGLE_NOT_PERIOD.CODE); 388 | } 389 | return isTruePeriod; 390 | } 391 | 392 | if (scope.selectType === SELECT_TYPE.MULTI) { 393 | isTruePeriod = true; 394 | return isTruePeriod; 395 | } 396 | 397 | // 'period': 398 | if (this.length > 1) { 399 | 400 | this.sortByDate(); 401 | 402 | for (var i = 0; i < this.length - 1; i++) { 403 | if (this[i + 1].sortField - this[i].sortField !== 1) { 404 | var d1 = new Date(this[i].getFullYear(), this[i].getMonth(), this[i].getDate()); 405 | var d2 = new Date(this[i + 1].getFullYear(), this[i + 1].getMonth(), this[i + 1].getDate()); 406 | var diff = (d2.getTime() - d1.getTime()) / (24 * 60 * 60 * 1000); 407 | 408 | if (diff != 1) { 409 | isTruePeriod = false; 410 | errors.add(ERRORS.INPUT_PERIOD__DATES_NOT_PERIOD.CODE); 411 | return isTruePeriod; 412 | } 413 | } 414 | } 415 | } 416 | 417 | isTruePeriod = true; 418 | errors.remove(ERRORS.INPUT_PERIOD__DATES_NOT_PERIOD.CODE); 419 | return isTruePeriod; 420 | }; 421 | 422 | scope.selectedDates.checkClones = function () { 423 | 424 | scope.selectedDates.sortByDate.call(this); 425 | 426 | var i = 0; 427 | while (i < this.length - 1) { 428 | if (this[i].sortField === this[i + 1].sortField) { 429 | this.splice(i + 1, 1); 430 | } else { 431 | i++; 432 | } 433 | } 434 | }; 435 | 436 | // checking input period 437 | scope.selectedDates.checkClones(); 438 | scope.selectedDates.checkPeriod(); 439 | 440 | scope.selectedDates.checkClones.call(scope.disabledDates); 441 | for (var c = 0; c < 8; c++) { 442 | scope.selectedDates.checkClones.call(scope.calendar[c].dates); 443 | } 444 | 445 | scope.selectedDates.checkDisabledConflicts(); 446 | } 447 | 448 | function initCalendarDates() { 449 | 450 | 451 | // VIEWED DATES: 452 | scope.dayList = []; 453 | // methods: 454 | scope.dayList.zero = function () { 455 | this.length = 0; 456 | }; 457 | 458 | scope.dayList.findDay = function (year, month, date) { 459 | for (var i = 0; i < this.length; i++) { 460 | if (this[i].year === year && this[i].month === month && this[i].date === date) { 461 | return i; 462 | } 463 | } 464 | }; 465 | 466 | scope.dayList.repaint = function () { 467 | var viewMonthDates = []; 468 | scope.selectedDates.sortByDate(); 469 | 470 | var firstDay = glueDate(this[0]); 471 | var lastDay = glueDate(this[this.length - 1]); 472 | 473 | var sd = scope.selectedDates; 474 | for (var i = 0; i < sd.length; i++) { 475 | if (sd[i].sortField >= firstDay && sd[i].sortField <= lastDay) { 476 | viewMonthDates.push(sd[i].sortField); 477 | } else if (sd[i].sortField > lastDay) { 478 | break; 479 | } 480 | } 481 | 482 | i = 0; 483 | while (i < this.length) { 484 | this[i].style.isSelected = viewMonthDates.indexOf(glueDate(this[i])) >= 0; 485 | i++; 486 | } 487 | }; 488 | 489 | scope.dayList.repaintDay = function (year, month, date) { 490 | scope.dayList.repaint(); 491 | var i = this.findDay(year, month, date); 492 | this[i].style.isSelected = !this[i].style.isSelected; 493 | }; 494 | } 495 | 496 | function initBtns() { 497 | // BUTTONS: 498 | scope.btns = []; 499 | 500 | if (scope.btnClearShow && scope.accessType === ACCESS_TYPE.WRITE) { 501 | scope.btns.push({ 502 | text: scope.btnClear, 503 | type: scope.btnClearClass, 504 | sType: 'clear', 505 | onClickModal: function () { 506 | btnClear(); 507 | }, 508 | onTap: function (e) { 509 | btnClear(); 510 | if (scope.btnsIsNative) { 511 | e.preventDefault(); 512 | } 513 | } 514 | }); 515 | } 516 | 517 | if (scope.btnTodayShow) { 518 | scope.btns.push({ 519 | text: scope.btnToday, 520 | type: scope.btnTodayClass, 521 | sType: 'today', 522 | onClickModal: function () { 523 | btnToday(); 524 | }, 525 | onTap: function (e) { 526 | btnToday(); 527 | if (scope.btnsIsNative) { 528 | e.preventDefault(); 529 | } 530 | } 531 | }); 532 | } 533 | 534 | scope.btns.push({ 535 | text: scope.btnCancel, 536 | type: scope.btnCancelClass, 537 | sType: 'cancel', 538 | onClickModal: function () { 539 | btnCancel(); 540 | scope.closeModal(); 541 | }, 542 | onTap: function () { 543 | btnCancel(); 544 | if (!scope.btnsIsNative) { 545 | scope.popup.close(); 546 | } 547 | } 548 | }); 549 | 550 | if (scope.accessType === ACCESS_TYPE.WRITE) { 551 | scope.btns.push({ 552 | text: scope.btnOk, 553 | type: scope.btnOkClass, 554 | sType: 'ok', 555 | onClickModal: function () { 556 | btnOk(); 557 | scope.closeModal(); 558 | }, 559 | onTap: function () { 560 | btnOk(); 561 | if (!scope.btnsIsNative) { 562 | scope.popup.close(); 563 | } 564 | } 565 | }); 566 | } 567 | 568 | if (scope.templateType === TEMPLATE_TYPE.MODAL) scope.btns.reverse() 569 | } 570 | 571 | function setViewMonth() { 572 | // select viewed month(current || nearest next) 573 | if (scope.inputObj.viewMonth && scope.inputObj.viewMonth.length > 0) { 574 | scope.viewYear = scope.inputObj.viewMonth[0].getFullYear(); 575 | scope.viewMonth = scope.inputObj.viewMonth[0].getMonth(); 576 | } else if (scope.selectedDates && scope.selectedDates.length > 0) { 577 | var date = scope.selectedDates.getNearestFutureMonth(); 578 | scope.viewYear = date.year; 579 | scope.viewMonth = date.month; 580 | } else { 581 | scope.viewYear = new Date().getFullYear(); 582 | scope.viewMonth = new Date().getMonth(); 583 | } 584 | } 585 | 586 | function refreshDateList() { 587 | 588 | var today = new Date(); 589 | var viewYear = scope.viewYear; 590 | var viewMonth = scope.viewMonth; 591 | var nowDay = today.getDate(); 592 | var isCurMonthNow = (viewYear === today.getFullYear() && viewMonth === today.getMonth()); 593 | 594 | var lastDay = new Date(viewYear, viewMonth + 1, 0).getDate(); 595 | 596 | scope.dayList.zero(); 597 | 598 | // current month 599 | for (var i = 1; i <= lastDay; i++) { 600 | var isViewMonth = true; 601 | 602 | var isToday = isCurMonthNow && nowDay === i; 603 | var isCalendar = []; 604 | for (var c = 0; c < 8; c++) { 605 | isCalendar[c] = scope.selectedDates.findDate.call(scope.calendar[c].dates, viewYear, viewMonth, i).isPresent; 606 | } 607 | 608 | var isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, viewYear, viewMonth, i, true).isPresent; 609 | var isSelected = scope.selectedDates.findDate(viewYear, viewMonth, i).isPresent && !isDisabled; 610 | 611 | var iDate = new Date(viewYear, viewMonth, i); 612 | 613 | scope.dayList.push({ 614 | year: viewYear, 615 | month: viewMonth, 616 | date: i, 617 | day: iDate.getDay(), 618 | style: { 619 | isSelected: isSelected, 620 | isToday: isToday, 621 | isDisabled: isDisabled, 622 | isCalendar0: isCalendar[0], 623 | isCalendar1: isCalendar[1], 624 | isCalendar2: isCalendar[2], 625 | isCalendar3: isCalendar[3], 626 | isCalendar4: isCalendar[4], 627 | isCalendar5: isCalendar[5], 628 | isCalendar6: isCalendar[6], 629 | isCalendar7: isCalendar[7], 630 | isViewMonth: isViewMonth 631 | } 632 | }); 633 | } 634 | 635 | // set Monday as the first day of the week. 636 | var insertDays = scope.dayList[0].day - scope.mondayFirst; 637 | insertDays = (insertDays < 0) ? 6 : insertDays; 638 | lastDay = new Date(viewYear, viewMonth, 0).getDate(); 639 | 640 | // end of preview month 641 | var date = monthShift(viewYear, viewMonth, '-'); 642 | isViewMonth = false; 643 | isToday = false; 644 | 645 | 646 | for (var j = 0; j < insertDays; j++) { 647 | 648 | 649 | for (c = 0; c < 8; c++) { 650 | isCalendar[c] = scope.selectedDates.findDate.call(scope.calendar[c].dates, date.year, date.month, lastDay - j).isPresent; 651 | } 652 | 653 | isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, date.year, date.month, lastDay - j).isPresent; 654 | isSelected = scope.selectedDates.findDate(date.year, date.month, lastDay - j).isPresent && !isDisabled; 655 | 656 | iDate = new Date(date.year, date.month, lastDay - j); 657 | 658 | scope.dayList.unshift({ 659 | year: date.year, 660 | month: date.month, 661 | date: lastDay - j, 662 | day: iDate.getDay(), 663 | style: { 664 | isSelected: isSelected, 665 | isToday: isToday, 666 | isDisabled: isDisabled, 667 | isCalendar0: isCalendar[0], 668 | isCalendar1: isCalendar[1], 669 | isCalendar2: isCalendar[2], 670 | isCalendar3: isCalendar[3], 671 | isCalendar4: isCalendar[4], 672 | isCalendar5: isCalendar[5], 673 | isCalendar6: isCalendar[6], 674 | isCalendar7: isCalendar[7], 675 | isViewMonth: isViewMonth 676 | } 677 | }); 678 | } 679 | 680 | scope.rows = [0, 7, 14, 21, 28]; 681 | if (scope.dayList.length / 7 > 5) { 682 | scope.rows.push(35); // = [0, 7, 14, 21, 28, 35]; 683 | } 684 | 685 | var daysLeft = 7 - scope.dayList.length % 7; 686 | // start of next month 687 | date = monthShift(scope.viewYear, scope.viewMonth, '+'); 688 | for (i = 1; i <= daysLeft; i++) { 689 | for (c = 0; c < 8; c++) { 690 | isCalendar[c] = scope.selectedDates.findDate.call(scope.calendar[c].dates, date.year, date.month, i).isPresent; 691 | } 692 | 693 | isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, date.year, date.month, i).isPresent; 694 | isSelected = scope.selectedDates.findDate(date.year, date.month, i).isPresent && !isDisabled; 695 | iDate = new Date(date.year, date.month, i); 696 | 697 | scope.dayList.push({ 698 | year: date.year, 699 | month: date.month, 700 | date: i, 701 | day: iDate.getDay(), 702 | style: { 703 | isSelected: isSelected, 704 | isToday: isToday, 705 | isDisabled: isDisabled, 706 | isCalendar0: isCalendar[0], 707 | isCalendar1: isCalendar[1], 708 | isCalendar2: isCalendar[2], 709 | isCalendar3: isCalendar[3], 710 | isCalendar4: isCalendar[4], 711 | isCalendar5: isCalendar[5], 712 | isCalendar6: isCalendar[6], 713 | isCalendar7: isCalendar[7], 714 | isViewMonth: isViewMonth 715 | } 716 | }); 717 | } 718 | 719 | scope.cols = [0, 1, 2, 3, 4, 5, 6]; 720 | 721 | } 722 | 723 | scope.prevMonth = function () { 724 | var date = monthShift(scope.viewYear, scope.viewMonth, '-'); 725 | if (scope.fromYearMonth === undefined || date.year * 100 + date.month >= scope.fromYearMonth) { 726 | scope.viewYear = date.year; 727 | scope.viewMonth = date.month; 728 | 729 | refreshDateList(); 730 | } 731 | }; 732 | 733 | scope.nextMonth = function () { 734 | var date = monthShift(scope.viewYear, scope.viewMonth, '+'); 735 | if (scope.toYearMonth === undefined || date.year * 100 + date.month <= scope.toYearMonth) { 736 | scope.viewYear = date.year; 737 | scope.viewMonth = date.month; 738 | refreshDateList(); 739 | } 740 | }; 741 | 742 | scope.monthYearSelect = function () { 743 | var year = scope.monthYear.select.getFullYear(); 744 | var month = scope.monthYear.select.getMonth(); 745 | if ((scope.toYearMonth === undefined || year * 100 + month <= scope.toYearMonth) && (scope.fromYearMonth === undefined || year * 100 + month >= scope.fromYearMonth)) { 746 | 747 | scope.viewYear = year; 748 | scope.viewMonth = month; 749 | 750 | refreshDateList(); 751 | } else { 752 | 753 | } 754 | }; 755 | 756 | // date-cell ng-click: 757 | scope.onTap = function (date, row) { 758 | if (scope.accessType == ACCESS_TYPE.WRITE) { 759 | if (!scope.selectByWeek.is) { 760 | selectDay(date) 761 | } else { 762 | if (scope.selectByWeekMode === SELECT_BY_WEEK_MODE.NORMAL) { 763 | var state = !scope.selectedDates.findDate(date.year, date.month, date.date).isPresent; 764 | } 765 | for (var i = 0; i < 7; i++) { 766 | var d = scope.dayList[row + i]; 767 | selectDay(d, state); 768 | } 769 | } 770 | 771 | if (scope.closeOnSelect) { 772 | btnOk(); 773 | if (scope.templateType === TEMPLATE_TYPE.POPUP) { 774 | $timeout(scope.popup.close, 300); 775 | } else { 776 | $timeout(scope.closeModal, 300); 777 | } 778 | } 779 | } 780 | }; 781 | 782 | scope.onHold = function (date) { 783 | scope.holded = { 784 | is: true, 785 | isSelected: date.style.isSelected, 786 | isDisabled: date.style.isDisabled, 787 | isToday: date.style.isToday, 788 | isCalendar0: date.style.isCalendar0, 789 | isCalendar1: date.style.isCalendar1, 790 | isCalendar2: date.style.isCalendar2, 791 | isCalendar3: date.style.isCalendar3, 792 | isCalendar4: date.style.isCalendar4, 793 | isCalendar5: date.style.isCalendar5, 794 | isCalendar6: date.style.isCalendar6, 795 | isCalendar7: date.style.isCalendar7, 796 | date: date.date 797 | }; 798 | }; 799 | 800 | scope.onRelease = function (date) { 801 | scope.holded = { 802 | is: false, 803 | date: 'date' 804 | }; 805 | }; 806 | 807 | function selectDay(date, state) { 808 | var isDisabled = scope.selectedDates.findDate.call(scope.disabledDates, date.year, date.month, date.date).isPresent; 809 | if (!isDisabled) { 810 | scope.selectedDates.addRemove(date.year, date.month, date.date, state); 811 | scope.dayList.repaint(); 812 | scope.selectedDates.checkPeriod(); 813 | 814 | } 815 | } 816 | 817 | function monthShift(year, month, direction) { 818 | switch (direction) { 819 | case '+': 820 | if (month === 11) { 821 | year++; 822 | month = 0; 823 | } else { 824 | month++; 825 | } 826 | break; 827 | 828 | case '-': 829 | if (month === 0) { 830 | year--; 831 | month = 11; 832 | } else { 833 | month--; 834 | } 835 | break; 836 | } 837 | 838 | return {year: year, month: month}; 839 | } 840 | 841 | function btnOk() { 842 | scope.inputObj.callback(scope.selectedDates); 843 | } 844 | 845 | function btnCancel() { 846 | scope.inputObj.callback(scope.inputDates); 847 | } 848 | 849 | function btnClear() { 850 | scope.selectedDates.clear(); 851 | scope.dayList.repaint(); 852 | scope.selectedDates.checkPeriod(); 853 | } 854 | 855 | function btnToday() { 856 | var d = new Date(); 857 | 858 | scope.viewYear = d.getFullYear(); 859 | scope.viewMonth = d.getMonth(); 860 | 861 | refreshDateList(); 862 | } 863 | 864 | function initModal() { 865 | // reference for the 'ionic-multi-date-picker' modal. 866 | $ionicModal.fromTemplateUrl('ionic-multi-date-picker-modal.html', { 867 | scope: scope, 868 | animation: 'slide-in-up' 869 | }).then(function (modal) { 870 | scope.modal = modal; 871 | }); 872 | scope.openModal = function () { 873 | scope.modal.show(); 874 | }; 875 | scope.closeModal = function () { 876 | scope.modal.hide(); 877 | }; 878 | } 879 | 880 | //Called when the user clicks on the button to invoke the 'ionic-multi-date-picker' 881 | element.on("click", function () { 882 | //This code is added to set passed date from datepickerObject 883 | start(); 884 | 885 | if (scope.templateType === TEMPLATE_TYPE.MODAL) { 886 | scope.openModal(); 887 | } else { 888 | //Getting the reference for the 'ionic-multi-date-picker' popup. 889 | var buttons = scope.btns; 890 | if (!scope.btnsIsNative) { 891 | buttons = []; 892 | } 893 | scope.popup = $ionicPopup.show({ 894 | templateUrl: 'ionic-multi-date-picker-popup.html', 895 | cssClass: 'picker-body', 896 | scope: scope, 897 | buttons: buttons 898 | }); 899 | } 900 | }); 901 | } 902 | }; 903 | } 904 | 905 | })(); -------------------------------------------------------------------------------- /src/ionic-multi-date-picker.scss: -------------------------------------------------------------------------------- 1 | $MDP-RED: rgb(246, 109, 103); 2 | $MDP-YELLOW: rgb(246, 232, 0); 3 | $MDP-ORANGE: rgb(246, 130, 0); 4 | $MDP-VIOLET: rgb(246, 0, 199); 5 | $MDP-SAHA: rgb(159, 0, 246); 6 | $MDP-CORAL: rgb(255, 133, 121); 7 | $MDP-BLUE: rgb(58, 129, 197); 8 | $MDP-SKYEY: rgb(83, 167, 255); 9 | $MDP-GREEN: rgb(155, 214, 89); 10 | $MDP-GGREEN: rgb(0, 214, 108); 11 | $MDP-WHITE: rgb(255, 255, 255); 12 | $MDP-GRAY: rgb(204, 204, 204); 13 | $MDP-BLACK: rgb(0, 0, 0); 14 | $MDP-HOLIDAY: rgb(255, 0, 0); 15 | $MDP-DISABLED: rgb(134, 134, 134); 16 | $MDP-DISABLED-BG: rgb(231, 231, 231); 17 | $CIRCLE-D: 25px; 18 | //COLORS CLASSES: 19 | .cal-color-red { 20 | &:before { 21 | background-color: $MDP-RED; 22 | } 23 | } 24 | 25 | .cal-color-yellow { 26 | &:before { 27 | background-color: $MDP-YELLOW; 28 | } 29 | } 30 | 31 | .cal-color-orange, .cal-color-4 { 32 | &:before { 33 | background-color: $MDP-ORANGE; 34 | } 35 | } 36 | 37 | .cal-color-violet, .cal-color-2 { 38 | &:before { 39 | background-color: $MDP-VIOLET; 40 | } 41 | } 42 | 43 | .cal-color-saha, .cal-color-6 { 44 | &:before { 45 | background-color: $MDP-SAHA; 46 | } 47 | } 48 | 49 | .cal-color-coral { 50 | &:before { 51 | background-color: $MDP-CORAL; 52 | } 53 | } 54 | 55 | .cal-color-blue, .cal-color-3 { 56 | &:before { 57 | background-color: $MDP-BLUE; 58 | } 59 | } 60 | 61 | .cal-color-skyey, .cal-color-7 { 62 | &:before { 63 | background-color: $MDP-SKYEY; 64 | } 65 | } 66 | 67 | .cal-color-green { 68 | &:before { 69 | background-color: $MDP-GREEN; 70 | } 71 | } 72 | 73 | .cal-color-ggreen, .cal-color-5 { 74 | &:before { 75 | background-color: $MDP-GGREEN; 76 | } 77 | } 78 | 79 | .cal-color-holiday, .cal-color-0 { 80 | &:before { 81 | background-color: $MDP-HOLIDAY; 82 | } 83 | } 84 | 85 | .cal-color-black, .cal-color-1 { 86 | &:before { 87 | background-color: $MDP-BLACK; 88 | } 89 | } 90 | 91 | .picker-body { 92 | 93 | height: inherit; 94 | 95 | .popup-head { 96 | // NB! header of ionic popup 97 | padding: 0; 98 | border: 0; 99 | } 100 | 101 | .popup-body { 102 | overflow: inherit !important; 103 | padding: 0; 104 | } 105 | } 106 | 107 | .cal-green { 108 | color: $MDP-GREEN !important; 109 | } 110 | 111 | .cal-green-bg { 112 | background-color: $MDP-GREEN; 113 | z-index: -2; 114 | } 115 | 116 | .ionic-datepicker { 117 | background-color: $MDP-WHITE; 118 | .no-padding { 119 | padding: 0; 120 | } 121 | 122 | .clear { 123 | clear: both; 124 | } 125 | 126 | .title { 127 | 128 | color: $MDP-BLUE; 129 | 130 | h3 { 131 | font-size: 2em; 132 | text-align: center !important; 133 | margin: 0; 134 | padding: 10px; 135 | width: 100%; 136 | } 137 | 138 | div { 139 | font-size: 21px; 140 | text-align: center !important; 141 | margin: 0; 142 | padding: 5px; 143 | width: 100%; 144 | } 145 | } 146 | 147 | .navigator { 148 | background-color: $MDP-BLUE; 149 | min-height: 50px; 150 | } 151 | 152 | .icon-chevron { 153 | position: relative; 154 | } 155 | .icon-chevron:before { 156 | background-color: $MDP-WHITE; 157 | width: 24px; 158 | height: 24px; 159 | border-radius: 50%; 160 | padding: 5px 3px; 161 | position: absolute; 162 | top: -7px; 163 | z-index: 1; 164 | } 165 | 166 | .icon-chevron-left:before { 167 | left: 2px; 168 | } 169 | 170 | .icon-chevron-right:before { 171 | left: -25px; 172 | } 173 | 174 | .month-year-selector { 175 | position: fixed; 176 | right: 60px; 177 | top: 0; 178 | left: 60px; 179 | //max-width: 100px; 180 | background-color: transparent; 181 | color: transparent; 182 | border-width: 0; 183 | max-width: 40%; 184 | input { 185 | color: transparent; 186 | } 187 | } 188 | 189 | /* calendar */ 190 | .calendar-grid { 191 | margin: 0 auto 0; 192 | max-width: 260px; 193 | } 194 | .week-days { 195 | text-transform: uppercase; 196 | text-align: center; 197 | } 198 | 199 | .weekend { 200 | color: $MDP-RED; 201 | } 202 | 203 | .calendar-0, .calendar-1, .calendar-2, .calendar-3, .calendar-4, 204 | .calendar-5, .calendar-6, .calendar-7 { 205 | position: absolute; 206 | top: 0; 207 | left: 0; 208 | color: transparent; 209 | &:before { 210 | position: absolute; 211 | content: ''; 212 | z-index: 0; 213 | width: 8px; 214 | height: 8px; 215 | border: 2px solid $MDP-WHITE; 216 | border-radius: 50%; 217 | } 218 | } 219 | 220 | .calendar-0 { 221 | &:before { 222 | top: 3px; 223 | left: 5px; 224 | } 225 | } 226 | 227 | .calendar-1 { 228 | &:before { 229 | top: -1px; 230 | left: 14px; 231 | } 232 | } 233 | 234 | .calendar-2 { 235 | &:before { 236 | top: 3px; 237 | left: 23px; 238 | } 239 | } 240 | 241 | .calendar-3 { 242 | &:before { 243 | top: 12px; 244 | left: 27px; 245 | } 246 | } 247 | 248 | .calendar-4 { 249 | &:before { 250 | top: 22px; 251 | left: 24px; 252 | } 253 | } 254 | 255 | .calendar-5 { 256 | &:before { 257 | top: 25px; 258 | left: 14px; 259 | } 260 | } 261 | 262 | .calendar-6 { 263 | &:before { 264 | top: 22px; 265 | left: 5px; 266 | } 267 | } 268 | 269 | .calendar-7 { 270 | &:before { 271 | top: 12px; 272 | left: 1px; 273 | } 274 | } 275 | 276 | .disabledDate { 277 | color: $MDP-DISABLED !important; 278 | &:after { 279 | position: absolute; 280 | content: ''; 281 | top: 4px; 282 | left: 5px; 283 | z-index: -1; 284 | width: $CIRCLE-D; 285 | height: $CIRCLE-D; 286 | border-radius: 50%; 287 | background-color: $MDP-DISABLED-BG; 288 | } 289 | } 290 | 291 | .not-cur-month { 292 | color: $MDP-GRAY; 293 | } 294 | 295 | .today { 296 | font-weight: bolder; 297 | &:after { 298 | content: ''; 299 | position: absolute; 300 | top: 4px; 301 | left: 5px; 302 | z-index: -1; 303 | width: $CIRCLE-D; 304 | height: $CIRCLE-D; 305 | border-radius: 50%; 306 | border: 2px solid $MDP-SKYEY; 307 | } 308 | } 309 | 310 | .not-empty:after { 311 | content: ''; 312 | position: absolute; 313 | top: 4px; 314 | left: 5px; 315 | z-index: -1; 316 | width: $CIRCLE-D; 317 | height: $CIRCLE-D; 318 | border-radius: 50%; 319 | border: 1px solid $MDP-GRAY; 320 | } 321 | 322 | .selected, .selected-light { 323 | color: $MDP-WHITE !important; 324 | &:after { 325 | content: ''; 326 | position: absolute; 327 | top: 4px; 328 | left: 5px; 329 | z-index: -1; 330 | width: $CIRCLE-D; 331 | height: $CIRCLE-D; 332 | background-color: $MDP-RED; 333 | border-radius: 50%; 334 | } 335 | } 336 | .selected { 337 | &:after { 338 | background-color: $MDP-RED; 339 | } 340 | } 341 | .selected-light { 342 | &:after { 343 | background-color: $MDP-CORAL; 344 | } 345 | } 346 | 347 | .date-grid { 348 | height: 200px; 349 | .date-row { 350 | text-align: center; 351 | .date-col { 352 | position: relative; 353 | z-index: 1; 354 | width: 44px; 355 | &:hover { 356 | cursor: pointer; 357 | } 358 | &:active { 359 | cursor: pointer; 360 | } 361 | .date-cell { 362 | padding: 5px; 363 | margin: 1px; 364 | } 365 | } 366 | } 367 | } 368 | 369 | /* calendars names */ 370 | .calendar-names { 371 | position: relative; 372 | max-width: 260px; 373 | height: 87px; 374 | margin: 0 auto; 375 | 376 | .calendars-point { 377 | width: 29px; 378 | text-align: center; 379 | position: absolute; 380 | left: 110px; 381 | top: 31px; 382 | z-index: 1; 383 | &:before { 384 | position: absolute; 385 | content: ''; 386 | left: -10px; 387 | top: -12px; 388 | width: 47px; 389 | height: 47px; 390 | border-radius: 50%; 391 | z-index: -1; 392 | } 393 | } 394 | .calendars-point-today:before { 395 | border: 2px solid $MDP-SKYEY; 396 | } 397 | .calendars-point-selected { 398 | color: $MDP-WHITE; 399 | &:before { 400 | background-color: $MDP-CORAL; 401 | } 402 | } 403 | .calendars-point-disabled { 404 | color: $MDP-DISABLED; 405 | &:before { 406 | background-color: $MDP-DISABLED-BG; 407 | } 408 | } 409 | .calendars-point-contour:before { 410 | border: 1px solid $MDP-GRAY; 411 | } 412 | 413 | .calendar-0-name, .calendar-1-name, .calendar-2-name, .calendar-3-name, 414 | .calendar-4-name, .calendar-5-name, .calendar-6-name, .calendar-7-name { 415 | position: absolute; 416 | width: 40%; 417 | text-align: center; 418 | } 419 | 420 | .calendar-0-name { 421 | top: 16px; 422 | left: 5px; 423 | } 424 | .calendar-1-name { 425 | top: 0; 426 | left: 74px; 427 | } 428 | .calendar-2-name { 429 | top: 16px; 430 | left: 144px; 431 | } 432 | .calendar-3-name { 433 | top: 32px; 434 | left: 149px; 435 | } 436 | .calendar-4-name { 437 | top: 48px; 438 | left: 144px; 439 | } 440 | .calendar-5-name { 441 | top: 64px; 442 | left: 74px; 443 | } 444 | .calendar-6-name { 445 | top: 48px; 446 | left: 5px; 447 | } 448 | .calendar-7-name { 449 | top: 32px; 450 | left: 0; 451 | } 452 | 453 | .calendar-0-point, .calendar-1-point, .calendar-2-point, .calendar-3-point, 454 | .calendar-4-point, .calendar-5-point, .calendar-6-point, .calendar-7-point { 455 | position: absolute; 456 | color: transparent; 457 | &:before { 458 | position: absolute; 459 | content: ''; 460 | width: 12px; 461 | height: 12px; 462 | border: 3px solid $MDP-WHITE; 463 | border-radius: 50%; 464 | z-index: 2; 465 | } 466 | } 467 | 468 | .calendar-0-point { 469 | top: 20px; 470 | left: 100px; 471 | } 472 | .calendar-1-point { 473 | top: 14px; 474 | left: 118px; 475 | } 476 | .calendar-2-point:before { 477 | top: 20px; 478 | left: 136px; 479 | } 480 | .calendar-3-point:before { 481 | top: 37px; 482 | left: 143px; 483 | } 484 | .calendar-4-point:before { 485 | top: 53px; 486 | left: 136px; 487 | } 488 | .calendar-5-point:before { 489 | top: 59px; 490 | left: 119px; 491 | } 492 | .calendar-6-point:before { 493 | top: 53px; 494 | left: 100px; 495 | } 496 | .calendar-7-point:before { 497 | top: 37px; 498 | left: 93px; 499 | } 500 | } 501 | 502 | /* errors */ 503 | .errors { 504 | max-width: 260px; 505 | padding: 10px; 506 | margin: 0 auto; 507 | color: $MDP-RED; 508 | } 509 | 510 | .tgl-period div { 511 | margin: 0; 512 | } 513 | 514 | .view-month { 515 | color: $MDP-WHITE; 516 | padding: 14px; 517 | } 518 | 519 | .pointer_events_none { 520 | pointer-events: none !important; 521 | } 522 | 523 | .select_section { 524 | padding: 0; 525 | 526 | label { 527 | padding: 12px; 528 | } 529 | 530 | select { 531 | font-size: 12px; 532 | font-weight: bold; 533 | padding: 2px 10px; 534 | direction: ltr; 535 | left: 0; 536 | width: 100%; 537 | max-width: 100%; 538 | } 539 | 540 | .item-select:after { 541 | right: 4px; 542 | border-top: 4px solid; 543 | border-right: 4px solid $MDP-BLACK; 544 | border-left: 4px solid $MDP-BLACK; 545 | } 546 | } 547 | 548 | .left-arrow { 549 | direction: rtl; 550 | } 551 | 552 | .font_22px { 553 | font-size: 22px; 554 | } 555 | 556 | .btns-right-popup { 557 | float: right; 558 | } 559 | 560 | .btns-right-modal { 561 | direction: rtl; 562 | } 563 | } 564 | 565 | .ionic_datepicker_modal_content { 566 | padding-top: 10%; 567 | 568 | .ionic-datepicker { 569 | .selected_date_full { 570 | font-size: 20px; 571 | padding: 20px; 572 | } 573 | } 574 | .cal-button { 575 | padding: 0 !important; 576 | font-size: 14px !important; 577 | } 578 | } 579 | 580 | @media (min-width: 680px) { 581 | .ionic_datepicker_modal_content { 582 | padding-top: 0; 583 | } 584 | 585 | .ionic_datepicker_modal_content .ionic-datepicker .selected_date_full { 586 | font-size: inherit; 587 | } 588 | 589 | .ionic_datepicker_modal_content .ionic-datepicker .selected_date_full { 590 | padding: 10px 0 0 0; 591 | } 592 | } 593 | 594 | /* 595 | .ionic_datepicker_popup_btn_cancel { 596 | position: fixed; 597 | top: 10px; 598 | right: 10px; 599 | padding-top: 3px; 600 | padding-left: 8px; 601 | font-size: 17px; 602 | width: 30px; 603 | height: 30px; 604 | border: 2px solid rgba(235, 71, 60, 0.95); 605 | color: white; 606 | border-radius: 15px; 607 | background-color: rgba(235, 71, 60, 0.95); 608 | }*/ -------------------------------------------------------------------------------- /src/ionic-multi-date-picker.service.js: -------------------------------------------------------------------------------- 1 | //By Rajeshwar Patlolla - rajeshwar.patlolla@gmail.com 2 | //https://github.com/rajeshwarpatlolla 3 | 4 | // forked and edited by Denni Adam - dennila2@gmail.com 5 | // https://github.com/dennila2 6 | (function(){ 7 | 'use strict'; 8 | 9 | angular.module('ionic-multi-date-picker') 10 | .service('IonicMultiDatePickerService', IonicMultiDatePickerService); 11 | 12 | IonicMultiDatePickerService.$inject = []; 13 | function IonicMultiDatePickerService(){ 14 | this.monthsList = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; 15 | 16 | } 17 | 18 | })(); -------------------------------------------------------------------------------- /src/template-body.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 |
22 |
23 |
27 |
28 |
29 |
30 |
32 |
43 |
47 | {{ dayList[row + col].date }} 48 |
49 | 50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 | 67 |
68 |
69 |
70 |
71 | 72 |
73 |
{{ holded.date }}
76 |
. 79 |
80 |
. 83 |
84 |
. 87 |
88 |
. 91 |
92 |
. 95 |
96 |
. 99 |
100 |
. 103 |
104 |
. 107 |
108 |
110 | {{ calendar[0].name.title }} 111 |
112 |
114 | {{ calendar[1].name.title }} 115 |
116 |
118 | {{ calendar[2].name.title }} 119 |
120 |
122 | {{ calendar[3].name.title }} 123 |
124 |
126 | {{ calendar[4].name.title }} 127 |
128 |
130 | {{ calendar[5].name.title }} 131 |
132 |
134 | {{ calendar[6].name.title }} 135 |
136 |
138 | {{ calendar[7].name.title }} 139 |
140 |
141 | 142 |
143 |
144 | {{ error[errorLanguage] }} 145 |
146 |
147 | 148 |
149 |
150 | {{ tglSelectByWeek }} 151 | 158 |
159 |
--------------------------------------------------------------------------------