├── .gitignore
├── .idea
├── inspectionProfiles
│ └── Project_Default.xml
├── ionic3-datepicker.iml
├── jsLinters
│ └── tslint.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── .npmignore
├── LICENSE
├── README.md
├── demo
├── .editorconfig
├── .gitignore
├── config.xml
├── ionic.config.json
├── package.json
├── server.js
├── src
│ ├── app
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── app.scss
│ │ └── main.ts
│ ├── assets
│ │ └── icon
│ │ │ └── favicon.ico
│ ├── declarations.d.ts
│ ├── index.html
│ ├── manifest.json
│ ├── pages
│ │ └── home
│ │ │ ├── home.html
│ │ │ ├── home.scss
│ │ │ └── home.ts
│ ├── service-worker.js
│ └── theme
│ │ └── variables.scss
├── tsconfig.json
└── tslint.json
├── index.ts
├── package.json
├── scripts
└── copy-package.js
├── src
├── components
│ ├── datepicker.component.html
│ ├── datepicker.component.scss
│ ├── datepicker.component.ts
│ ├── datepicker.directive.ts
│ ├── datepicker.interface.ts
│ ├── datepicker.modal.ts
│ ├── datepicker.module.ts
│ ├── datepicker.service.ts
│ └── nls.ts
└── index.ts
├── tsconfig.json
└── tslint.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | aot/
4 | debug.log
5 | npm-debug.log
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/ionic3-datepicker.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/jsLinters/tslint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 | years
293 | month
294 | months
295 | config
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 | true
330 | DEFINITION_ORDER
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 | JSP Inspections
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 | $USER_HOME$/.subversion
574 |
575 |
576 |
577 |
578 | 1504243045560
579 |
580 |
581 | 1504243045560
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 | 1.7
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | spec
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 celsomarques
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## How to use ###
4 |
5 | ### 1) Install using npm ###
6 |
7 | ```
8 | npm i ionic3-datepicker --save
9 | ```
10 |
11 | ### 2) Add it to your ngModule in app.module ###
12 |
13 | ```
14 | import { DatePickerModule } from 'ionic3-datepicker';
15 | ```
16 | ```
17 | imports: [
18 | IonicModule.forRoot(App),
19 | DatePickerModule,
20 | ],
21 | ```
22 | ### 3) Use the directive ion-datepicker in your html ###
23 | ```
24 |
25 | {{localDate | date}}
26 |
27 | ```
28 |
29 | ### Dismiss the datepicker from the class ###
30 |
31 | ```
32 |
33 | import { DatePickerDirective } from 'ionic3-datepicker';
34 |
35 | @ViewChild(DatePickerDirective) private datepickerDirective:DatePickerDirective;
36 |
37 | public closeDatepicker(){
38 | this.datepickerDirective.dismiss();
39 | }
40 |
41 | ```
42 |
43 | ## Please note en-US locale starts the calendar with monday and en-UK starts it with sunday ###
44 |
45 |
46 | `[value]` - defines the initial value
47 |
48 | `[min]` - minimum date that user is allowed to select. (not required)
49 |
50 | `[max]` - maximum date that user is allowed to select. (not required)
51 |
52 | `[disabledDates]` - An array of dates that should be disabled (not required)
53 |
54 | `[markDates]` - An array of dates that should be mark (background-color) (not required)
55 |
56 | `(ionChanged)` - an event emitter that returns the date as a $event.
57 |
58 | `(ionCanceled)` - an event that is raised when the cancel button is activated. Returns no data.
59 |
60 | `[headerClasses]` - a bridge to the header classes of the directive using ngClass (string, array or object) (not required)
61 |
62 | `[bodyClasses]` - a bridge to the date classes of the directive using ngClass (string, array or object) (not required)
63 |
64 | `[modalOptions]` - a modal is used to display the picker to configure the animation or other options you may use this
65 |
66 | `[locale]` - for translating the calendar. Avaliable local is en-US, en-UK, he-IL, pt-BR, ru-RU, de, fi, zh-TW, zh-CN
67 |
68 | `[localeStrings]` - if you dont want to use the built translations - accepts an object { weekdays: string[], months: string[], monday:boolean },
69 | For example:
70 | ```
71 | {
72 | monday:true,
73 | weekdays: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
74 | months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
75 | },
76 | ```
77 |
78 | `[okText]` - text for the ok button
79 |
80 | `[cancelText]` - text for the cancel button
81 |
82 |
83 | ### 4) Pictures ###
84 |
85 |
--------------------------------------------------------------------------------
/demo/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
2 | # editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 2
9 |
10 | # We recommend you to keep these unchanged
11 | end_of_line = lf
12 | charset = utf-8
13 | trim_trailing_whitespace = true
14 | insert_final_newline = true
15 |
16 | [*.md]
17 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies intentionally untracked files to ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | *~
5 | *.sw[mnpcod]
6 | *.log
7 | *.tmp
8 | *.tmp.*
9 | log.txt
10 | *.sublime-project
11 | *.sublime-workspace
12 | .vscode/
13 | npm-debug.log*
14 |
15 | .idea/
16 | .sass-cache/
17 | .tmp/
18 | .versions/
19 | coverage/
20 | dist/
21 | node_modules/
22 | tmp/
23 | temp/
24 | hooks/
25 | platforms/
26 | plugins/
27 | plugins/android.json
28 | plugins/ios.json
29 | www/
30 | $RECYCLE.BIN/
31 |
32 | .DS_Store
33 | Thumbs.db
34 | UserInterfaceState.xcuserstate
35 |
--------------------------------------------------------------------------------
/demo/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | demo-datepicker-ionic2
4 | An awesome Ionic/Cordova app.
5 | Ionic Framework Team
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/demo/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-datepicker-ionic2",
3 | "app_id": "",
4 | "integrations": {},
5 | "type": "ionic-angular"
6 | }
7 |
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic-hello-world",
3 | "author": "Ionic Framework",
4 | "homepage": "http://ionicframework.com/",
5 | "private": true,
6 | "scripts": {
7 | "ionic:build": "ionic-app-scripts build",
8 | "ionic:serve": "ionic-app-scripts serve"
9 | },
10 | "dependencies": {
11 | "@angular/common": "4.1.3",
12 | "@angular/compiler": "4.1.3",
13 | "@angular/compiler-cli": "4.1.3",
14 | "@angular/core": "4.1.3",
15 | "@angular/forms": "4.1.3",
16 | "@angular/http": "4.1.3",
17 | "@angular/platform-browser": "4.1.3",
18 | "@angular/platform-browser-dynamic": "4.1.3",
19 | "datepicker-ionic2": "^2.4.3",
20 | "ionic-angular": "3.5.0",
21 | "ionicons": "3.0.0",
22 | "rxjs": "5.4.0",
23 | "sw-toolbox": "3.6.0",
24 | "zone.js": "0.8.12"
25 | },
26 | "devDependencies": {
27 | "@ionic/app-scripts": "1.3.12",
28 | "typescript": "~2.3.4"
29 | },
30 | "description": "demo-datepicker-ionic2: An Ionic project"
31 | }
--------------------------------------------------------------------------------
/demo/server.js:
--------------------------------------------------------------------------------
1 | var connect = require('connect'),
2 | serveStatic = require('serve-static');
3 |
4 | var app = connect();
5 |
6 | app.use(serveStatic("www"));
7 | app.listen(process.env.PORT || 5000);
--------------------------------------------------------------------------------
/demo/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { HomePage } from '../pages/home/home';
3 | import { Platform } from 'ionic-angular';
4 |
5 | @Component({
6 | template: ``
7 | })
8 | export class MyApp {
9 | rootPage = HomePage;
10 |
11 | constructor(platform: Platform) {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/demo/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { ErrorHandler, NgModule } from '@angular/core';
2 | import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
3 |
4 | import { BrowserModule } from '@angular/platform-browser';
5 | import { DatePickerModule } from '../../../dist';
6 | import { HomePage } from '../pages/home/home';
7 | import { MyApp } from './app.component';
8 |
9 | @NgModule({
10 | declarations: [
11 | MyApp,
12 | HomePage,
13 | ],
14 | imports: [
15 | IonicModule.forRoot(MyApp),
16 | DatePickerModule,
17 | BrowserModule,
18 | ],
19 | bootstrap: [IonicApp],
20 | entryComponents: [
21 | MyApp,
22 | HomePage,
23 | ],
24 | providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler }]
25 | })
26 | export class AppModule { }
27 |
--------------------------------------------------------------------------------
/demo/src/app/app.scss:
--------------------------------------------------------------------------------
1 | // http://ionicframework.com/docs/v2/theming/
2 |
3 |
4 | // App Global Sass
5 | // --------------------------------------------------
6 | // Put style rules here that you want to apply globally. These
7 | // styles are for the entire app and not just one component.
8 | // Additionally, this file can be also used as an entry point
9 | // to import other Sass files to be included in the output CSS.
10 | //
11 | // Shared Sass variables, which can be used to adjust Ionic's
12 | // default Sass variables, belong in "theme/variables.scss".
13 | //
14 | // To declare rules for a specific mode, create a child rule
15 | // for the .md, .ios, or .wp mode classes. The mode class is
16 | // automatically applied to the
element in the app.
17 |
--------------------------------------------------------------------------------
/demo/src/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/demo/src/assets/icon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/celsomarques/ionic-datepicker/385934c6d94e089613c99439afe287bfd214f470/demo/src/assets/icon/favicon.ico
--------------------------------------------------------------------------------
/demo/src/declarations.d.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Declaration files are how the Typescript compiler knows about the type information(or shape) of an object.
3 | They're what make intellisense work and make Typescript know all about your code.
4 |
5 | A wildcard module is declared below to allow third party libraries to be used in an app even if they don't
6 | provide their own type declarations.
7 |
8 | To learn more about using third party libraries in an Ionic app, check out the docs here:
9 | http://ionicframework.com/docs/v2/resources/third-party-libs/
10 |
11 | For more info on type definition files, check out the Typescript docs here:
12 | https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html
13 | */
14 | declare module '*';
--------------------------------------------------------------------------------
/demo/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ionic App
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/demo/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ionic",
3 | "short_name": "Ionic",
4 | "start_url": "index.html",
5 | "display": "standalone",
6 | "icons": [{
7 | "src": "assets/imgs/logo.png",
8 | "sizes": "512x512",
9 | "type": "image/png"
10 | }],
11 | "background_color": "#4e8ef7",
12 | "theme_color": "#4e8ef7"
13 | }
--------------------------------------------------------------------------------
/demo/src/pages/home/home.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
13 | {{initDate | date}}
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/demo/src/pages/home/home.scss:
--------------------------------------------------------------------------------
1 | page-home {
2 |
3 | }
4 | *{
5 | box-sizing:border-box;
6 | }
7 |
--------------------------------------------------------------------------------
/demo/src/pages/home/home.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController } from 'ionic-angular';
3 |
4 | @Component({
5 | selector: 'page-home',
6 | templateUrl: 'home.html'
7 | })
8 | export class HomePage {
9 | public localDate: Date = new Date();
10 | public initDate: Date = new Date();
11 | public initDate2: Date = new Date(2015, 1, 1);
12 | public disabledDates: Date[] = [new Date(2017, 7, 14)];
13 |
14 | public maxDate: Date = new Date(new Date().setDate(new Date().getDate() + 30));
15 | public min: Date = new Date()
16 | constructor(public navCtrl: NavController) {
17 |
18 | }
19 | public Log(stuff): void {
20 | console.log(stuff);
21 | }
22 |
23 | public event(data: Date): void {
24 | this.localDate = data;
25 | }
26 | setDate(date: Date) {
27 | console.log(date);
28 | this.initDate = date;
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/demo/src/service-worker.js:
--------------------------------------------------------------------------------
1 | // tick this to make the cache invalidate and update
2 | const CACHE_VERSION = 1;
3 | const CURRENT_CACHES = {
4 | 'read-through': 'read-through-cache-v' + CACHE_VERSION
5 | };
6 |
7 | self.addEventListener('activate', (event) => {
8 | // Delete all caches that aren't named in CURRENT_CACHES.
9 | // While there is only one cache in this example, the same logic will handle the case where
10 | // there are multiple versioned caches.
11 | const expectedCacheNames = Object.keys(CURRENT_CACHES).map((key) => {
12 | return CURRENT_CACHES[key];
13 | });
14 |
15 | event.waitUntil(
16 | caches.keys().then((cacheNames) => {
17 | return Promise.all(
18 | cacheNames.map((cacheName) => {
19 | if (expectedCacheNames.indexOf(cacheName) === -1) {
20 | // If this cache name isn't present in the array of "expected" cache names, then delete it.
21 | console.log('Deleting out of date cache:', cacheName);
22 | return caches.delete(cacheName);
23 | }
24 | })
25 | );
26 | })
27 | );
28 | });
29 |
30 | // This sample illustrates an aggressive approach to caching, in which every valid response is
31 | // cached and every request is first checked against the cache.
32 | // This may not be an appropriate approach if your web application makes requests for
33 | // arbitrary URLs as part of its normal operation (e.g. a RSS client or a news aggregator),
34 | // as the cache could end up containing large responses that might not end up ever being accessed.
35 | // Other approaches, like selectively caching based on response headers or only caching
36 | // responses served from a specific domain, might be more appropriate for those use cases.
37 | self.addEventListener('fetch', (event) => {
38 |
39 | event.respondWith(
40 | caches.open(CURRENT_CACHES['read-through']).then((cache) => {
41 | return cache.match(event.request).then((response) => {
42 | if (response) {
43 | // If there is an entry in the cache for event.request, then response will be defined
44 | // and we can just return it.
45 |
46 | return response;
47 | }
48 |
49 | // Otherwise, if there is no entry in the cache for event.request, response will be
50 | // undefined, and we need to fetch() the resource.
51 | console.log(' No response for %s found in cache. ' +
52 | 'About to fetch from network...', event.request.url);
53 |
54 | // We call .clone() on the request since we might use it in the call to cache.put() later on.
55 | // Both fetch() and cache.put() "consume" the request, so we need to make a copy.
56 | // (see https://fetch.spec.whatwg.org/#dom-request-clone)
57 | return fetch(event.request.clone()).then((response) => {
58 |
59 | // Optional: add in extra conditions here, e.g. response.type == 'basic' to only cache
60 | // responses from the same domain. See https://fetch.spec.whatwg.org/#concept-response-type
61 | if (response.status < 400 && response.type === 'basic') {
62 | // We need to call .clone() on the response object to save a copy of it to the cache.
63 | // (https://fetch.spec.whatwg.org/#dom-request-clone)
64 | cache.put(event.request, response.clone());
65 | }
66 |
67 | // Return the original response object, which will be used to fulfill the resource request.
68 | return response;
69 | });
70 | }).catch((error) => {
71 | // This catch() will handle exceptions that arise from the match() or fetch() operations.
72 | // Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
73 | // It will return a normal response object that has the appropriate error code set.
74 | console.error(' Read-through caching failed:', error);
75 |
76 | throw error;
77 | });
78 | })
79 | );
80 | });
--------------------------------------------------------------------------------
/demo/src/theme/variables.scss:
--------------------------------------------------------------------------------
1 | // Ionic Variables and Theming. For more info, please see:
2 | // http://ionicframework.com/docs/v2/theming/
3 | @import "ionic.globals";
4 |
5 |
6 | // Shared Variables
7 | // --------------------------------------------------
8 | // To customize the look and feel of this app, you can override
9 | // the Sass variables found in Ionic's source scss files.
10 | // To view all the possible Ionic variables, see:
11 | // http://ionicframework.com/docs/v2/theming/overriding-ionic-variables/
12 |
13 | $text-color: #000;
14 | $background-color: #fff;
15 |
16 |
17 | // Named Color Variables
18 | // --------------------------------------------------
19 | // Named colors makes it easy to reuse colors on various components.
20 | // It's highly recommended to change the default colors
21 | // to match your app's branding. Ionic uses a Sass map of
22 | // colors so you can add, rename and remove colors as needed.
23 | // The "primary" color is the only required color in the map.
24 |
25 | $colors: (
26 | primary: #387ef5,
27 | secondary: #32db64,
28 | danger: #f53d3d,
29 | light: #f4f4f4,
30 | dark: #222
31 | );
32 |
33 |
34 | // App iOS Variables
35 | // --------------------------------------------------
36 | // iOS only Sass variables can go here
37 |
38 |
39 |
40 |
41 | // App Material Design Variables
42 | // --------------------------------------------------
43 | // Material Design only Sass variables can go here
44 |
45 |
46 |
47 |
48 | // App Windows Variables
49 | // --------------------------------------------------
50 | // Windows only Sass variables can go here
51 |
52 |
53 |
54 |
55 | // App Theme
56 | // --------------------------------------------------
57 | // Ionic apps can have different themes applied, which can
58 | // then be future customized. This import comes last
59 | // so that the above variables are used and Ionic's
60 | // default are overridden.
61 |
62 | @import "ionic.theme.default";
63 |
64 |
65 | // Ionicons
66 | // --------------------------------------------------
67 | // The premium icon font for Ionic. For more info, please see:
68 | // http://ionicframework.com/docs/v2/ionicons/
69 |
70 | $ionicons-font-path: "../assets/fonts";
71 | @import "ionicons";
72 |
--------------------------------------------------------------------------------
/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "lib": [
8 | "dom",
9 | "es2015"
10 | ],
11 | "module": "es2015",
12 | "moduleResolution": "node",
13 | "sourceMap": true,
14 | "target": "es5"
15 | },
16 | "include": [
17 | "src/**/*.ts"
18 | ],
19 | "exclude": [
20 | "node_modules"
21 | ],
22 | "compileOnSave": false,
23 | "atom": {
24 | "rewriteTsconfig": false
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/demo/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src/datepicker-ionic2';
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ionic3-datepicker",
3 | "version": "2.4.12",
4 | "description": "A date picker for ionic 3 and 2 framework",
5 | "main": "index.js",
6 | "author": "Paulo Eduardo ",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/pauloedsr/ionic3-datepicker"
10 | },
11 | "keywords": [
12 | "ionic3-datepicker",
13 | "ionic3",
14 | "ionic3 datepicker",
15 | "datepicker",
16 | "datepicker ionic3",
17 | "datepicker for ionic3",
18 | "datepicker for ionic3 framework"
19 | ],
20 | "scripts": {
21 | "ngc": "ngc",
22 | "build": "npm run ngc && node ./scripts/copy-package",
23 | "publishPackage": "npm run build && cd dist && npm publish",
24 | "dev": "tsc --watch"
25 | },
26 | "license": "MIT",
27 | "dependencies": {},
28 | "devDependencies": {
29 | "@angular/common": "4.1.3",
30 | "@angular/compiler": "4.1.3",
31 | "@angular/compiler-cli": "4.1.3",
32 | "@angular/core": "4.1.3",
33 | "@angular/forms": "4.1.3",
34 | "@angular/http": "4.1.3",
35 | "@angular/platform-browser": "4.1.3",
36 | "@angular/platform-browser-dynamic": "4.1.3",
37 | "ionic-angular": "3.5.0",
38 | "ionicons": "3.0.0",
39 | "rxjs": "5.4.0",
40 | "sw-toolbox": "3.6.0",
41 | "zone.js": "0.8.12",
42 | "typescript": "2.3.4"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/scripts/copy-package.js:
--------------------------------------------------------------------------------
1 |
2 | var fs = require('fs');
3 |
4 | var packageJson = require('../package.json');
5 | if (! packageJson) {
6 | throw new Error('Can\'t find package json');
7 | }
8 |
9 | delete packageJson.devDependencies;
10 |
11 | fs.writeFile('./dist/package.json', JSON.stringify(packageJson, null, 2));
--------------------------------------------------------------------------------
/src/components/datepicker.component.html:
--------------------------------------------------------------------------------
1 |
2 |
25 |
27 |
28 |
37 |
41 |
45 |
52 |
53 |
54 |
56 | {{limitTo(dayOfWeek,3)}}
57 |
58 |
59 |
60 |
62 |
71 | {{getDate(i, j) | date:'d'}}
72 |
73 |
74 |
75 |
76 |
86 |
--------------------------------------------------------------------------------
/src/components/datepicker.component.scss:
--------------------------------------------------------------------------------
1 | $headerHeight:35%;
2 | $bodyheight:1;
3 | $footerheight:60px;
4 | ionic2-datepicker{
5 | .datepicker-wrapper{
6 | height: 100%;
7 | background-color:white;
8 | display: flex;
9 | flex-direction: column;
10 | justify-content: space-between;
11 | .datepicker-header{
12 | color:white;
13 | background-color: #009688;
14 | display:flex;
15 | flex-flow: column;
16 | height:$headerHeight;
17 | .date-header{
18 | display:flex;
19 | flex-flow: column;
20 | text-align: center;
21 | .datepicker-day-of-month {
22 | font-size: 60px;
23 | font-weight: 700
24 | }
25 | .datepicker-year, .datepicker-month {
26 | font-size: 14px;
27 | margin-top: 10px;
28 | margin-bottom: 10px;
29 | }
30 | }
31 | .weekday-header{
32 | padding: 8px 10px;
33 | background-color: #008d7f;
34 | .weekday-title{
35 | font-weight: bold;
36 | text-align: center;
37 | }
38 | }
39 | }
40 | }
41 |
42 | .weekdays-row{
43 | text-align:center;
44 | }
45 |
46 | .datepicker-calendar{
47 | height:calc(100% - (#{$headerHeight} + #{$footerheight}));
48 | .datepicker-controls{
49 | align-items: center;
50 | justify-content: space-between;
51 | }
52 | .calendar-wrapper{
53 | height:calc(100% - #{$footerheight} - 40px);
54 | display: flex;
55 | flex-direction: column;
56 | justify-content: space-around;
57 | .datepicker-date-col:hover {
58 | background-color: rgba(56, 126, 245, .5);
59 | border-radius: 20px;
60 | }
61 |
62 | .datepicker-selected {
63 | background-color: rgba(182, 217, 214, 1);
64 | border-radius:20px;
65 | }
66 |
67 | .datepicker-mark {
68 | background-color: rgba(202, 157, 14, 1);
69 | border-radius:20px;
70 | }
71 |
72 | .datepicker-current {
73 | color: rgba(60, 170, 159, 1);
74 | border-radius:20px;
75 | }
76 |
77 | .datepicker-disabled {
78 | color: rgba(170, 170, 170, 1)
79 | }
80 |
81 | .datepicker-disabled:hover {
82 | background-color: transparent;
83 | cursor: default
84 | }
85 |
86 | .calendar-cell {
87 | flex-flow:row wrap;
88 | text-align: center;
89 |
90 | }
91 | }
92 | }
93 |
94 | .datepicker-footer{
95 | display:flex;
96 | justify-content: space-between;
97 | height:$footerheight;
98 | button{
99 | width:100%;
100 | }
101 | }
102 |
103 | }
--------------------------------------------------------------------------------
/src/components/datepicker.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, EventEmitter, ViewEncapsulation} from '@angular/core';
2 | import {NavParams, ViewController} from 'ionic-angular';
3 |
4 | import {DateService} from './datepicker.service';
5 | import {FormControl} from '@angular/forms';
6 |
7 | @Component({
8 | template: `
9 |
10 |
33 |
35 |
36 |
46 |
50 |
54 |
63 |
64 |
65 |
67 | {{limitTo(dayOfWeek, 3)}}
68 |
69 |
70 |
71 |
73 |
82 | {{getDate(i, j) | date:'d'}}
83 |
84 |
85 |
86 |
87 |
101 |
102 | `,
103 | styles: [`
104 | ionic2-datepicker .datepicker-wrapper {
105 | height: 100%;
106 | background-color: white;
107 | display: flex;
108 | flex-direction: column;
109 | justify-content: space-between;
110 | }
111 |
112 | ionic2-datepicker .datepicker-wrapper .datepicker-header {
113 | color: white;
114 | background-color: #009688;
115 | display: flex;
116 | flex-flow: column;
117 | height: 35%;
118 | }
119 |
120 | ionic2-datepicker .datepicker-wrapper .datepicker-header .date-header {
121 | display: flex;
122 | flex-flow: column;
123 | text-align: center;
124 | }
125 |
126 | ionic2-datepicker .datepicker-wrapper .datepicker-header .date-header .datepicker-day-of-month {
127 | font-size: 60px;
128 | font-weight: 700;
129 | }
130 |
131 | ionic2-datepicker .datepicker-wrapper .datepicker-header .date-header .datepicker-year, ionic2-datepicker .datepicker-wrapper .datepicker-header .date-header .datepicker-month {
132 | font-size: 14px;
133 | margin-top: 10px;
134 | margin-bottom: 10px;
135 | }
136 |
137 | ionic2-datepicker .datepicker-wrapper .datepicker-header .weekday-header {
138 | padding: 8px 10px;
139 | background-color: #008d7f;
140 | }
141 |
142 | ionic2-datepicker .datepicker-wrapper .datepicker-header .weekday-header .weekday-title {
143 | font-weight: bold;
144 | text-align: center;
145 | }
146 |
147 | ionic2-datepicker .weekdays-row {
148 | text-align: center;
149 | }
150 |
151 | ionic2-datepicker .datepicker-calendar {
152 | height: calc(100% - (35% + 60px));
153 | }
154 |
155 | ionic2-datepicker .datepicker-calendar .datepicker-controls {
156 | align-items: center;
157 | justify-content: space-between;
158 | }
159 |
160 | ionic2-datepicker .datepicker-calendar .calendar-wrapper {
161 | height: calc(100% - 60px - 40px);
162 | display: flex;
163 | flex-direction: column;
164 | justify-content: space-around;
165 | }
166 |
167 | ionic2-datepicker .datepicker-calendar .calendar-wrapper .datepicker-mark {
168 | background-color: #5b6c6b;
169 | border-radius: 20px;
170 | }
171 |
172 | ionic2-datepicker .datepicker-calendar .calendar-wrapper .datepicker-selected {
173 | background-color: #b6d9d6;
174 | border-radius: 20px;
175 | }
176 |
177 | ionic2-datepicker .datepicker-calendar .calendar-wrapper .datepicker-current {
178 | color: #3caa9f;
179 | border-radius: 20px;
180 | }
181 |
182 | ionic2-datepicker .datepicker-calendar .calendar-wrapper .datepicker-disabled {
183 | color: #aaaaaa;
184 | }
185 |
186 | ionic2-datepicker .datepicker-calendar .calendar-wrapper .calendar-cell {
187 | flex-flow: row wrap;
188 | text-align: center;
189 | }
190 |
191 | ionic2-datepicker .datepicker-footer {
192 | display: flex;
193 | justify-content: space-between;
194 | height: 60px;
195 | }
196 |
197 | ionic2-datepicker .datepicker-footer button {
198 | width: 100%;
199 | }
200 |
201 | `],
202 | selector: 'ionic2-datepicker',
203 | encapsulation: ViewEncapsulation.None,
204 | })
205 |
206 | export class DatePickerComponent {
207 | public config: {
208 | okText: string,
209 | cancelText: string,
210 | min: Date,
211 | max: Date,
212 | ionChanged: EventEmitter,
213 | ionSelected: EventEmitter,
214 | ionCanceled: EventEmitter,
215 | headerClasses: string[],
216 | bodyClasses: string[],
217 | date: Date,
218 | disabledDates: Date[],
219 | markDates: Date[],
220 | showMaxAndMin: boolean;
221 | };
222 | public selectedDate: Date = new Date();
223 | public dateList: Date[];
224 | public cols: number[];
225 | public rows: number[];
226 | public weekdays: string[];
227 | public months: string[];
228 | public years: string[];
229 | public active: boolean = false;
230 | private tempDate: Date;
231 | private today: Date = new Date();
232 |
233 |
234 | public yearsMaxMin: number[];
235 | public selectedMonth;
236 | public selectedYear;
237 | public monthChanged: FormControl;
238 | public yearChanged: FormControl;
239 | public nextDisabled: boolean = false;
240 | public previousDisabled: boolean = false;
241 | private maxYear: number;
242 | private minYear: number;
243 |
244 | constructor(public viewCtrl: ViewController,
245 | public navParams: NavParams,
246 | public DatepickerService: DateService) {
247 | this.config = this.navParams.data;
248 | this.selectedDate = this.navParams.data.date;
249 | this.initialize();
250 |
251 | }
252 |
253 |
254 | /**
255 | * @function initialize - Initializes date variables
256 | */
257 | public initialize(): void {
258 | this.tempDate = this.selectedDate;
259 | this.createDateList(this.selectedDate);
260 | this.weekdays = this.DatepickerService.getDaysOfWeek();
261 | this.months = this.DatepickerService.getMonths();
262 | this.years = this.DatepickerService.getYears();
263 | this.initSelectBoxes();
264 | this.initSelectBoxListener();
265 | }
266 |
267 | /**
268 | * initializes the selectbox and considers max and min date
269 | */
270 | private initSelectBoxes() {
271 | let maxDate = this.config.max;
272 | let minDate = this.config.min;
273 | this.maxYear = Number.parseInt(this.years[this.years.length - 1]);
274 | this.minYear = Number.parseInt(this.years[0]);
275 | if (maxDate) {
276 | this.maxYear = maxDate.getFullYear();
277 | }
278 | if (minDate) {
279 | this.minYear = minDate.getFullYear();
280 | }
281 | this.yearsMaxMin = [];
282 | for (let _minYear = this.minYear; _minYear <= this.maxYear; _minYear++) {
283 | this.yearsMaxMin.push(_minYear);
284 | }
285 | this.selectedMonth = this.getSelectedMonth();
286 | this.selectedYear = this.getSelectedYear();
287 | }
288 |
289 | /**
290 | * initializes the listener to change the dategrid if that changes
291 | */
292 | private initSelectBoxListener() {
293 | this.monthChanged = new FormControl();
294 | this.monthChanged.valueChanges
295 | .subscribe(selectedMonth => {
296 | let monthAsNumber = this.months.indexOf(selectedMonth);
297 | let testDate: Date = new Date(this.tempDate.getTime());
298 | testDate.setMonth(monthAsNumber);
299 | this.tempDate = testDate;
300 | this.createDateList(this.tempDate);
301 | this.checkDisableButtons(monthAsNumber, testDate.getFullYear());
302 | });
303 | this.yearChanged = new FormControl();
304 | this.yearChanged.valueChanges
305 | .subscribe(selectedYear => {
306 | let testDate: Date = new Date(this.tempDate.getTime());
307 | testDate.setFullYear(selectedYear);
308 | this.tempDate = testDate;
309 | this.createDateList(this.tempDate);
310 | this.checkDisableButtons(testDate.getMonth(), selectedYear);
311 | });
312 | }
313 |
314 | /**
315 | * checks if the forward/previos buttons should be disabled or not
316 | * @param selectedMonth
317 | * @param selectedYear
318 | */
319 | checkDisableButtons(selectedMonth, selectedYear) {
320 | this.nextDisabled = selectedMonth == 11 && this.maxYear === selectedYear;
321 | this.previousDisabled = selectedMonth == 0 && this.minYear === selectedYear;
322 | }
323 |
324 | /**
325 | * @function createDateList - creates the list of dates
326 | * @param selectedDate - creates the list based on the currently selected date
327 | */
328 | public createDateList(selectedDate: Date): void {
329 | this.dateList = this.DatepickerService.createDateList(selectedDate);
330 | this.cols = new Array(7);
331 | this.rows = new Array(Math.ceil(this.dateList.length / this.cols.length));
332 | }
333 |
334 | /**
335 | * @function getDate - gets the actual date of date from the list of dates
336 | * @param row - the row of the date in a month. For instance 14 date would be 3rd or 2nd row
337 | * @param col - the column of the date in a month. For instance 1 would be on the column of the weekday.
338 | */
339 | public getDate(row: number, col: number): Date {
340 | /**
341 | * @description The locale en-US is noted for the sake of starting with monday if its in usa
342 | */
343 | return this.dateList[(row * 7 + col) + ((this.DatepickerService.doesStartFromMonday()) ? 1 : 0)];
344 | }
345 |
346 | /**
347 | * @function getDate - gets the actual number of date from the list of dates
348 | * @param row - the row of the date in a month. For instance 14 date would be 3rd or 2nd row
349 | * @param col - the column of the date in a month. For instance 1 would be on the column of the weekday.
350 | */
351 | public getDateAsDay(row: number, col: number): number {
352 | let date = this.getDate(row, col);
353 | if (date) return date.getDate();
354 | }
355 |
356 |
357 | /**
358 | * @function isDisabled - Checks whether the date should be disabled or not
359 | * @param date - the date to test against
360 | */
361 | public isDisabled(date: Date): boolean {
362 | if (!date) return true;
363 | if (this.config.min) {
364 | this.config.min.setHours(0, 0, 0, 0);
365 | if (date < this.config.min) return true;
366 | }
367 | if (this.config.max) {
368 | this.config.max.setHours(0, 0, 0, 0);
369 | if (date > this.config.max) return true;
370 | }
371 | if (this.config.disabledDates) {
372 | return this.config.disabledDates.some(disabledDate =>
373 | this.areEqualDates(new Date(disabledDate), date));
374 | }
375 | return false;
376 | }
377 |
378 | public isMark(date: Date): boolean {
379 | if (!date) return false;
380 | if (this.config.markDates) {
381 | return this.config.markDates.some(markDate =>
382 | this.areEqualDates(new Date(markDate), date));
383 | }
384 | return false
385 | }
386 |
387 | public isActualDate(date: Date): boolean {
388 | if (!date) return false;
389 | return this.areEqualDates(date, this.today);
390 | }
391 |
392 | public isActualMonth(month: number): boolean {
393 | return month === this.today.getMonth();
394 | }
395 |
396 | public isActualYear(year: number): boolean {
397 | return year === this.today.getFullYear();
398 | }
399 |
400 | public isSelectedDate(date: Date): boolean {
401 | if (!date) return false;
402 | return this.areEqualDates(date, this.selectedDate);
403 | }
404 |
405 | public isSelectedMonth(month: number): boolean {
406 | return month === this.tempDate.getMonth();
407 | }
408 |
409 | public isSelectedYear(year: number): boolean {
410 | return year === this.tempDate.getFullYear();
411 | }
412 |
413 |
414 | public selectDate(date: Date): void {
415 | if (this.isDisabled(date)) return;
416 | this.selectedDate = date;
417 | this.selectedDate.setHours(0, 0, 0, 0);
418 | this.tempDate = this.selectedDate;
419 | this.config.ionSelected.emit(this.tempDate);
420 | }
421 |
422 |
423 | public getSelectedWeekday(): string {
424 | return this.weekdays[this.selectedDate.getDay()];
425 | }
426 |
427 | public getSelectedMonth(date?: Date): string {
428 | if (!date) {
429 | return this.months[this.selectedDate.getMonth()];
430 | } else {
431 | return this.months[date.getMonth()];
432 | }
433 | }
434 |
435 | public getTempMonth() {
436 | return this.months[this.tempDate.getMonth()];
437 | }
438 |
439 | public getTempYear() {
440 | return (this.tempDate || this.selectedDate).getFullYear();
441 | }
442 |
443 | public getSelectedDate() {
444 | return (this.selectedDate || new Date()).getDate();
445 | }
446 |
447 | public getSelectedYear() {
448 | return (this.selectedDate || new Date()).getFullYear();
449 | }
450 |
451 |
452 | public onCancel(e: Event) {
453 | if (this.config.date)
454 | this.selectedDate = this.config.date || new Date();
455 | this.config.ionCanceled.emit();
456 | this.viewCtrl.dismiss();
457 | };
458 |
459 | public onDone(e: Event) {
460 | this.config.date = this.selectedDate;
461 | this.config.ionChanged.emit(this.config.date);
462 | this.viewCtrl.dismiss();
463 | };
464 |
465 | public selectMonthOrYear() {
466 | this.createDateList(this.tempDate);
467 | if (this.isDisabled(this.tempDate)) return;
468 | this.selectedDate = this.tempDate;
469 | }
470 |
471 | private areEqualDates(dateA: Date, dateB: Date) {
472 | return dateA.getDate() === dateB.getDate() &&
473 | dateA.getMonth() === dateB.getMonth() &&
474 | dateA.getFullYear() === dateB.getFullYear();
475 | }
476 |
477 | public limitTo(arr: Array | string, limit: number): Array | string {
478 | if (this.DatepickerService.locale === 'custom') return arr;
479 | if (this.DatepickerService.locale === 'de') limit = 2;
480 | if (Array.isArray(arr))
481 | return arr.splice(0, limit);
482 | if (this.DatepickerService.locale === 'zh-CN' || this.DatepickerService.locale === 'zh-TW')
483 | arr = arr.replace('星期', '')
484 | return (arr).slice(0, limit);
485 | }
486 |
487 | public getMonthRows(): {}[] {
488 | return [];
489 | }
490 |
491 |
492 | public nextMonth() {
493 | //if (this.max.getMonth() < this.tempDate.getMonth() + 1 && this.min.getFullYear() === this.tempDate.getFullYear()) return;
494 | let testDate: Date = new Date(this.tempDate.getTime());
495 | testDate.setDate(1);
496 |
497 | if (testDate.getMonth() === 11) {
498 | testDate.setFullYear(testDate.getFullYear() + 1);
499 | testDate.setMonth(0);
500 | }
501 | else {
502 | testDate.setMonth(testDate.getMonth() + 1);
503 | }
504 | if ((!this.config.max || this.config.max >= testDate) || this.config.showMaxAndMin) {
505 | this.setDateAfterSelection(testDate);
506 | }
507 | }
508 |
509 | public prevMonth() {
510 | let testDate: Date = new Date(this.tempDate.getTime());
511 | testDate.setDate(0);
512 | // testDate.setDate(this.tempDate.getDate());
513 | if ((!this.config.min ||
514 | (this.config.min <= testDate)) || this.config.showMaxAndMin) {
515 | this.setDateAfterSelection(testDate);
516 | }
517 | }
518 |
519 | /**
520 | * calls to create the days (list/grid) if applicable
521 | * @param {Date} testDate
522 | */
523 | private setDateAfterSelection(testDate: Date) {
524 | this.tempDate = testDate;
525 | this.createDateList(this.tempDate);
526 | this.selectedMonth = this.getSelectedMonth(this.tempDate);
527 | this.selectedYear = this.tempDate.getFullYear();
528 | this.checkDisableButtons(this.tempDate.getMonth(), this.selectedYear);
529 | }
530 | }
--------------------------------------------------------------------------------
/src/components/datepicker.directive.ts:
--------------------------------------------------------------------------------
1 | import {ModalOptions} from 'ionic-angular';
2 | import {DatePickerController, DatePickerDisplayer} from './datepicker.modal';
3 | import {Directive, EventEmitter, HostListener, Input, Output} from '@angular/core';
4 |
5 | import {DatePickerData} from './datepicker.interface';
6 | import {DateService} from './datepicker.service';
7 |
8 | @Directive({
9 | selector: 'ion-datepicker,[ion-datepicker]',
10 | })
11 | export class DatePickerDirective {
12 | @Output('ionChanged') public changed: EventEmitter = new EventEmitter();
13 | @Output('ionCanceled') public canceled: EventEmitter = new EventEmitter();
14 |
15 | @Input() public max: Date;
16 | @Input() public min: Date;
17 |
18 | @Input()
19 | public set locale(val: string) {
20 | if (val)
21 | this.dateService.locale = val;
22 | };
23 |
24 | @Input()
25 | public set localeStrings(val: { weekdays: string[], months: string[] }) {
26 | if (val) {
27 | this.dateService.locale = 'custom';
28 | this.locale = 'custom';
29 | this.dateService.setCustomNls(val);
30 | }
31 | };
32 |
33 | @Input() public okText: string;
34 | @Input() public cancelText: string;
35 | @Input() public bodyClasses: Array;
36 | @Input() public headerClasses: Array;
37 | @Input() public modalOptions: ModalOptions;
38 | @Input() public value: Date = new Date();
39 | @Input() public disabledDates: Date[] = [];
40 | @Input() public markDates: Date[] = [];
41 | @Input() public showMaxAndMin: boolean = false;
42 | public dateSelected: EventEmitter = new EventEmitter();
43 | public modal: DatePickerDisplayer;
44 | private _fn: any;
45 |
46 | constructor(public datepickerCtrl: DatePickerController,
47 | public dateService: DateService) {
48 | this.changed.subscribe((d: Date) => {
49 | this.value = d;
50 | });
51 | }
52 |
53 | @HostListener('tap', ['$event'])
54 | _click(ev: UIEvent) {
55 | this.open();
56 | }
57 |
58 | public open() {
59 | const data = {
60 | min: this.min,
61 | max: this.max,
62 | bodyClasses: this.bodyClasses,
63 | headerClasses: this.headerClasses,
64 | ionChanged: this.changed,
65 | ionCanceled: this.canceled,
66 | ionSelected: this.dateSelected,
67 | date: this.value,
68 | okText: this.okText,
69 | cancelText: this.cancelText,
70 | disabledDates: this.disabledDates,
71 | markDates: this.markDates,
72 | showMaxAndMin: this.showMaxAndMin
73 | };
74 | this.modal = this.datepickerCtrl.create(data, this.modalOptions);
75 | this.modal.present();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/components/datepicker.interface.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from "@angular/core";
2 | import { languages } from './nls';
3 |
4 | export interface DatePickerData {
5 | okText?: string,
6 | cancelText?: string,
7 | showMaxAndMin: boolean,
8 | min?: Date,
9 | max?: Date,
10 | ionChanged: EventEmitter,
11 | ionSelected: EventEmitter,
12 | ionCanceled: EventEmitter,
13 | headerClasses?: string[],
14 | bodyClasses?: string[],
15 | date?: Date
16 | locale?: languages;
17 | disabledDates: Date[];
18 | markDates: Date[];
19 | }
--------------------------------------------------------------------------------
/src/components/datepicker.modal.ts:
--------------------------------------------------------------------------------
1 | import { App, ModalCmp, ModalOptions, NavOptions, ViewController } from 'ionic-angular';
2 | import { ModalMDSlideIn, ModalMDSlideOut, ModalSlideIn, ModalSlideOut } from 'ionic-angular/components/modal/modal-transitions';
3 |
4 | import { Config } from 'ionic-angular/config/config';
5 | import { DatePickerComponent } from './datepicker.component';
6 | import { Injectable } from '@angular/core';
7 | import { PORTAL_MODAL } from 'ionic-angular/components/app/app-constants';
8 | import { isPresent } from 'ionic-angular/util/util';
9 |
10 | /**
11 | * @private
12 | */
13 | export class DatePickerDisplayer extends ViewController {
14 | private _app: App;
15 | private _enterAnimation: string;
16 | private _leaveAnimation: string;
17 |
18 | constructor(app: App, component: any, data: any, opts: ModalOptions = {}, config: Config) {
19 |
20 | data = data || {};
21 | data.component = component;
22 | opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
23 | opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
24 | data.opts = opts;
25 |
26 | super(ModalCmp, data, null);
27 | this._app = app;
28 | this._enterAnimation = opts.enterAnimation;
29 | this._leaveAnimation = opts.leaveAnimation;
30 |
31 | this.isOverlay = true;
32 |
33 | config.setTransition('modal-slide-in', ModalSlideIn);
34 | config.setTransition('modal-slide-out', ModalSlideOut);
35 | config.setTransition('modal-md-slide-in', ModalMDSlideIn);
36 | config.setTransition('modal-md-slide-out', ModalMDSlideOut);
37 | }
38 |
39 | /**
40 | * @private
41 | */
42 | getTransitionName(direction: string): string {
43 | let key: string;
44 | if (direction === 'back') {
45 | if (this._leaveAnimation) {
46 | return this._leaveAnimation;
47 | }
48 | key = 'modalLeave';
49 | } else {
50 | if (this._enterAnimation) {
51 | return this._enterAnimation;
52 | }
53 | key = 'modalEnter';
54 | }
55 | return this._nav && this._nav.config.get(key);
56 | }
57 |
58 | /**
59 | * Present the action sheet instance.
60 | *
61 | * @param {NavOptions} [opts={}] Nav options to go with this transition.
62 | * @returns {Promise} Returns a promise which is resolved when the transition has completed.
63 | */
64 | present(navOptions: NavOptions = {}) {
65 | return this._app.present(this, navOptions, PORTAL_MODAL);
66 | }
67 | }
68 | @Injectable()
69 | export class DatePickerController {
70 |
71 | constructor(private _app: App, public config: Config) { }
72 | /**
73 | * Create a modal to display. See below for options.
74 | *
75 | * @param {object} component The Modal view
76 | * @param {object} data Any data to pass to the Modal view
77 | * @param {object} opts Modal options
78 | */
79 | create(data: any = {}, opts: ModalOptions = {}) {
80 | data.component = DatePickerComponent;
81 | opts.showBackdrop = opts.showBackdrop !== undefined ? !!opts.showBackdrop : true;
82 | opts.enableBackdropDismiss = opts.enableBackdropDismiss !== undefined ? !!opts.enableBackdropDismiss : true;
83 | data.opts = opts;
84 | return new DatePickerDisplayer(this._app, data.component, data, opts, this.config);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/components/datepicker.module.ts:
--------------------------------------------------------------------------------
1 | import {CUSTOM_ELEMENTS_SCHEMA, NgModule} from '@angular/core';
2 |
3 | import {CommonModule} from '@angular/common';
4 | import {DatePickerComponent} from './datepicker.component';
5 | import {DatePickerController} from './datepicker.modal';
6 | import {DatePickerDirective} from './datepicker.directive';
7 | import {DateService} from './datepicker.service';
8 | import {FormsModule, ReactiveFormsModule} from '@angular/forms';
9 |
10 | @NgModule({
11 | imports: [
12 | CommonModule, FormsModule, ReactiveFormsModule
13 | ],
14 | exports: [
15 | DatePickerComponent,
16 | DatePickerDirective],
17 | entryComponents: [DatePickerComponent],
18 | declarations: [DatePickerComponent, DatePickerDirective],
19 | providers: [
20 | DatePickerController,
21 | DateService],
22 | schemas: [
23 | CUSTOM_ELEMENTS_SCHEMA
24 | ]
25 | })
26 | export class DatePickerModule {
27 | }
28 |
--------------------------------------------------------------------------------
/src/components/datepicker.service.ts:
--------------------------------------------------------------------------------
1 | import {languages, nls} from './nls';
2 |
3 | import {Injectable} from '@angular/core';
4 |
5 | @Injectable()
6 | export class DateService {
7 | private static _local: languages = undefined;
8 |
9 | public get locale(): languages {
10 | return DateService._local || 'en-UK';
11 | }
12 |
13 | public set locale(val: languages) {
14 | if (!nls.checkExists(val)) {
15 | throw 'Locale not recognized as a valid value. Only en-US/he-IL/ru-RU/pt-BR/de avaliable';
16 | }
17 | DateService._local = val;
18 | }
19 |
20 | constructor() {
21 | }
22 |
23 | // private locale = ((window).navigator['userLanguage'] || window.navigator.language).toLowerCase();
24 |
25 | public setCustomNls(val: { weekdays: string[], months: string[] }) {
26 | nls._nls.custom = val;
27 | }
28 |
29 | public getDaysOfWeek() {
30 | return nls.getWeekdays(this.locale);
31 | }
32 |
33 | public getMonths() {
34 | return nls.getMonths(this.locale);
35 | }
36 |
37 | public doesStartFromMonday(): boolean {
38 | return nls.getNls(this.locale).monday === true;
39 | }
40 |
41 | public getYears() {
42 | let years: Array = [];
43 | for (let i = 1900; i < 2101; i++) years.push(i);
44 | return years;
45 | }
46 |
47 | public createDateList(currentDate: Date) {
48 | let firstDayOfWeek = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1).getDay();
49 | let firstDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1).getDate();
50 | let lastDay = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate();
51 | let dateList: Date[] = [];
52 |
53 | // Empty placeholders so dates align with weekday columns
54 | for (let j = 0; j < firstDayOfWeek; j++) {
55 | dateList.push(undefined);
56 | }
57 |
58 | // Actual dates
59 | for (let i = firstDay; i <= lastDay; i++) {
60 | dateList.push(new Date(currentDate.getFullYear(), currentDate.getMonth(), i));
61 | }
62 |
63 | return dateList;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/components/nls.ts:
--------------------------------------------------------------------------------
1 |
2 | export module nls {
3 | export const _nls =
4 | {
5 | 'custom': {
6 |
7 | },
8 | 'en-US': {
9 | monday: true,
10 | weekdays: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
11 | months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
12 | },
13 | 'en-UK': {
14 | weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
15 | months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
16 | },
17 | 'pt-BR': {
18 | weekdays: ['Domingo', 'Segunda-Feira', 'Terça-Feira', 'Quarta-Feira', 'Quinta-Feira', 'Sexta-Feira', 'Sábado'],
19 | months: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro']
20 | },
21 | 'he-IL': {
22 | weekdays: ['ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת'],
23 | months: ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר']
24 | },
25 | 'ru-RU': {
26 | weekdays: ['Воскресение', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],
27 | months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']
28 | },
29 | 'de': {
30 | weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
31 | months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
32 | 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember']
33 | },
34 | 'fi': {
35 | weekdays: ['Sunnuntai', 'Maanantai', 'Tiistai', 'Keskiviikko', 'Torstai', 'Perjantai', 'Lauantai'],
36 | months: ['Tammikuu', 'Helmikuu', 'Maaliskuu', 'Huhtikuu', 'Toukokuu', 'Kesäkuu',
37 | 'Heinäkuu', 'Elokuu', 'Syyskuu', 'Lokakuu', 'Marraskuu', 'Joulukuu']
38 | },
39 | 'zh-CN': {
40 | weekdays: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
41 | months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
42 | },
43 | 'zh-TW': {
44 | weekdays: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
45 | months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
46 | }
47 | };
48 |
49 | export function getWeekdays(locale: languages): string[] {
50 | return this.getNls(locale).weekdays;
51 | }
52 | export function getMonths(locale: languages): string[] {
53 | return this.getNls(locale).months;
54 | }
55 | export function getNls(locale: languages): { weekdays: string[], months: string[], monday: boolean } {
56 | return this._nls[locale] || this._nls['en-US'];
57 | }
58 |
59 | export function checkExists(locale: string): boolean {
60 | let keys: Array = Object.keys(this._nls);
61 | return keys.some(key => key === locale);
62 | }
63 | }
64 | export type languages = string | 'en-US' | 'en-UK' | 'pt-BR' | 'he-IL' | 'ru-RU' | 'de' | 'fi' | 'zh-TW' | 'zh-CN' | 'custom';
65 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { DatePickerModule } from './components/datepicker.module';
2 | export { DatePickerDirective } from './components/datepicker.directive';
3 | export { DatePickerComponent } from './components/datepicker.component';
4 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "emitDecoratorMetadata": true,
4 | "experimentalDecorators": true,
5 | "target": "es5",
6 | "module": "es2015",
7 | "moduleResolution": "node",
8 | "removeComments": true,
9 | "lib": [
10 | "es2015",
11 | "dom"
12 | ],
13 | "sourceMap": true,
14 | "outDir": "dist",
15 | "declarationDir": "dist",
16 | "declaration": true
17 | },
18 | "compileOnSave": true,
19 | "include": [
20 | "src/**/*"
21 | ],
22 | "exclude": [
23 | "demo",
24 | "index.d.ts",
25 | "node_modules",
26 | "dist"
27 | ],
28 | "angularCompilerOptions": {
29 | "genDir": "dist/",
30 | "strictMetadataEmit": true,
31 | "skipTemplateCodegen": true
32 | }
33 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-duplicate-variable": true,
4 | "no-unused-variable": [
5 | true
6 | ]
7 | },
8 | "rulesDirectory": [
9 | "node_modules/tslint-eslint-rules/dist/rules"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------