├── .gitignore ├── .npmignore ├── .travis.yml ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── README.md ├── app ├── app.component.ts ├── app.route.ts ├── build │ ├── app.js │ └── app.js.map ├── component-test.component.ts ├── directive-test.component.ts ├── index.html ├── main.ts ├── moment-with-locales.min.js ├── moment.min.js └── webpack.config.js ├── dist ├── datetime-picker.component.d.ts ├── datetime-picker.component.js ├── datetime-picker.component.js.map ├── datetime-picker.component.metadata.json ├── datetime-picker.directive.d.ts ├── datetime-picker.directive.js ├── datetime-picker.directive.js.map ├── datetime-picker.directive.metadata.json ├── datetime-picker.module.d.ts ├── datetime-picker.module.js ├── datetime-picker.module.js.map ├── datetime-picker.module.metadata.json ├── datetime-picker.umd.js ├── datetime-picker.umd.js.map ├── datetime.d.ts ├── datetime.js ├── datetime.js.map ├── datetime.metadata.json ├── index.d.ts ├── index.js └── index.js.map ├── package.json ├── src ├── datetime-picker.component.ts ├── datetime-picker.directive.ts ├── datetime-picker.module.ts ├── datetime.ts └── index.ts ├── tsconfig.json ├── tsconfig.ngc.json ├── webpack.config.js └── webtest.txt /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | *.log 4 | app/app.component.js 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | test 3 | build.sh 4 | tsconfig.json 5 | node_modules 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | # To start firefox, xvfb(X virtual framebuffer) 5 | before_script: 6 | - export DISPLAY=:99.0 7 | - sh -e /etc/init.d/xvfb start 8 | - sleep 5 9 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **IMPORTANT** 2 | _Please be specific with an example. An issue with no example or unclear requirements may be closed._ 3 | 4 | **Steps to reproduce and a minimal demo** 5 | 6 | - _What steps should we try in your demo to see the problem?_ 7 | - _Plunker example(required), MCVE(Minimal/Complete/Verifable Example)_ 8 | - _If you cannot reproduce an issue with a plunker example, it may be your environmental issue_ 9 | 10 | **Current behavior** 11 | 12 | - 13 | 14 | **Expected/desired behavior** 15 | 16 | - 17 | 18 | **Other information** 19 | 20 | - 21 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Allen Kim 2 | 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular(2+) Datetime Picker 2 | 3 | 4 | 5 | 6 | [![Build Status](https://travis-ci.org/ng2-ui/datetime-picker.svg?branch=master)](https://travis-ci.org/ng2-ui/datetime-picker) 7 | [![Join the chat at https://gitter.im/ng2-ui/datetime-picker](https://badges.gitter.im/ng2-ui/datetime-picker.svg)](https://gitter.im/ng2-ui/datetime-picker?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 8 | AngularJS 2 DateTime Picker 9 | 10 | ## NOTE: NOT-MAINTAINED :( 11 | This project has been archived because of inactivity of the owner, Allen Kim. The current owner is looking for a new owner and ready to transfer ownership. Please send me the email to "allenhwkim AT gmail.com" to claim the ownership. 12 | 13 | 14 | 15 | 16 | 17 | [Plunker Example](https://plnkr.co/edit/su2aiL) 18 | [French Example](https://plnkr.co/edit/J6hXyB?p=preview) 19 | 20 | 21 | ## How Does It Work 22 | 23 | 1. Get a Date or string from input field. 24 | 2. If input value is string, convert it to Date object and save it internally. 25 | 3. When the input field is clicked, show date time picker with date value. 26 | 4. When date time is selected, set `toString` function of selected date for formatting. 27 | 5. Set input field with the selected value. 28 | 29 | ## Install 30 | 31 | 1. install datetime-picker 32 | 33 | $ npm install @ngui/datetime-picker --save 34 | 35 | 2. If you are using SystemJS, add `map` and `packages` to your `systemjs.config.js` 36 | 37 | map[‘@ngui/datetime-picker'] = 'node_modules/@ngui/datetime-picker/dist'; 38 | packages[‘@ngui/datetime-picker'] = { main: '@ngui/datetime-picker.umd.js', defaultExtension: 'js’ } 39 | 40 | 3. import NguiDatetimePickerModule to your AppModule 41 | 42 | import { NgModule } from '@angular/core'; 43 | import { FormsModule } from "@angular/forms"; 44 | import { BrowserModule } from '@angular/platform-browser'; 45 | import { AppComponent } from './app.component'; 46 | import { NguiDatetimePickerModule } from '@ngui/datetime-picker'; 47 | 48 | @NgModule({ 49 | imports: [BrowserModule, FormsModule, NguiDatetimePickerModule], 50 | declarations: [AppComponent], 51 | bootstrap: [ AppComponent ] 52 | }) 53 | export class AppModule { } 54 | 55 | ## Use it in your code 56 | 57 | 58 | 62 | 63 |
64 | 70 |
71 | 72 | 81 | 82 | For full example, please check `test` directory to see the example of; 83 | 84 | - `app.module.ts` 85 | - and `app.component.ts`. 86 | 87 | ## Override default style 88 | 89 | The default style is written in `src/ngui-datetime-picker.component.ts`. 90 | This can be overwritten by giving a more detailed css selector. 91 | 92 | e.g., 93 | 94 | #my-div .ngui-datetime-picker { 95 | background-color: blue; 96 | } 97 | 98 | ## Override built-in date parser and date formatter 99 | 100 | The default date parser and formatter can only handle 'YYYY-MM-DD HH:MM' format 101 | if you are not using [momentjs](http://momentjs.com/). If you use momentjs, you 102 | can use momentjs dateformat by adding the following in your html. 103 | 104 | 105 | 106 | If you are using moment and want to pass in a string date value in one format but display it in a different format 107 | you can use both date-format and parse-format: 108 | 109 | 114 | 115 | If you want to have your own date format without using momentjs, 116 | please override `NguiDateTime.parser` and `NguiDateTime.formatDate` function. 117 | For example, 118 | 119 | import { NguiDatetimePickerModule, NguiDatetime } from '@ngui/datetime-picker'; 120 | 121 | // Override Date object formatter 122 | NguiDatetime.formatDate = (date: Date) : string => { 123 | ..... my own function that returns a string .... 124 | }; 125 | 126 | // Override Date object parser 127 | NguiDatetime.parseDate = (str: any): Date => { 128 | .... my own function that returns a date ... 129 | } ; 130 | 131 | @NgModule({ 132 | imports: [BrowserModule, FormsModule, NguiDatetimePickerModule], 133 | declarations: [AppComponent], 134 | bootstrap: [ AppComponent ] 135 | }) 136 | export class AppModule { } 137 | 138 | In addition, you can override other static variables of `NguiDatetime` class. The following 139 | is the list of variables that you can override. 140 | 141 | * **days**: default: 1,2,....31 142 | * **daysOfWeek**: default: Sunday, Monday, ..... 143 | * **weekends**: default: 0,6 144 | * **firstDayOfWeek**: default: 0 as in Sunday 145 | * **months**: default: January, February 146 | * **formatDate**: default: returns YYYY-MM-DD HH:MM 147 | * **parseDate**: default: returns date from YYYY-MM-DD HH:MM 148 | * **locale**: default: 'date', 'year', 'month', time', 'hour', 'minute' 149 | 150 | ## **ng2-ui** welcomes new members and contributors 151 | 152 | This module is only improved and maintained by contributors like you; 153 | 154 | As a contributor, it's NOT required to be skilled in Javascript nor Angular2. 155 | It’s required to be open-minded and interested in helping others. 156 | You can contribute to the following; 157 | 158 | * Updating README.md 159 | * Making more and clearer comments 160 | * Answering issues and building FAQ 161 | * Documentation 162 | * Translation 163 | 164 | In result of your active contribution, you will be listed as a core contributor 165 | on https://ng2-ui.github.io, and a member of ng2-ui too. 166 | 167 | If you are interested in becoming a contributor and/or a member of ng-ui, 168 | please send me email to `allenhwkim AT gmail.com` with your github id. 169 | 170 | ## Attributes 171 | All options are optional except value 172 | 173 | * **date-only**, true or false, default is false 174 | * **time-only**, true or false, default is false 175 | * **close-on-select**, true or false. indicates to close ngui-datetime-picker when select a date. default: true 176 | * **date-format**, momentjs date format, e.g. YYYY-MM-DD hh:mm:ss. 177 | You need to include `moment` js in your html to use date-format. 178 | `` 179 | * **parse-format**, momentjs date format used to parse a string input value, e.g. YYYY-MM-DD hh:mm:ss. 180 | You need to include `moment` js in your html to use parse-format. 181 | `` 182 | * **default-value** a date selected when a popup opens, default the current date 183 | * **minute-step** the interval of minutes, default 1 184 | * **min-date** Date, mininum selectable date 185 | * **max-date** Date, maximum selectable date 186 | * **min-hour** number, mininum selectable hour 187 | * **max-hour** number, maximum selectable hour 188 | * **disabled-dates** Array of Date, dates not selectable 189 | * **show-week-numbers** trueor false, default false. Show week numbers 190 | 191 | ## Outputs of directive 192 | 193 | * **ngModelChange**, triggered when the input value as changed (contains new input value) 194 | * **valueChanged**, triggered when a date modification is done (contains new date value) 195 | * **popupClosed**, triggered when the component is closed (contains a boolean true) 196 | 197 | ## Outputs of component 198 | 199 | * **selected$**, triggered when a date modification is done (contains new date value) 200 | * **closing$**, triggered when the component is closed (contains a boolean true) 201 | 202 | ## For Developers 203 | 204 | ### To start 205 | 206 | $ git clone https://github.com/ng2-ui/datetime-picker.git 207 | $ cd datetime-picker 208 | $ npm install 209 | $ npm start 210 | 211 | ### List of available npm tasks 212 | 213 | * `npm run` : List all available tasks 214 | * `npm start`: Run `app` directory for development using `webpack-dev-server` with port 9001 215 | * `npm run clean`: Remove dist folder 216 | * `npm run clean:dist`: Clean up unnecessary dist folder within dist and app directory 217 | * `npm run lint`: Lint TypeScript code 218 | * `npm run build:ngc`: build ES module 219 | * `npm run build:umd`: Build UMD module `ng2-map.umd.js` 220 | * `npm run build:app`: Build `app/build/app.js` for runnable examples 221 | * `npm run build`: Build all(build:ngc, build:umc, build:app, and clean:dist) 222 | -------------------------------------------------------------------------------- /app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | //noinspection TypeScriptCheckImport 4 | import { NguiDatetime } from '@ngui/datetime-picker'; 5 | NguiDatetime.firstDayOfWeek = 0; //e.g. 1, or 6 6 | 7 | @Component({ 8 | selector: 'my-app', 9 | template: ` 10 | Directive 11 | Component 12 | ` 13 | }) 14 | export class AppComponent { 15 | } 16 | -------------------------------------------------------------------------------- /app/app.route.ts: -------------------------------------------------------------------------------- 1 | import { Routes, RouterModule } from '@angular/router'; 2 | import { ModuleWithProviders } from '@angular/core'; 3 | 4 | import { DirectiveTestComponent } from './directive-test.component'; 5 | import { ComponentTestComponent } from './component-test.component'; 6 | 7 | export const routes: Routes = [ 8 | { path: 'directive-test', component: DirectiveTestComponent }, 9 | { path: 'component-test', component: ComponentTestComponent }, 10 | { path: '', redirectTo: '/directive-test', pathMatch: 'full' }, 11 | ]; 12 | 13 | export const APP_ROUTER_PROVIDERS: ModuleWithProviders = RouterModule.forRoot(routes); 14 | export const APP_ROUTER_COMPONENTS = [ 15 | DirectiveTestComponent, 16 | ComponentTestComponent 17 | ]; 18 | 19 | -------------------------------------------------------------------------------- /app/component-test.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation } from '@angular/core'; 2 | import { Validators, FormGroup, FormArray, FormBuilder } from '@angular/forms'; 3 | 4 | declare var moment: any; 5 | moment['locale']('en-ca'); //e.g. fr-ca 6 | 7 | //noinspection TypeScriptCheckImport 8 | import { NguiDatetime } from '@ngui/datetime-picker'; 9 | 10 | var templateStr = ` 11 |

Attributes and Events

12 | 13 | 29 | 30 |
selected DateTime : {{ selectedDate || defaultValue }} 31 |
32 |
{{templateStr | htmlCode:'ngui-utils-1'}}
33 |
34 | `; 35 | 36 | @Component({ 37 | selector: 'my-app', 38 | template: templateStr, 39 | encapsulation: ViewEncapsulation.None, 40 | styles: [` 41 | fieldset {display: inline-block; vertical-align: top; margin: 10px; padding: 20px } 42 | `] 43 | }) 44 | export class ComponentTestComponent { 45 | templateStr: string = templateStr; 46 | selectedDate: Date; 47 | 48 | defaultValue = new Date(2017, 0, 31, 21, 45); 49 | minDate = new Date(2017, 0, 1); 50 | maxDate = new Date(2017, 11, 31); 51 | disabledDates = [new Date(2016, 11, 26), new Date(2016, 11, 27)]; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/directive-test.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation } from '@angular/core'; 2 | import { Validators, FormGroup, FormArray, FormBuilder } from '@angular/forms'; 3 | 4 | //noinspection TypeScriptCheckImport 5 | import { NguiDatetime } from '@ngui/datetime-picker'; 6 | 7 | declare var moment: any; 8 | moment['locale']('en-ca'); //e.g. fr-ca 9 | 10 | var templateStr = ` 11 |
12 |

Ng2 DateTime Picker Test

13 | 14 |

min date, max date, disabled dates

15 | 16 | 26 | date2: {{date2}} 27 | 28 | 29 |
{{templateStr | htmlCode:'ngui-utils-2'}}
30 |
31 | 32 |

time only

33 | 34 | 41 | 42 | 43 |
{{templateStr | htmlCode:'ngui-utils-4'}}
44 |
45 | 46 |

with timezone

47 | 48 | 52 | dateWithTimezone: {{dateWithTimezone}} 53 |
54 |
55 |
{{templateStr | htmlCode:'ngui-utils-6'}}
56 |
57 | 58 |

Reactive form

59 | 60 |
61 | 66 |
67 | myForm.controls.date.value: {{myForm.controls.date.value}} 68 |
myForm.value: {{myForm.value | json}} 69 |
myForm.dirty: {{myForm.dirty}} 70 |
myForm.controls.date.dirty: {{myForm.controls.date.dirty}} 71 |
72 | 74 | 2015-06-30 75 | 76 | 78 | 2015-07-19 79 | 80 | 82 | 2015-12-31 83 | 84 |
85 |
{{templateStr | htmlCode:'ngui-utils-3'}}
86 |
87 | 88 |
89 |

Material Design

90 | 91 | 92 | 98 | 99 | 100 |
101 | 102 |
103 | `; 104 | 105 | @Component({ 106 | selector: 'my-app', 107 | template: templateStr, 108 | encapsulation: ViewEncapsulation.None, 109 | styles: [` 110 | ngui-utils-1 .ngui-datetime-picker-wrapper { display: inline-block } 111 | div { font-family: Courier; font-size: 13px} 112 | input { min-width: 200px; font-size: 15px; } 113 | input.ng-dirty { background: #ddd; } 114 | fieldset {display: inline-block; vertical-align: top; margin: 10px; padding: 20px } 115 | `] 116 | }) 117 | export class DirectiveTestComponent { 118 | templateStr: string = templateStr; 119 | 120 | myForm: FormGroup; // our form model 121 | 122 | date2 = new Date(2017, 0, 28); 123 | date2DisabledDates = [new Date(2017, 0, 10), new Date(2017, 0, 20)]; 124 | date2MinDate = new Date(2017, 0, 1); 125 | date2MaxDate = new Date(2017, 11, 31); 126 | date2New = new Date(2017,11,31); 127 | 128 | date3 = new Date("Thu Jan 01 2015 00:00:00 GMT-0500 (EST)"); 129 | 130 | date4TimezoneFormat = 'DD/MM/YYYY HH:mm Z'; 131 | date4: string = NguiDatetime.formatDate( 132 | NguiDatetime.parseDate('2017-01-15T14:22:00-06:00', this.date4TimezoneFormat), this.date4TimezoneFormat 133 | ); 134 | 135 | mdDate: Date = new Date(2017, 0, 28); 136 | 137 | constructor(private fb: FormBuilder) { } 138 | 139 | ngOnInit() { 140 | this.myForm = this.fb.group({ 141 | date: ['2016-02-15', [Validators.required]], 142 | }); 143 | 144 | //moment.tz.setDefault('US/Central'); // Set the default timezone that moment will use 145 | } 146 | 147 | onDatetimePickerClosed() { 148 | console.log('datetime picker is closed'); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular2 Npm Package Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Loading... 14 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/main.ts: -------------------------------------------------------------------------------- 1 | // polyfills, comment the following out for debugging purpose 2 | import 'core-js/es6'; 3 | import 'core-js/es7/reflect'; 4 | import 'zone.js/dist/zone'; 5 | import 'hammerjs'; 6 | 7 | // The browser platform with a compiler 8 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 9 | 10 | import { NgModule } from '@angular/core'; 11 | import { BrowserModule } from '@angular/platform-browser'; 12 | import { FormsModule, ReactiveFormsModule } from "@angular/forms"; 13 | import { LocationStrategy, HashLocationStrategy } from "@angular/common"; 14 | import { MaterialModule } from '@angular/material'; 15 | 16 | import { AppComponent } from './app.component'; 17 | 18 | //noinspection TypeScriptCheckImport 19 | import { NguiDatetimePickerModule, NguiDatetime } from '@ngui/datetime-picker'; 20 | import { NguiUtilsModule } from '@ngui/utils'; 21 | 22 | import { APP_ROUTER_PROVIDERS, APP_ROUTER_COMPONENTS } from './app.route'; 23 | 24 | @NgModule({ 25 | imports: [ 26 | BrowserModule, 27 | APP_ROUTER_PROVIDERS, 28 | FormsModule, 29 | ReactiveFormsModule, 30 | NguiUtilsModule, 31 | NguiDatetimePickerModule, 32 | MaterialModule 33 | ], 34 | declarations: [AppComponent, APP_ROUTER_COMPONENTS], 35 | providers: [ 36 | { provide: LocationStrategy, useClass: HashLocationStrategy }, 37 | ], 38 | bootstrap: [ AppComponent ] 39 | }) 40 | export class AppModule { } 41 | 42 | // Compile and launch the module 43 | platformBrowserDynamic().bootstrapModule(AppModule); 44 | 45 | -------------------------------------------------------------------------------- /app/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | 3 | const config = { 4 | resolve: { 5 | extensions: ['', '.ts', '.webpack.js', '.web.js', '.js'], 6 | alias: { 7 | '@ngui/datetime-picker': '../src/index.ts' 8 | } 9 | }, 10 | devtool: 'source-map', 11 | entry: './app/main.ts', 12 | module: { 13 | loaders: [ 14 | { test: /\.ts$/, loaders: ['ts', 'angular2-template-loader'] }, 15 | { test: /\.html$/, loader: 'raw' } 16 | ] 17 | }, 18 | plugins: [], 19 | ts: { 20 | include: ['src/**/*.ts', 'app/**/*.ts'] 21 | }, 22 | output: { 23 | path: `${__dirname}/build/`, 24 | publicPath: '/build/', 25 | filename: 'app.js' 26 | } 27 | }; 28 | 29 | if (process.env.NODE_ENV === 'prod') { 30 | config.plugins = [ 31 | new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) 32 | ]; 33 | config.module.loaders.push({ 34 | test: /\.ts$/, loader: 'strip-loader?strip[]=debug,strip[]=console.log' 35 | }); 36 | } 37 | 38 | module.exports = config; 39 | -------------------------------------------------------------------------------- /dist/datetime-picker.component.d.ts: -------------------------------------------------------------------------------- 1 | import { ElementRef, ChangeDetectorRef, EventEmitter } from '@angular/core'; 2 | import { NguiDatetime } from './datetime'; 3 | /** 4 | * show a selected date in monthly calendar 5 | */ 6 | export declare class NguiDatetimePickerComponent { 7 | nguiDatetime: NguiDatetime; 8 | cdRef: ChangeDetectorRef; 9 | dateFormat: string; 10 | dateOnly: boolean; 11 | timeOnly: boolean; 12 | selectedDate: Date; 13 | hour: number; 14 | minute: number; 15 | minuteStep: number; 16 | defaultValue: Date; 17 | minDate: Date; 18 | maxDate: Date; 19 | minHour: number; 20 | maxHour: number; 21 | disabledDates: Date[]; 22 | showCloseButton: boolean; 23 | showCloseLayer: boolean; 24 | showWeekNumbers: boolean; 25 | showTodayShortcut: boolean; 26 | showAmPm: boolean; 27 | selected$: EventEmitter; 28 | closing$: EventEmitter; 29 | hours: ElementRef; 30 | minutes: ElementRef; 31 | el: HTMLElement; 32 | disabledDatesInTime: number[]; 33 | locale: any; 34 | showYearSelector: boolean; 35 | private _monthData; 36 | private timeSuffix; 37 | constructor(elementRef: ElementRef, nguiDatetime: NguiDatetime, cdRef: ChangeDetectorRef); 38 | readonly yearsSelectable: number[]; 39 | year: number; 40 | month: number; 41 | day: number; 42 | readonly monthData: any; 43 | today: Date; 44 | ngOnInit(): void; 45 | isWeekend(dayNum: number, month?: number): boolean; 46 | selectYear(year: any): void; 47 | toDate(day: number, month?: number): Date; 48 | toDateOnly(date: Date): Date; 49 | selectCurrentTime(): void; 50 | /** 51 | * set the selected date and close it when closeOnSelect is true 52 | * @param date {Date} 53 | */ 54 | selectDateTime(date?: Date): boolean; 55 | /** 56 | * show prev/next month calendar 57 | */ 58 | updateMonthData(num: number): void; 59 | isDateDisabled(date: Date): boolean; 60 | close(): void; 61 | selectToday(): void; 62 | private convertHours(hours); 63 | } 64 | -------------------------------------------------------------------------------- /dist/datetime-picker.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var core_1 = require('@angular/core'); 3 | var datetime_1 = require('./datetime'); 4 | //@TODO 5 | // . display currently selected day 6 | /** 7 | * show a selected date in monthly calendar 8 | */ 9 | var NguiDatetimePickerComponent = (function () { 10 | function NguiDatetimePickerComponent(elementRef, nguiDatetime, cdRef) { 11 | this.nguiDatetime = nguiDatetime; 12 | this.cdRef = cdRef; 13 | this.minuteStep = 1; 14 | this.showWeekNumbers = false; 15 | this.showTodayShortcut = false; 16 | this.showAmPm = false; 17 | this.selected$ = new core_1.EventEmitter(); 18 | this.closing$ = new core_1.EventEmitter(); 19 | this.locale = datetime_1.NguiDatetime.locale; 20 | this.showYearSelector = false; 21 | this.el = elementRef.nativeElement; 22 | } 23 | Object.defineProperty(NguiDatetimePickerComponent.prototype, "yearsSelectable", { 24 | get: function () { 25 | var startYear = this.year - 100; 26 | var endYear = this.year + 50; 27 | var years = []; 28 | for (var year = startYear; year < endYear; year++) { 29 | years.push(year); 30 | } 31 | return years; 32 | }, 33 | enumerable: true, 34 | configurable: true 35 | }); 36 | Object.defineProperty(NguiDatetimePickerComponent.prototype, "year", { 37 | get: function () { 38 | return this.selectedDate.getFullYear(); 39 | }, 40 | set: function (year) { }, 41 | enumerable: true, 42 | configurable: true 43 | }); 44 | Object.defineProperty(NguiDatetimePickerComponent.prototype, "month", { 45 | get: function () { 46 | return this.selectedDate.getMonth(); 47 | }, 48 | set: function (month) { }, 49 | enumerable: true, 50 | configurable: true 51 | }); 52 | Object.defineProperty(NguiDatetimePickerComponent.prototype, "day", { 53 | get: function () { 54 | return this.selectedDate.getDate(); 55 | }, 56 | set: function (day) { }, 57 | enumerable: true, 58 | configurable: true 59 | }); 60 | Object.defineProperty(NguiDatetimePickerComponent.prototype, "monthData", { 61 | get: function () { 62 | return this._monthData; 63 | }, 64 | enumerable: true, 65 | configurable: true 66 | }); 67 | Object.defineProperty(NguiDatetimePickerComponent.prototype, "today", { 68 | get: function () { 69 | var dt = new Date(); 70 | dt.setHours(0); 71 | dt.setMinutes(0); 72 | dt.setSeconds(0); 73 | dt.setMilliseconds(0); 74 | return dt; 75 | }, 76 | set: function (today) { }, 77 | enumerable: true, 78 | configurable: true 79 | }); 80 | NguiDatetimePickerComponent.prototype.ngOnInit = function () { 81 | if (!this.defaultValue || isNaN(this.defaultValue.getTime())) { 82 | this.defaultValue = new Date(); 83 | } 84 | this.selectedDate = this.defaultValue; 85 | // set hour and minute using moment if available to avoid having Javascript change timezones 86 | if (typeof moment === 'undefined') { 87 | this.hour = this.selectedDate.getHours(); 88 | this.minute = this.selectedDate.getMinutes(); 89 | } 90 | else { 91 | var m = moment(this.selectedDate); 92 | this.hour = m.hours(); 93 | this.minute = m.minute(); 94 | } 95 | this._monthData = this.nguiDatetime.getMonthData(this.year, this.month); 96 | }; 97 | NguiDatetimePickerComponent.prototype.isWeekend = function (dayNum, month) { 98 | if (typeof month === 'undefined') { 99 | return datetime_1.NguiDatetime.weekends.indexOf(dayNum % 7) !== -1; //weekday index 100 | } 101 | else { 102 | var weekday = this.toDate(dayNum, month).getDay(); 103 | return datetime_1.NguiDatetime.weekends.indexOf(weekday) !== -1; 104 | } 105 | }; 106 | NguiDatetimePickerComponent.prototype.selectYear = function (year) { 107 | this._monthData = this.nguiDatetime.getMonthData(year, this._monthData.month); 108 | this.showYearSelector = false; 109 | }; 110 | NguiDatetimePickerComponent.prototype.toDate = function (day, month) { 111 | return new Date(this._monthData.year, month || this._monthData.month, day); 112 | }; 113 | NguiDatetimePickerComponent.prototype.toDateOnly = function (date) { 114 | return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0); 115 | }; 116 | NguiDatetimePickerComponent.prototype.selectCurrentTime = function () { 117 | this.hour = (new Date()).getHours(); 118 | this.minute = (new Date()).getMinutes(); 119 | this.selectDateTime(); 120 | }; 121 | /** 122 | * set the hour and minute 123 | * @param hour {string} 124 | * @param minute {string} 125 | */ 126 | NguiDatetimePickerComponent.prototype.selectTime = function (hour, minute) { 127 | //NOTE: must get hour & minute because 2-way binding does not work with range input in IE <= 11 128 | this.hour = parseInt(hour, 10) || 0; 129 | this.minute = parseInt(minute, 10) || 0; 130 | this.selectDateTime(); 131 | }; 132 | /** 133 | * set the selected date and close it when closeOnSelect is true 134 | * @param date {Date} 135 | */ 136 | NguiDatetimePickerComponent.prototype.selectDateTime = function (date) { 137 | var _this = this; 138 | this.selectedDate = date || this.selectedDate; 139 | if (this.isDateDisabled(this.selectedDate)) { 140 | return false; 141 | } 142 | // editing hours and minutes via javascript date methods causes date to lose timezone info, 143 | // so edit using moment if available 144 | var hour = parseInt('' + this.hour || '0', 10); 145 | var minute = parseInt('' + this.minute || '0', 10); 146 | if (typeof moment !== 'undefined') { 147 | // here selected date has a time of 00:00 in local time, 148 | // so build moment by getting year/month/day separately 149 | // to avoid it saving as a day earlier 150 | var m = moment([this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate()]); 151 | m.hours(hour); 152 | m.minutes(minute); 153 | this.selectedDate = m.toDate(); 154 | } 155 | else { 156 | this.selectedDate.setHours(hour); 157 | this.selectedDate.setMinutes(minute); 158 | } 159 | //console.log('this.selectedDate', this.selectedDate) 160 | this.selectedDate.toString = function () { 161 | return datetime_1.NguiDatetime.formatDate(_this.selectedDate, _this.dateFormat, _this.dateOnly); 162 | }; 163 | this.selected$.emit(this.selectedDate); 164 | }; 165 | ; 166 | /** 167 | * show prev/next month calendar 168 | */ 169 | NguiDatetimePickerComponent.prototype.updateMonthData = function (num) { 170 | this._monthData = this.nguiDatetime.getMonthData(this._monthData.year, this._monthData.month + num); 171 | }; 172 | NguiDatetimePickerComponent.prototype.isDateDisabled = function (date) { 173 | var dateInTime = date.getTime(); 174 | this.disabledDatesInTime = 175 | this.disabledDatesInTime || (this.disabledDates || []).map(function (d) { return d.getTime(); }); 176 | if (this.minDate && (dateInTime < this.minDate.getTime())) { 177 | return true; 178 | } 179 | else if (this.maxDate && (dateInTime > this.maxDate.getTime())) { 180 | return true; 181 | } 182 | else if (this.disabledDatesInTime.indexOf(dateInTime) >= 0) { 183 | return true; 184 | } 185 | return false; 186 | }; 187 | NguiDatetimePickerComponent.prototype.close = function () { 188 | this.closing$.emit(true); 189 | }; 190 | NguiDatetimePickerComponent.prototype.selectToday = function () { 191 | this.selectDateTime(new Date()); 192 | }; 193 | NguiDatetimePickerComponent.prototype.convertHours = function (hours) { 194 | if (this.showAmPm) { 195 | this.timeSuffix = (hours >= 12) ? 'PM' : 'AM'; 196 | hours = (hours == 0) ? 12 : (hours > 12) ? hours - 12 : hours; 197 | } 198 | else { 199 | this.timeSuffix = null; 200 | } 201 | return ("0" + hours).slice(-2); 202 | }; 203 | NguiDatetimePickerComponent.decorators = [ 204 | { type: core_1.Component, args: [{ 205 | providers: [datetime_1.NguiDatetime], 206 | selector: 'ngui-datetime-picker', 207 | template: "\n
\n
\n
\n \n \n
\n «\n \n \n {{monthData?.shortName}}\n \n \n {{monthData.year}}\n \n »\n \n
\n\n \n
\n \n
\n
\n {{weekNumber}}\n
\n
\n \n \n
\n\n \n
\n {{dayOfWeek.shortName}}\n
\n\n \n
\n
\n {{dayNum}}\n
\n
\n\n
\n {{dayNum}}\n
\n\n \n
\n
\n {{dayNum}}\n
\n
\n
\n
\n\n
\n Today\n
\n\n \n
\n
{{locale.currentTime}}
\n \n \n {{convertHours(hour)}} : {{(\"0\"+minute).slice(-2)}} {{timeSuffix}}\n
\n
\n \n \n
\n
\n \n \n
\n
\n\n \n
\n
\n {{locale.year}}\n
\n \n {{year}}\n \n
\n
\n ", 208 | styles: [ 209 | "\n@keyframes slideDown {\n 0% {\n transform: translateY(-10px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes slideUp {\n 0% {\n transform: translateY(100%);\n }\n 100% {\n transform: translateY(0%);\n }\n}\n\n.ngui-datetime-picker-wrapper {\n position: relative;\n}\n\n.ngui-datetime-picker {\n color: #333;\n outline-width: 0;\n font: normal 14px sans-serif;\n border: 1px solid #ddd;\n display: inline-block;\n background: #fff;\n animation: slideDown 0.1s ease-in-out;\n animation-fill-mode: both;\n}\n.ngui-datetime-picker .days {\n width: 210px; /* 30 x 7 days */\n box-sizing: content-box;\n}\n.ngui-datetime-picker .close-button {\n position: absolute;\n width: 1em;\n height: 1em;\n right: 0;\n z-index: 1;\n padding: 0 5px;\n box-sizing: content-box;\n}\n.ngui-datetime-picker .close-button:before {\n content: 'X';\n cursor: pointer;\n color: #ff0000;\n}\n.ngui-datetime-picker > .month {\n text-align: center;\n line-height: 22px;\n padding: 10px;\n background: #fcfcfc;\n text-transform: uppercase;\n font-weight: bold;\n border-bottom: 1px solid #ddd;\n position: relative;\n}\n\n.ngui-datetime-picker > .month > .prev_next {\n color: #555;\n display: block;\n font: normal 24px sans-serif;\n outline: none;\n background: transparent;\n border: none;\n cursor: pointer;\n width: 25px;\n text-align: center;\n box-sizing: content-box;\n}\n.ngui-datetime-picker > .month > .prev_next:hover {\n background-color: #333;\n color: #fff;\n}\n.ngui-datetime-picker > .month > .prev_next.prev {\n float: left;\n}\n.ngui-datetime-picker > .month > .prev_next.next {\n float: right;\n}\n\n.ngui-datetime-picker .week-numbers-and-days {\n text-align: center;\n}\n.ngui-datetime-picker .week-numbers {\n line-height: 30px;\n display: inline-block;\n padding: 30px 0 0 0;\n color: #ddd;\n text-align: right;\n width: 21px;\n vertical-align: top;\n box-sizing: content-box;\n}\n\n.ngui-datetime-picker .days {\n display: inline-block;\n width: 210px; /* 30 x 7 */\n text-align: center;\n padding: 0 10px;\n box-sizing: content-box;\n}\n.ngui-datetime-picker .days .day-of-week,\n.ngui-datetime-picker .days .day {\n box-sizing: border-box;\n border: 1px solid transparent;\n width: 30px;\n line-height: 28px;\n float: left;\n}\n.ngui-datetime-picker .days .day-of-week {\n font-weight: bold;\n}\n.ngui-datetime-picker .days .day-of-week.weekend {\n color: #ccc;\n background-color: inherit;\n}\n.ngui-datetime-picker .days .day:not(.selectable) {\n color: #ccc;\n cursor: default;\n}\n.ngui-datetime-picker .days .weekend {\n color: #ccc;\n background-color: #eee;\n}\n.ngui-datetime-picker .days .day.selectable {\n cursor: pointer;\n}\n.ngui-datetime-picker .days .day.selected {\n background: gray;\n color: #fff;\n}\n.ngui-datetime-picker .days .day:not(.selected).selectable:hover {\n background: #eee;\n}\n.ngui-datetime-picker .days:after {\n content: '';\n display: block;\n clear: left;\n height: 0;\n}\n.ngui-datetime-picker .time {\n position: relative;\n padding: 10px;\n text-transform: Capitalize;\n}\n.ngui-datetime-picker .year-selector {\n position: absolute;\n top: 0;\n left: 0;\n background: #fff;\n height: 100%;\n overflow: auto; \n padding: 5px;\n z-index: 2;\n}\n.ngui-datetime-picker .year-selector .locale{\n text-align: center;\n}\n.ngui-datetime-picker .year-selector .year {\n display: inline-block;\n cursor: pointer;\n padding: 2px 5px;\n}\n.ngui-datetime-picker .year-selector .year:hover {\n background-color: #ddd;\n}\n.ngui-datetime-picker .select-current-time {\n position: absolute;\n top: 1em;\n right: 5px;\n z-index: 1;\n cursor: pointer;\n color: #0000ff;\n}\n.ngui-datetime-picker .hourLabel,\n.ngui-datetime-picker .minutesLabel {\n display: inline-block;\n width: 45px;\n vertical-align: top;\n box-sizing: content-box;\n}\n.closing-layer {\n display: block;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n background: rgba(0,0,0,0);\n}\n\n.ngui-datetime-picker .shortcuts {\n padding: 10px;\n text-align: center;\n}\n\n.ngui-datetime-picker .shortcuts a {\n font-family: Sans-serif;\n margin: 0 0.5em;\n text-decoration: none;\n}\n\n@media (max-width: 767px) {\n .ngui-datetime-picker {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0; \n width: auto !important;\n animation: slideUp 0.1s ease-in-out;\n }\n\n .ngui-datetime-picker > .days {\n display: block;\n margin: 0 auto;\n }\n\n .closing-layer {\n display: block;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n background: rgba(0,0,0,0.2);\n }\n}\n " 210 | ], 211 | encapsulation: core_1.ViewEncapsulation.None 212 | },] }, 213 | ]; 214 | /** @nocollapse */ 215 | NguiDatetimePickerComponent.ctorParameters = [ 216 | { type: core_1.ElementRef, }, 217 | { type: datetime_1.NguiDatetime, }, 218 | { type: core_1.ChangeDetectorRef, }, 219 | ]; 220 | NguiDatetimePickerComponent.propDecorators = { 221 | 'dateFormat': [{ type: core_1.Input, args: ['date-format',] },], 222 | 'dateOnly': [{ type: core_1.Input, args: ['date-only',] },], 223 | 'timeOnly': [{ type: core_1.Input, args: ['time-only',] },], 224 | 'selectedDate': [{ type: core_1.Input, args: ['selected-date',] },], 225 | 'hour': [{ type: core_1.Input, args: ['hour',] },], 226 | 'minute': [{ type: core_1.Input, args: ['minute',] },], 227 | 'minuteStep': [{ type: core_1.Input, args: ['minuteStep',] },], 228 | 'defaultValue': [{ type: core_1.Input, args: ['default-value',] },], 229 | 'minDate': [{ type: core_1.Input, args: ['min-date',] },], 230 | 'maxDate': [{ type: core_1.Input, args: ['max-date',] },], 231 | 'minHour': [{ type: core_1.Input, args: ['min-hour',] },], 232 | 'maxHour': [{ type: core_1.Input, args: ['max-hour',] },], 233 | 'disabledDates': [{ type: core_1.Input, args: ['disabled-dates',] },], 234 | 'showCloseButton': [{ type: core_1.Input, args: ['show-close-button',] },], 235 | 'showCloseLayer': [{ type: core_1.Input, args: ['show-close-layer',] },], 236 | 'showWeekNumbers': [{ type: core_1.Input, args: ['show-week-numbers',] },], 237 | 'showTodayShortcut': [{ type: core_1.Input, args: ['show-today-shortcut',] },], 238 | 'showAmPm': [{ type: core_1.Input, args: ['show-am-pm',] },], 239 | 'selected$': [{ type: core_1.Output, args: ['selected$',] },], 240 | 'closing$': [{ type: core_1.Output, args: ['closing$',] },], 241 | 'hours': [{ type: core_1.ViewChild, args: ['hours',] },], 242 | 'minutes': [{ type: core_1.ViewChild, args: ['minutes',] },], 243 | }; 244 | return NguiDatetimePickerComponent; 245 | }()); 246 | exports.NguiDatetimePickerComponent = NguiDatetimePickerComponent; 247 | //# sourceMappingURL=datetime-picker.component.js.map -------------------------------------------------------------------------------- /dist/datetime-picker.component.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"datetime-picker.component.js","sourceRoot":"","sources":["../src/datetime-picker.component.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/datetime-picker.component.metadata.json: -------------------------------------------------------------------------------- 1 | {"__symbolic":"module","version":1,"metadata":{"NguiDatetimePickerComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component"},"arguments":[{"providers":[{"__symbolic":"reference","module":"./datetime","name":"NguiDatetime"}],"selector":"ngui-datetime-picker","template":"\n
\n
\n
\n \n \n
\n «\n \n \n {{monthData?.shortName}}\n \n \n {{monthData.year}}\n \n »\n \n
\n\n \n
\n \n
\n
\n {{weekNumber}}\n
\n
\n \n \n
\n\n \n
\n {{dayOfWeek.shortName}}\n
\n\n \n
\n
\n {{dayNum}}\n
\n
\n\n
\n {{dayNum}}\n
\n\n \n
\n
\n {{dayNum}}\n
\n
\n
\n
\n\n
\n Today\n
\n\n \n
\n
{{locale.currentTime}}
\n \n \n {{convertHours(hour)}} : {{(\"0\"+minute).slice(-2)}} {{timeSuffix}}\n
\n
\n \n \n
\n
\n \n \n
\n
\n\n \n
\n
\n {{locale.year}}\n
\n \n {{year}}\n \n
\n
\n ","styles":["\n@keyframes slideDown {\n 0% {\n transform: translateY(-10px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes slideUp {\n 0% {\n transform: translateY(100%);\n }\n 100% {\n transform: translateY(0%);\n }\n}\n\n.ngui-datetime-picker-wrapper {\n position: relative;\n}\n\n.ngui-datetime-picker {\n color: #333;\n outline-width: 0;\n font: normal 14px sans-serif;\n border: 1px solid #ddd;\n display: inline-block;\n background: #fff;\n animation: slideDown 0.1s ease-in-out;\n animation-fill-mode: both;\n}\n.ngui-datetime-picker .days {\n width: 210px; /* 30 x 7 days */\n box-sizing: content-box;\n}\n.ngui-datetime-picker .close-button {\n position: absolute;\n width: 1em;\n height: 1em;\n right: 0;\n z-index: 1;\n padding: 0 5px;\n box-sizing: content-box;\n}\n.ngui-datetime-picker .close-button:before {\n content: 'X';\n cursor: pointer;\n color: #ff0000;\n}\n.ngui-datetime-picker > .month {\n text-align: center;\n line-height: 22px;\n padding: 10px;\n background: #fcfcfc;\n text-transform: uppercase;\n font-weight: bold;\n border-bottom: 1px solid #ddd;\n position: relative;\n}\n\n.ngui-datetime-picker > .month > .prev_next {\n color: #555;\n display: block;\n font: normal 24px sans-serif;\n outline: none;\n background: transparent;\n border: none;\n cursor: pointer;\n width: 25px;\n text-align: center;\n box-sizing: content-box;\n}\n.ngui-datetime-picker > .month > .prev_next:hover {\n background-color: #333;\n color: #fff;\n}\n.ngui-datetime-picker > .month > .prev_next.prev {\n float: left;\n}\n.ngui-datetime-picker > .month > .prev_next.next {\n float: right;\n}\n\n.ngui-datetime-picker .week-numbers-and-days {\n text-align: center;\n}\n.ngui-datetime-picker .week-numbers {\n line-height: 30px;\n display: inline-block;\n padding: 30px 0 0 0;\n color: #ddd;\n text-align: right;\n width: 21px;\n vertical-align: top;\n box-sizing: content-box;\n}\n\n.ngui-datetime-picker .days {\n display: inline-block;\n width: 210px; /* 30 x 7 */\n text-align: center;\n padding: 0 10px;\n box-sizing: content-box;\n}\n.ngui-datetime-picker .days .day-of-week,\n.ngui-datetime-picker .days .day {\n box-sizing: border-box;\n border: 1px solid transparent;\n width: 30px;\n line-height: 28px;\n float: left;\n}\n.ngui-datetime-picker .days .day-of-week {\n font-weight: bold;\n}\n.ngui-datetime-picker .days .day-of-week.weekend {\n color: #ccc;\n background-color: inherit;\n}\n.ngui-datetime-picker .days .day:not(.selectable) {\n color: #ccc;\n cursor: default;\n}\n.ngui-datetime-picker .days .weekend {\n color: #ccc;\n background-color: #eee;\n}\n.ngui-datetime-picker .days .day.selectable {\n cursor: pointer;\n}\n.ngui-datetime-picker .days .day.selected {\n background: gray;\n color: #fff;\n}\n.ngui-datetime-picker .days .day:not(.selected).selectable:hover {\n background: #eee;\n}\n.ngui-datetime-picker .days:after {\n content: '';\n display: block;\n clear: left;\n height: 0;\n}\n.ngui-datetime-picker .time {\n position: relative;\n padding: 10px;\n text-transform: Capitalize;\n}\n.ngui-datetime-picker .year-selector {\n position: absolute;\n top: 0;\n left: 0;\n background: #fff;\n height: 100%;\n overflow: auto; \n padding: 5px;\n z-index: 2;\n}\n.ngui-datetime-picker .year-selector .locale{\n text-align: center;\n}\n.ngui-datetime-picker .year-selector .year {\n display: inline-block;\n cursor: pointer;\n padding: 2px 5px;\n}\n.ngui-datetime-picker .year-selector .year:hover {\n background-color: #ddd;\n}\n.ngui-datetime-picker .select-current-time {\n position: absolute;\n top: 1em;\n right: 5px;\n z-index: 1;\n cursor: pointer;\n color: #0000ff;\n}\n.ngui-datetime-picker .hourLabel,\n.ngui-datetime-picker .minutesLabel {\n display: inline-block;\n width: 45px;\n vertical-align: top;\n box-sizing: content-box;\n}\n.closing-layer {\n display: block;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n background: rgba(0,0,0,0);\n}\n\n.ngui-datetime-picker .shortcuts {\n padding: 10px;\n text-align: center;\n}\n\n.ngui-datetime-picker .shortcuts a {\n font-family: Sans-serif;\n margin: 0 0.5em;\n text-decoration: none;\n}\n\n@media (max-width: 767px) {\n .ngui-datetime-picker {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0; \n width: auto !important;\n animation: slideUp 0.1s ease-in-out;\n }\n\n .ngui-datetime-picker > .days {\n display: block;\n margin: 0 auto;\n }\n\n .closing-layer {\n display: block;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n background: rgba(0,0,0,0.2);\n }\n}\n "],"encapsulation":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewEncapsulation"},"member":"None"}}]}],"members":{"dateFormat":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["date-format"]}]}],"dateOnly":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["date-only"]}]}],"timeOnly":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["time-only"]}]}],"selectedDate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["selected-date"]}]}],"hour":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["hour"]}]}],"minute":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["minute"]}]}],"minuteStep":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["minuteStep"]}]}],"defaultValue":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["default-value"]}]}],"minDate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["min-date"]}]}],"maxDate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["max-date"]}]}],"minHour":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["min-hour"]}]}],"maxHour":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["max-hour"]}]}],"disabledDates":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["disabled-dates"]}]}],"showCloseButton":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-close-button"]}]}],"showCloseLayer":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-close-layer"]}]}],"showWeekNumbers":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-week-numbers"]}]}],"showTodayShortcut":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-today-shortcut"]}]}],"showAmPm":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-am-pm"]}]}],"selected$":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"},"arguments":["selected$"]}]}],"closing$":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"},"arguments":["closing$"]}]}],"hours":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild"},"arguments":["hours"]}]}],"minutes":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild"},"arguments":["minutes"]}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ElementRef"},{"__symbolic":"reference","module":"./datetime","name":"NguiDatetime"},{"__symbolic":"reference","module":"@angular/core","name":"ChangeDetectorRef"}]}],"ngOnInit":[{"__symbolic":"method"}],"isWeekend":[{"__symbolic":"method"}],"selectYear":[{"__symbolic":"method"}],"toDate":[{"__symbolic":"method"}],"toDateOnly":[{"__symbolic":"method"}],"selectCurrentTime":[{"__symbolic":"method"}],"selectDateTime":[{"__symbolic":"method"}],"updateMonthData":[{"__symbolic":"method"}],"isDateDisabled":[{"__symbolic":"method"}],"close":[{"__symbolic":"method"}],"selectToday":[{"__symbolic":"method"}],"convertHours":[{"__symbolic":"method"}]}}}} -------------------------------------------------------------------------------- /dist/datetime-picker.directive.d.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFactoryResolver, EventEmitter, OnChanges, OnInit, SimpleChanges, ViewContainerRef } from '@angular/core'; 2 | import { ControlContainer } from '@angular/forms'; 3 | /** 4 | * If the given string is not a valid date, it defaults back to today 5 | */ 6 | export declare class NguiDatetimePickerDirective implements OnInit, OnChanges { 7 | private resolver; 8 | private viewContainerRef; 9 | private parent; 10 | dateFormat: string; 11 | parseFormat: string; 12 | dateOnly: boolean; 13 | timeOnly: boolean; 14 | closeOnSelect: boolean; 15 | defaultValue: Date | string; 16 | minuteStep: number; 17 | minDate: Date | string; 18 | maxDate: Date | string; 19 | minHour: Date | number; 20 | maxHour: Date | number; 21 | disabledDates: Date[]; 22 | showCloseLayer: boolean; 23 | showTodayShortcut: boolean; 24 | showWeekNumbers: boolean; 25 | formControlName: string; 26 | isDraggable: boolean; 27 | ngModel: any; 28 | ngModelChange: EventEmitter<{}>; 29 | valueChanged$: EventEmitter<{}>; 30 | popupClosed$: EventEmitter<{}>; 31 | private el; 32 | private nguiDatetimePickerEl; 33 | private componentRef; 34 | private ctrl; 35 | private sub; 36 | inputEl: HTMLInputElement; 37 | clickedDatetimePicker: boolean; 38 | userModifyingValue: boolean; 39 | constructor(resolver: ComponentFactoryResolver, viewContainerRef: ViewContainerRef, parent: ControlContainer); 40 | /** 41 | * convert defaultValue, minDate, maxDate, minHour, and maxHour to proper types 42 | */ 43 | normalizeInput(): void; 44 | ngOnInit(): void; 45 | ngAfterViewInit(): void; 46 | handleKeyDown: (event: any) => void; 47 | ngOnChanges(changes: SimpleChanges): void; 48 | updateDatepicker(): void; 49 | setInputElDateValue(date: any): void; 50 | ngOnDestroy(): void; 51 | inputElValueChanged: (date: string | Date) => void; 52 | showDatetimePicker: (event?: any) => void; 53 | dateSelected: (date: any) => void; 54 | hideDatetimePicker: (event?: any) => any; 55 | private elementIn(el, containerEl); 56 | private styleDatetimePicker(); 57 | private getDate; 58 | private drag_start; 59 | private drag_over(event); 60 | private drop; 61 | } 62 | -------------------------------------------------------------------------------- /dist/datetime-picker.directive.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var core_1 = require('@angular/core'); 3 | var forms_1 = require('@angular/forms'); 4 | var datetime_picker_component_1 = require('./datetime-picker.component'); 5 | var datetime_1 = require('./datetime'); 6 | function isInteger(value) { 7 | if (Number.isInteger) { 8 | return Number.isInteger(value); 9 | } 10 | return typeof value === "number" && 11 | isFinite(value) && 12 | Math.floor(value) === value; 13 | } 14 | ; 15 | function isNaN(value) { 16 | if (Number.isNaN) { 17 | return Number.isNaN(value); 18 | } 19 | return value !== value; 20 | } 21 | ; 22 | /** 23 | * If the given string is not a valid date, it defaults back to today 24 | */ 25 | var NguiDatetimePickerDirective = (function () { 26 | function NguiDatetimePickerDirective(resolver, viewContainerRef, parent) { 27 | var _this = this; 28 | this.resolver = resolver; 29 | this.viewContainerRef = viewContainerRef; 30 | this.parent = parent; 31 | this.closeOnSelect = true; 32 | this.showTodayShortcut = false; 33 | this.isDraggable = true; 34 | this.ngModelChange = new core_1.EventEmitter(); 35 | this.valueChanged$ = new core_1.EventEmitter(); 36 | this.popupClosed$ = new core_1.EventEmitter(); 37 | this.userModifyingValue = false; 38 | this.handleKeyDown = function (event) { 39 | _this.userModifyingValue = true; 40 | }; 41 | /* input element string value is changed */ 42 | this.inputElValueChanged = function (date) { 43 | _this.setInputElDateValue(date); 44 | _this.el.value = date.toString(); 45 | if (_this.ctrl) { 46 | _this.ctrl.patchValue(_this.el.value); 47 | } 48 | _this.ngModel = _this.el['dateValue']; 49 | if (_this.ngModel) { 50 | _this.ngModel.toString = function () { return _this.el.value; }; 51 | _this.ngModelChange.emit(_this.ngModel); 52 | } 53 | }; 54 | //show datetimePicker element below the current element 55 | this.showDatetimePicker = function (event) { 56 | if (_this.componentRef) { 57 | return; 58 | } 59 | var factory = _this.resolver.resolveComponentFactory(datetime_picker_component_1.NguiDatetimePickerComponent); 60 | _this.componentRef = _this.viewContainerRef.createComponent(factory); 61 | _this.nguiDatetimePickerEl = _this.componentRef.location.nativeElement; 62 | _this.nguiDatetimePickerEl.setAttribute('tabindex', '32767'); 63 | _this.nguiDatetimePickerEl.setAttribute('draggable', String(_this.isDraggable)); 64 | _this.nguiDatetimePickerEl.addEventListener('mousedown', function (event) { 65 | _this.clickedDatetimePicker = true; 66 | }); 67 | _this.nguiDatetimePickerEl.addEventListener('mouseup', function (event) { 68 | _this.clickedDatetimePicker = false; 69 | }); 70 | //This is for material design. MD has click event to make blur to happen 71 | _this.nguiDatetimePickerEl.addEventListener('click', function (event) { 72 | event.stopPropagation(); 73 | }); 74 | _this.nguiDatetimePickerEl.addEventListener('blur', function (event) { 75 | _this.hideDatetimePicker(); 76 | }); 77 | _this.nguiDatetimePickerEl.addEventListener('dragstart', _this.drag_start, false); 78 | document.body.addEventListener('dragover', _this.drag_over, false); 79 | document.body.addEventListener('drop', _this.drop, false); 80 | var component = _this.componentRef.instance; 81 | component.defaultValue = _this.defaultValue || _this.el['dateValue']; 82 | component.dateFormat = _this.dateFormat; 83 | component.dateOnly = _this.dateOnly; 84 | component.timeOnly = _this.timeOnly; 85 | component.minuteStep = _this.minuteStep; 86 | component.minDate = _this.minDate; 87 | component.maxDate = _this.maxDate; 88 | component.minHour = _this.minHour; 89 | component.maxHour = _this.maxHour; 90 | component.disabledDates = _this.disabledDates; 91 | component.showCloseButton = _this.closeOnSelect === false; 92 | component.showCloseLayer = _this.showCloseLayer; 93 | component.showTodayShortcut = _this.showTodayShortcut; 94 | component.showWeekNumbers = _this.showWeekNumbers; 95 | _this.styleDatetimePicker(); 96 | component.selected$.subscribe(_this.dateSelected); 97 | component.closing$.subscribe(function () { 98 | _this.hideDatetimePicker(); 99 | }); 100 | //Hack not to fire tab keyup event 101 | // this.justShown = true; 102 | // setTimeout(() => this.justShown = false, 100); 103 | }; 104 | this.dateSelected = function (date) { 105 | _this.el.tagName === 'INPUT' && _this.inputElValueChanged(date); 106 | _this.valueChanged$.emit(date); 107 | if (_this.closeOnSelect !== false) { 108 | _this.hideDatetimePicker(); 109 | } 110 | else { 111 | _this.nguiDatetimePickerEl.focus(); 112 | } 113 | }; 114 | this.hideDatetimePicker = function (event) { 115 | if (_this.clickedDatetimePicker) { 116 | return false; 117 | } 118 | else { 119 | setTimeout(function () { 120 | if (_this.componentRef) { 121 | _this.componentRef.destroy(); 122 | _this.componentRef = undefined; 123 | } 124 | _this.popupClosed$.emit(true); 125 | }); 126 | } 127 | event && event.stopPropagation(); 128 | }; 129 | this.getDate = function (arg) { 130 | var date = arg; 131 | if (typeof arg === 'string') { 132 | date = datetime_1.NguiDatetime.parseDate(arg, _this.parseFormat, _this.dateFormat); 133 | } 134 | return date; 135 | }; 136 | this.drag_start = function (event) { 137 | if (document.activeElement.tagName == 'INPUT') { 138 | event.preventDefault(); 139 | return false; // block dragging 140 | } 141 | var style = window.getComputedStyle(event.target, null); 142 | event.dataTransfer.setData("text/plain", (parseInt(style.getPropertyValue("left"), 10) - event.clientX) 143 | + ',' 144 | + (parseInt(style.getPropertyValue("top"), 10) - event.clientY)); 145 | }; 146 | this.drop = function (event) { 147 | var offset = event.dataTransfer.getData("text/plain").split(','); 148 | _this.nguiDatetimePickerEl.style.left = (event.clientX + parseInt(offset[0], 10)) + 'px'; 149 | _this.nguiDatetimePickerEl.style.top = (event.clientY + parseInt(offset[1], 10)) + 'px'; 150 | _this.nguiDatetimePickerEl.style.bottom = ''; 151 | event.preventDefault(); 152 | return false; 153 | }; 154 | this.el = this.viewContainerRef.element.nativeElement; 155 | } 156 | /** 157 | * convert defaultValue, minDate, maxDate, minHour, and maxHour to proper types 158 | */ 159 | NguiDatetimePickerDirective.prototype.normalizeInput = function () { 160 | if (this.defaultValue && typeof this.defaultValue === 'string') { 161 | var d = datetime_1.NguiDatetime.parseDate(this.defaultValue); 162 | this.defaultValue = isNaN(d.getTime()) ? new Date() : d; 163 | } 164 | if (this.minDate && typeof this.minDate == 'string') { 165 | var d = datetime_1.NguiDatetime.parseDate(this.minDate); 166 | this.minDate = isNaN(d.getTime()) ? new Date() : d; 167 | } 168 | if (this.maxDate && typeof this.maxDate == 'string') { 169 | var d = datetime_1.NguiDatetime.parseDate(this.maxDate); 170 | this.maxDate = isNaN(d.getTime()) ? new Date() : d; 171 | } 172 | if (this.minHour) { 173 | if (this.minHour instanceof Date) { 174 | this.minHour = this.minHour.getHours(); 175 | } 176 | else { 177 | var hour = Number(this.minHour.toString()); 178 | if (!isInteger(hour) || hour > 23 || hour < 0) { 179 | this.minHour = undefined; 180 | } 181 | } 182 | } 183 | if (this.maxHour) { 184 | if (this.maxHour instanceof Date) { 185 | this.maxHour = this.maxHour.getHours(); 186 | } 187 | else { 188 | var hour = Number(this.maxHour.toString()); 189 | if (!isInteger(hour) || hour > 23 || hour < 0) { 190 | this.maxHour = undefined; 191 | } 192 | } 193 | } 194 | }; 195 | NguiDatetimePickerDirective.prototype.ngOnInit = function () { 196 | var _this = this; 197 | if (this.parent && this.formControlName) { 198 | if (this.parent["form"]) { 199 | this.ctrl = this.parent["form"].get(this.formControlName); 200 | } 201 | else if (this.parent["name"]) { 202 | var formDir = this.parent.formDirective; 203 | if (formDir instanceof forms_1.FormGroupDirective && formDir.form.get(this.parent["name"])) { 204 | this.ctrl = formDir.form.get(this.parent["name"]).get(this.formControlName); 205 | } 206 | } 207 | if (this.ctrl) { 208 | this.sub = this.ctrl.valueChanges.subscribe(function (date) { 209 | _this.setInputElDateValue(date); 210 | _this.updateDatepicker(); 211 | }); 212 | } 213 | } 214 | this.normalizeInput(); 215 | //wrap this element with a
tag, so that we can position dynamic element correctly 216 | var wrapper = document.createElement("div"); 217 | wrapper.className = 'ngui-datetime-picker-wrapper'; 218 | this.el.parentElement.insertBefore(wrapper, this.el.nextSibling); 219 | wrapper.appendChild(this.el); 220 | if (this.ngModel && this.ngModel.getTime) { 221 | this.ngModel.toString = function () { return datetime_1.NguiDatetime.formatDate(_this.ngModel, _this.dateFormat, _this.dateOnly); }; 222 | } 223 | setTimeout(function () { 224 | if (_this.el.tagName === 'INPUT') { 225 | _this.inputElValueChanged(_this.el.value); //set this.el.dateValue and reformat this.el.value 226 | } 227 | if (_this.ctrl) { 228 | _this.ctrl.markAsPristine(); 229 | } 230 | }); 231 | }; 232 | NguiDatetimePickerDirective.prototype.ngAfterViewInit = function () { 233 | // if this element is not an input tag, move dropdown after input tag 234 | // so that it displays correctly 235 | this.inputEl = this.el.tagName === "INPUT" ? 236 | this.el : this.el.querySelector("input"); 237 | if (this.inputEl) { 238 | this.inputEl.addEventListener('focus', this.showDatetimePicker); 239 | this.inputEl.addEventListener('blur', this.hideDatetimePicker); 240 | this.inputEl.addEventListener('keydown', this.handleKeyDown); 241 | } 242 | }; 243 | NguiDatetimePickerDirective.prototype.ngOnChanges = function (changes) { 244 | var _this = this; 245 | var date; 246 | if (changes && changes['ngModel']) { 247 | date = changes['ngModel'].currentValue; 248 | if (date && typeof date !== 'string') { 249 | date.toString = function () { return datetime_1.NguiDatetime.formatDate(date, _this.dateFormat, _this.dateOnly); }; 250 | this.setInputElDateValue(date); 251 | this.updateDatepicker(); 252 | } 253 | else if (date && typeof date === 'string') { 254 | /** if program assigns a string value, then format to date later */ 255 | if (!this.userModifyingValue) { 256 | setTimeout(function () { 257 | var dt = _this.getDate(date); 258 | dt.toString = function () { return datetime_1.NguiDatetime.formatDate(dt, _this.dateFormat, _this.dateOnly); }; 259 | _this.ngModel = dt; 260 | _this.inputEl.value = '' + dt; 261 | }); 262 | } 263 | } 264 | } 265 | this.userModifyingValue = false; 266 | }; 267 | NguiDatetimePickerDirective.prototype.updateDatepicker = function () { 268 | if (this.componentRef) { 269 | var component = this.componentRef.instance; 270 | component.defaultValue = this.el['dateValue']; 271 | } 272 | }; 273 | NguiDatetimePickerDirective.prototype.setInputElDateValue = function (date) { 274 | if (typeof date === 'string' && date) { 275 | this.el['dateValue'] = this.getDate(date); 276 | } 277 | else if (typeof date === 'object') { 278 | this.el['dateValue'] = date; 279 | } 280 | else if (typeof date === 'undefined') { 281 | this.el['dateValue'] = null; 282 | } 283 | if (this.ctrl) { 284 | this.ctrl.markAsDirty(); 285 | } 286 | }; 287 | NguiDatetimePickerDirective.prototype.ngOnDestroy = function () { 288 | if (this.sub) { 289 | this.sub.unsubscribe(); 290 | } 291 | }; 292 | NguiDatetimePickerDirective.prototype.elementIn = function (el, containerEl) { 293 | while (el = el.parentNode) { 294 | if (el === containerEl) 295 | return true; 296 | } 297 | return false; 298 | }; 299 | NguiDatetimePickerDirective.prototype.styleDatetimePicker = function () { 300 | var _this = this; 301 | // setting position, width, and height of auto complete dropdown 302 | var thisElBCR = this.el.getBoundingClientRect(); 303 | // this.nguiDatetimePickerEl.style.minWidth = thisElBCR.width + 'px'; 304 | this.nguiDatetimePickerEl.style.position = 'absolute'; 305 | this.nguiDatetimePickerEl.style.zIndex = '1000'; 306 | this.nguiDatetimePickerEl.style.left = '0'; 307 | this.nguiDatetimePickerEl.style.transition = 'height 0.3s ease-in'; 308 | this.nguiDatetimePickerEl.style.visibility = 'hidden'; 309 | setTimeout(function () { 310 | var thisElBcr = _this.el.getBoundingClientRect(); 311 | var nguiDatetimePickerElBcr = _this.nguiDatetimePickerEl.getBoundingClientRect(); 312 | if (thisElBcr.bottom + nguiDatetimePickerElBcr.height > window.innerHeight) { 313 | _this.nguiDatetimePickerEl.style.bottom = 314 | (thisElBcr.bottom - window.innerHeight + 15) + 'px'; 315 | } 316 | else { 317 | // otherwise, show below 318 | _this.nguiDatetimePickerEl.style.top = thisElBcr.height + 'px'; 319 | } 320 | _this.nguiDatetimePickerEl.style.visibility = 'visible'; 321 | }); 322 | }; 323 | ; 324 | NguiDatetimePickerDirective.prototype.drag_over = function (event) { 325 | event.preventDefault(); 326 | return false; 327 | }; 328 | NguiDatetimePickerDirective.decorators = [ 329 | { type: core_1.Directive, args: [{ 330 | selector: '[ngui-datetime-picker]', 331 | providers: [datetime_1.NguiDatetime] 332 | },] }, 333 | ]; 334 | /** @nocollapse */ 335 | NguiDatetimePickerDirective.ctorParameters = [ 336 | { type: core_1.ComponentFactoryResolver, }, 337 | { type: core_1.ViewContainerRef, }, 338 | { type: forms_1.ControlContainer, decorators: [{ type: core_1.Optional }, { type: core_1.Host }, { type: core_1.SkipSelf },] }, 339 | ]; 340 | NguiDatetimePickerDirective.propDecorators = { 341 | 'dateFormat': [{ type: core_1.Input, args: ['date-format',] },], 342 | 'parseFormat': [{ type: core_1.Input, args: ['parse-format',] },], 343 | 'dateOnly': [{ type: core_1.Input, args: ['date-only',] },], 344 | 'timeOnly': [{ type: core_1.Input, args: ['time-only',] },], 345 | 'closeOnSelect': [{ type: core_1.Input, args: ['close-on-select',] },], 346 | 'defaultValue': [{ type: core_1.Input, args: ['default-value',] },], 347 | 'minuteStep': [{ type: core_1.Input, args: ['minute-step',] },], 348 | 'minDate': [{ type: core_1.Input, args: ['min-date',] },], 349 | 'maxDate': [{ type: core_1.Input, args: ['max-date',] },], 350 | 'minHour': [{ type: core_1.Input, args: ['min-hour',] },], 351 | 'maxHour': [{ type: core_1.Input, args: ['max-hour',] },], 352 | 'disabledDates': [{ type: core_1.Input, args: ['disabled-dates',] },], 353 | 'showCloseLayer': [{ type: core_1.Input, args: ['show-close-layer',] },], 354 | 'showTodayShortcut': [{ type: core_1.Input, args: ['show-today-shortcut',] },], 355 | 'showWeekNumbers': [{ type: core_1.Input, args: ['show-week-numbers',] },], 356 | 'formControlName': [{ type: core_1.Input },], 357 | 'isDraggable': [{ type: core_1.Input, args: ['is-draggable',] },], 358 | 'ngModel': [{ type: core_1.Input, args: ['ngModel',] },], 359 | 'ngModelChange': [{ type: core_1.Output, args: ['ngModelChange',] },], 360 | 'valueChanged$': [{ type: core_1.Output, args: ['valueChanged',] },], 361 | 'popupClosed$': [{ type: core_1.Output, args: ['popupClosed',] },], 362 | }; 363 | return NguiDatetimePickerDirective; 364 | }()); 365 | exports.NguiDatetimePickerDirective = NguiDatetimePickerDirective; 366 | //# sourceMappingURL=datetime-picker.directive.js.map -------------------------------------------------------------------------------- /dist/datetime-picker.directive.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"datetime-picker.directive.js","sourceRoot":"","sources":["../src/datetime-picker.directive.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/datetime-picker.directive.metadata.json: -------------------------------------------------------------------------------- 1 | {"__symbolic":"module","version":1,"metadata":{"NguiDatetimePickerDirective":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Directive"},"arguments":[{"selector":"[ngui-datetime-picker]","providers":[{"__symbolic":"reference","module":"./datetime","name":"NguiDatetime"}]}]}],"members":{"dateFormat":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["date-format"]}]}],"parseFormat":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["parse-format"]}]}],"dateOnly":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["date-only"]}]}],"timeOnly":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["time-only"]}]}],"closeOnSelect":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["close-on-select"]}]}],"defaultValue":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["default-value"]}]}],"minuteStep":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["minute-step"]}]}],"minDate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["min-date"]}]}],"maxDate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["max-date"]}]}],"minHour":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["min-hour"]}]}],"maxHour":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["max-hour"]}]}],"disabledDates":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["disabled-dates"]}]}],"showCloseLayer":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-close-layer"]}]}],"showTodayShortcut":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-today-shortcut"]}]}],"showWeekNumbers":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["show-week-numbers"]}]}],"formControlName":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"isDraggable":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["is-draggable"]}]}],"ngModel":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"},"arguments":["ngModel"]}]}],"ngModelChange":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"},"arguments":["ngModelChange"]}]}],"valueChanged$":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"},"arguments":["valueChanged"]}]}],"popupClosed$":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"},"arguments":["popupClosed"]}]}],"__ctor__":[{"__symbolic":"constructor","parameterDecorators":[null,null,[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Optional"}},{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Host"}},{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"SkipSelf"}}]],"parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ComponentFactoryResolver"},{"__symbolic":"reference","module":"@angular/core","name":"ViewContainerRef"},{"__symbolic":"reference","module":"@angular/forms","name":"ControlContainer"}]}],"normalizeInput":[{"__symbolic":"method"}],"ngOnInit":[{"__symbolic":"method"}],"ngAfterViewInit":[{"__symbolic":"method"}],"ngOnChanges":[{"__symbolic":"method"}],"updateDatepicker":[{"__symbolic":"method"}],"setInputElDateValue":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}],"elementIn":[{"__symbolic":"method"}],"styleDatetimePicker":[{"__symbolic":"method"}],"drag_over":[{"__symbolic":"method"}]}}}} -------------------------------------------------------------------------------- /dist/datetime-picker.module.d.ts: -------------------------------------------------------------------------------- 1 | export declare class NguiDatetimePickerModule { 2 | } 3 | -------------------------------------------------------------------------------- /dist/datetime-picker.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var core_1 = require('@angular/core'); 3 | var forms_1 = require("@angular/forms"); 4 | var common_1 = require('@angular/common'); 5 | var datetime_1 = require('./datetime'); 6 | var datetime_picker_component_1 = require('./datetime-picker.component'); 7 | var datetime_picker_directive_1 = require('./datetime-picker.directive'); 8 | var NguiDatetimePickerModule = (function () { 9 | function NguiDatetimePickerModule() { 10 | } 11 | NguiDatetimePickerModule.decorators = [ 12 | { type: core_1.NgModule, args: [{ 13 | imports: [common_1.CommonModule, forms_1.FormsModule], 14 | declarations: [datetime_picker_component_1.NguiDatetimePickerComponent, datetime_picker_directive_1.NguiDatetimePickerDirective], 15 | exports: [datetime_picker_component_1.NguiDatetimePickerComponent, datetime_picker_directive_1.NguiDatetimePickerDirective], 16 | entryComponents: [datetime_picker_component_1.NguiDatetimePickerComponent], 17 | providers: [datetime_1.NguiDatetime] 18 | },] }, 19 | ]; 20 | /** @nocollapse */ 21 | NguiDatetimePickerModule.ctorParameters = []; 22 | return NguiDatetimePickerModule; 23 | }()); 24 | exports.NguiDatetimePickerModule = NguiDatetimePickerModule; 25 | //# sourceMappingURL=datetime-picker.module.js.map -------------------------------------------------------------------------------- /dist/datetime-picker.module.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"datetime-picker.module.js","sourceRoot":"","sources":["../src/datetime-picker.module.ts"],"names":[],"mappings":";AAAA,qBAAyB,eAAe,CAAC,CAAA;AACzC,sBAA4B,gBAAgB,CAAC,CAAA;AAC7C,uBAA8B,iBAAiB,CAAC,CAAA;AAEhD,yBAA6B,YAAY,CAAC,CAAA;AAC1C,0CAA4C,6BAA6B,CAAC,CAAA;AAC1E,0CAA4C,6BAA6B,CAAC,CAAA;AAG1E;IAAA;IAYA,CAAC;IAZ6C,mCAAU,GAA0B;QAClF,EAAE,IAAI,EAAE,eAAQ,EAAE,IAAI,EAAE,CAAC;oBACvB,OAAO,EAAE,CAAE,qBAAY,EAAE,mBAAW,CAAE;oBACtC,YAAY,EAAE,CAAC,uDAA2B,EAAE,uDAA2B,CAAC;oBACxE,OAAO,EAAG,CAAC,uDAA2B,EAAE,uDAA2B,CAAC;oBACpE,eAAe,EAAE,CAAC,uDAA2B,CAAC;oBAC9C,SAAS,EAAE,CAAE,uBAAY,CAAE;iBAC5B,EAAG,EAAE;KACL,CAAC;IACF,kBAAkB;IACX,uCAAc,GAA6D,EACjF,CAAC;IACF,+BAAC;AAAD,CAAC,AAZD,IAYC;AAZY,gCAAwB,2BAYpC,CAAA"} -------------------------------------------------------------------------------- /dist/datetime-picker.module.metadata.json: -------------------------------------------------------------------------------- 1 | {"__symbolic":"module","version":1,"metadata":{"NguiDatetimePickerModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule"},"arguments":[{"imports":[{"__symbolic":"reference","module":"@angular/common","name":"CommonModule"},{"__symbolic":"reference","module":"@angular/forms","name":"FormsModule"}],"declarations":[{"__symbolic":"reference","module":"./datetime-picker.component","name":"NguiDatetimePickerComponent"},{"__symbolic":"reference","module":"./datetime-picker.directive","name":"NguiDatetimePickerDirective"}],"exports":[{"__symbolic":"reference","module":"./datetime-picker.component","name":"NguiDatetimePickerComponent"},{"__symbolic":"reference","module":"./datetime-picker.directive","name":"NguiDatetimePickerDirective"}],"entryComponents":[{"__symbolic":"reference","module":"./datetime-picker.component","name":"NguiDatetimePickerComponent"}],"providers":[{"__symbolic":"reference","module":"./datetime","name":"NguiDatetime"}]}]}]}}} -------------------------------------------------------------------------------- /dist/datetime.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Static variables that you can override 3 | * 1. days. default 1,2,....31 4 | * 2. daysOfWeek, default Sunday, Monday, ..... 5 | * 3. firstDayOfWeek, default 0 as in Sunday 6 | * 4. months, default January, February 7 | * 5. formatDate(d) default returns YYYY-MM-DD HH:MM 8 | * 6. parseDate(str) default returns date from YYYY-MM-DD HH:MM 9 | */ 10 | export declare class NguiDatetime { 11 | static locale: any; 12 | static days: number[]; 13 | static weekends: number[]; 14 | static daysOfWeek: any[]; 15 | static firstDayOfWeek: number; 16 | static months: any[]; 17 | static formatDate(d: Date, format?: string, dateOnly?: boolean): string; 18 | static parseDate(dateStr: string, parseFormat?: string, dateFormat?: string): Date; 19 | static getWeekNumber(date: any): number; 20 | private static removeTimezone(dateStr); 21 | private static addDSTOffset(dateStr); 22 | private static parseFromDefaultFormat(dateStr); 23 | getMonthData(year: number, month: number): any; 24 | } 25 | -------------------------------------------------------------------------------- /dist/datetime.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var core_1 = require("@angular/core"); 3 | /** 4 | * Static variables that you can override 5 | * 1. days. default 1,2,....31 6 | * 2. daysOfWeek, default Sunday, Monday, ..... 7 | * 3. firstDayOfWeek, default 0 as in Sunday 8 | * 4. months, default January, February 9 | * 5. formatDate(d) default returns YYYY-MM-DD HH:MM 10 | * 6. parseDate(str) default returns date from YYYY-MM-DD HH:MM 11 | */ 12 | var NguiDatetime = (function () { 13 | function NguiDatetime() { 14 | } 15 | NguiDatetime.formatDate = function (d, format, dateOnly) { 16 | var ret; 17 | if (d && !format) { 18 | // return d.toLocaleString('en-us', hash); // IE11 does not understand this 19 | var pad0 = function (number) { return ("0" + number).slice(-2); }; 20 | ret = d.getFullYear() + '-' + pad0(d.getMonth() + 1) + '-' + pad0(d.getDate()); 21 | ret += dateOnly ? '' : ' ' + pad0(d.getHours()) + ':' + pad0(d.getMinutes()); 22 | return ret; 23 | } 24 | else if (d && typeof moment !== 'undefined') { 25 | return moment(d).format(format); 26 | } 27 | else { 28 | return ''; 29 | } 30 | }; 31 | NguiDatetime.parseDate = function (dateStr, parseFormat, dateFormat) { 32 | if (typeof moment === 'undefined') { 33 | dateStr = NguiDatetime.removeTimezone(dateStr); 34 | dateStr = dateStr + NguiDatetime.addDSTOffset(dateStr); 35 | return NguiDatetime.parseFromDefaultFormat(dateStr); 36 | } 37 | else if (dateFormat || parseFormat) { 38 | // try parse using each format because changing format programmatically calls this twice, 39 | // once with string in parse format and once in date format 40 | var formats = []; 41 | if (parseFormat) { 42 | formats.push(parseFormat); 43 | } 44 | if (dateFormat) { 45 | formats.push(dateFormat); 46 | } 47 | var m = moment(dateStr, formats); 48 | var date = m.toDate(); 49 | if (!m.isValid()) { 50 | date = moment(dateStr, moment.ISO_8601).toDate(); // parse as ISO format 51 | } 52 | return date; 53 | } 54 | else if (dateStr.length > 4) { 55 | var date = moment(dateStr, 'YYYY-MM-DD HH:mm').toDate(); 56 | return date; 57 | } 58 | else { 59 | return new Date(); 60 | } 61 | }; 62 | NguiDatetime.getWeekNumber = function (date) { 63 | if (!(date instanceof Date)) 64 | date = new Date(); 65 | // ISO week date weeks start on Monday, so correct the day number 66 | var nDay = (date.getDay() + 6) % 7; 67 | // ISO 8601 states that week 1 is the week with the first Thursday of that year 68 | // Set the target date to the Thursday in the target week 69 | date.setDate(date.getDate() - nDay + 3); 70 | // Store the millisecond value of the target date 71 | var n1stThursday = date.valueOf(); 72 | // Set the target to the first Thursday of the year 73 | // First, set the target to January 1st 74 | date.setMonth(0, 1); 75 | // Not a Thursday? Correct the date to the next Thursday 76 | if (date.getDay() !== 4) { 77 | date.setMonth(0, 1 + ((4 - date.getDay()) + 7) % 7); 78 | } 79 | // The week number is the number of weeks between the first Thursday of the year 80 | // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000) 81 | return 1 + Math.ceil((n1stThursday - date) / 604800000); 82 | }; 83 | //remove timezone 84 | NguiDatetime.removeTimezone = function (dateStr) { 85 | // if no time is given, add 00:00:00 at the end 86 | var matches = dateStr.match(/[0-9]{2}:/); 87 | dateStr += matches ? '' : ' 00:00:00'; 88 | return dateStr.replace(/([0-9]{2}-[0-9]{2})-([0-9]{4})/, '$2-$1') //mm-dd-yyyy to yyyy-mm-dd 89 | .replace(/([\/-][0-9]{2,4})\ ([0-9]{2}\:[0-9]{2}\:)/, '$1T$2') //reformat for FF 90 | .replace(/EDT|EST|CDT|CST|MDT|PDT|PST|UT|GMT/g, '') //remove timezone 91 | .replace(/\s*\(\)\s*/, '') //remove timezone 92 | .replace(/[\-\+][0-9]{2}:?[0-9]{2}$/, '') //remove timezone 93 | .replace(/000Z$/, '00'); //remove timezone 94 | }; 95 | NguiDatetime.addDSTOffset = function (dateStr) { 96 | var date = NguiDatetime.parseFromDefaultFormat(dateStr); 97 | var jan = new Date(date.getFullYear(), 0, 1); 98 | var jul = new Date(date.getFullYear(), 6, 1); 99 | var stdTimezoneOffset = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); 100 | var isDST = date.getTimezoneOffset() < stdTimezoneOffset; 101 | var offset = isDST ? stdTimezoneOffset - 60 : stdTimezoneOffset; 102 | var diff = offset >= 0 ? '-' : '+'; 103 | offset = Math.abs(offset); 104 | return diff + 105 | ('0' + (offset / 60)).slice(-2) + ':' + 106 | ('0' + (offset % 60)).slice(-2); 107 | }; 108 | ; 109 | NguiDatetime.parseFromDefaultFormat = function (dateStr) { 110 | var tmp = dateStr.split(/[\+\-:\ T]/); // split by dash, colon or space 111 | return new Date(parseInt(tmp[0], 10), parseInt(tmp[1], 10) - 1, parseInt(tmp[2], 10), parseInt(tmp[3] || '0', 10), parseInt(tmp[4] || '0', 10), parseInt(tmp[5] || '0', 10)); 112 | }; 113 | NguiDatetime.prototype.getMonthData = function (year, month) { 114 | year = month > 11 ? year + 1 : 115 | month < 0 ? year - 1 : year; 116 | month = (month + 12) % 12; 117 | var firstDayOfMonth = new Date(year, month, 1); 118 | var lastDayOfMonth = new Date(year, month + 1, 0); 119 | var lastDayOfPreviousMonth = new Date(year, month, 0); 120 | var daysInMonth = lastDayOfMonth.getDate(); 121 | var daysInLastMonth = lastDayOfPreviousMonth.getDate(); 122 | var dayOfWeek = firstDayOfMonth.getDay(); 123 | // Ensure there are always leading days to give context 124 | var leadingDays = (dayOfWeek - NguiDatetime.firstDayOfWeek + 7) % 7 || 7; 125 | var trailingDays = NguiDatetime.days.slice(0, 6 * 7 - (leadingDays + daysInMonth)); 126 | if (trailingDays.length > 7) { 127 | trailingDays = trailingDays.slice(0, trailingDays.length - 7); 128 | } 129 | var firstDay = new Date(firstDayOfMonth); 130 | firstDay.setDate(firstDayOfMonth.getDate() - (leadingDays % 7)); 131 | var firstWeekNumber = NguiDatetime.getWeekNumber(firstDay); 132 | var numWeeks = Math.ceil((daysInMonth + leadingDays % 7) / 7); 133 | var weekNumbers = Array(numWeeks).fill(0).map(function (el, ndx) { 134 | var weekNum = (ndx + firstWeekNumber + 52) % 52; 135 | return weekNum === 0 ? 52 : weekNum; 136 | }); 137 | var localizedDaysOfWeek = NguiDatetime.daysOfWeek 138 | .concat(NguiDatetime.daysOfWeek) 139 | .splice(NguiDatetime.firstDayOfWeek, 7); 140 | var monthData = { 141 | year: year, 142 | month: month, 143 | weekends: NguiDatetime.weekends, 144 | firstDayOfWeek: NguiDatetime.firstDayOfWeek, 145 | fullName: NguiDatetime.months[month].fullName, 146 | shortName: NguiDatetime.months[month].shortName, 147 | localizedDaysOfWeek: localizedDaysOfWeek, 148 | days: NguiDatetime.days.slice(0, daysInMonth), 149 | leadingDays: NguiDatetime.days.slice(-leadingDays - (31 - daysInLastMonth), daysInLastMonth), 150 | trailingDays: trailingDays, 151 | weekNumbers: weekNumbers 152 | }; 153 | return monthData; 154 | }; 155 | NguiDatetime.locale = { 156 | date: 'date', 157 | time: 'time', 158 | year: 'year', 159 | month: 'month', 160 | day: 'day', 161 | hour: 'hour', 162 | minute: 'minute', 163 | currentTime: "current time" 164 | }; 165 | NguiDatetime.days = [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]; 166 | NguiDatetime.weekends = [0, 6]; 167 | NguiDatetime.daysOfWeek = typeof moment === 'undefined' ? [ 168 | { fullName: 'Sunday', shortName: 'Su' }, 169 | { fullName: 'Monday', shortName: 'Mo' }, 170 | { fullName: 'Tuesday', shortName: 'Tu' }, 171 | { fullName: 'Wednesday', shortName: 'We' }, 172 | { fullName: 'Thursday', shortName: 'Th' }, 173 | { fullName: 'Friday', shortName: 'Fr' }, 174 | { fullName: 'Saturday', shortName: 'Sa' } 175 | ] : moment.weekdays().map(function (el, index) { 176 | return { 177 | fullName: el, 178 | shortName: moment.weekdaysShort()[index].substr(0, 2) 179 | }; 180 | }); 181 | NguiDatetime.firstDayOfWeek = typeof moment === 'undefined' ? 0 : moment.localeData().firstDayOfWeek(); 182 | NguiDatetime.months = typeof moment === 'undefined' ? [ 183 | { fullName: 'January', shortName: 'Jan' }, 184 | { fullName: 'February', shortName: 'Feb' }, 185 | { fullName: 'March', shortName: 'Mar' }, 186 | { fullName: 'April', shortName: 'Apr' }, 187 | { fullName: 'May', shortName: 'May' }, 188 | { fullName: 'June', shortName: 'Jun' }, 189 | { fullName: 'July', shortName: 'Jul' }, 190 | { fullName: 'August', shortName: 'Aug' }, 191 | { fullName: 'September', shortName: 'Sep' }, 192 | { fullName: 'October', shortName: 'Oct' }, 193 | { fullName: 'November', shortName: 'Nov' }, 194 | { fullName: 'December', shortName: 'Dec' } 195 | ] : moment.months().map(function (el, index) { 196 | return { 197 | fullName: el, 198 | shortName: moment['monthsShort']()[index] 199 | }; 200 | }); 201 | NguiDatetime.decorators = [ 202 | { type: core_1.Injectable }, 203 | ]; 204 | /** @nocollapse */ 205 | NguiDatetime.ctorParameters = []; 206 | return NguiDatetime; 207 | }()); 208 | exports.NguiDatetime = NguiDatetime; 209 | //# sourceMappingURL=datetime.js.map -------------------------------------------------------------------------------- /dist/datetime.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"datetime.js","sourceRoot":"","sources":["../src/datetime.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/datetime.metadata.json: -------------------------------------------------------------------------------- 1 | {"__symbolic":"module","version":1,"metadata":{"NguiDatetime":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable"}}],"members":{"getMonthData":[{"__symbolic":"method"}]},"statics":{"locale":{"date":"date","time":"time","year":"year","month":"month","day":"day","hour":"hour","minute":"minute","currentTime":"current time"},"days":[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],"weekends":[0,6],"daysOfWeek":{"__symbolic":"if","condition":{"__symbolic":"binop","operator":"===","left":{"__symbolic":"error","message":"Expression form not supported","line":33,"character":4},"right":"undefined"},"thenExpression":[{"fullName":"Sunday","shortName":"Su"},{"fullName":"Monday","shortName":"Mo"},{"fullName":"Tuesday","shortName":"Tu"},{"fullName":"Wednesday","shortName":"We"},{"fullName":"Thursday","shortName":"Th"},{"fullName":"Friday","shortName":"Fr"},{"fullName":"Saturday","shortName":"Sa"}],"elseExpression":{"__symbolic":"error","message":"Function call not supported","line":41,"character":30}},"firstDayOfWeek":{"__symbolic":"if","condition":{"__symbolic":"binop","operator":"===","left":{"__symbolic":"error","message":"Expression form not supported","line":49,"character":4},"right":"undefined"},"thenExpression":0,"elseExpression":{"__symbolic":"error","message":"Reference to a local symbol","line":0,"character":12,"context":{"name":"moment"}}},"months":{"__symbolic":"if","condition":{"__symbolic":"binop","operator":"===","left":{"__symbolic":"error","message":"Expression form not supported","line":51,"character":25},"right":"undefined"},"thenExpression":[{"fullName":"January","shortName":"Jan"},{"fullName":"February","shortName":"Feb"},{"fullName":"March","shortName":"Mar"},{"fullName":"April","shortName":"Apr"},{"fullName":"May","shortName":"May"},{"fullName":"June","shortName":"Jun"},{"fullName":"July","shortName":"Jul"},{"fullName":"August","shortName":"Aug"},{"fullName":"September","shortName":"Sep"},{"fullName":"October","shortName":"Oct"},{"fullName":"November","shortName":"Nov"},{"fullName":"December","shortName":"Dec"}],"elseExpression":{"__symbolic":"error","message":"Function call not supported","line":64,"character":26}}}}}} -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import { NguiDatetime } from './datetime'; 2 | import { NguiDatetimePickerComponent } from './datetime-picker.component'; 3 | import { NguiDatetimePickerDirective } from './datetime-picker.directive'; 4 | import { NguiDatetimePickerModule } from './datetime-picker.module'; 5 | export { NguiDatetime, NguiDatetimePickerComponent, NguiDatetimePickerDirective, NguiDatetimePickerModule }; 6 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var datetime_1 = require('./datetime'); 3 | exports.NguiDatetime = datetime_1.NguiDatetime; 4 | var datetime_picker_component_1 = require('./datetime-picker.component'); 5 | exports.NguiDatetimePickerComponent = datetime_picker_component_1.NguiDatetimePickerComponent; 6 | var datetime_picker_directive_1 = require('./datetime-picker.directive'); 7 | exports.NguiDatetimePickerDirective = datetime_picker_directive_1.NguiDatetimePickerDirective; 8 | var datetime_picker_module_1 = require('./datetime-picker.module'); 9 | exports.NguiDatetimePickerModule = datetime_picker_module_1.NguiDatetimePickerModule; 10 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,yBAA6B,YAAY,CAAC,CAAA;AAMxC,oBAAY;AALd,0CAA4C,6BAA6B,CAAC,CAAA;AAMxE,mCAA2B;AAL7B,0CAA4C,6BAA6B,CAAC,CAAA;AAMxE,mCAA2B;AAL7B,uCAAyC,0BAA0B,CAAC,CAAA;AAMlE,gCAAwB;AACzB"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ngui/datetime-picker", 3 | "version": "0.16.2", 4 | "description": "Angular2 DateTime Picker", 5 | "license": "ISC", 6 | "main": "dist/datetime-picker.umd.js", 7 | "module": "dist/index.js", 8 | "typings": "dist/index.d.ts", 9 | "scripts": { 10 | "start": "webpack-dev-server --quiet --port 9002 --content-base app --config app/webpack.config --open", 11 | "lint": "tslint 'src/**/*.ts' 'app/**/*.ts'", 12 | "clean": "rimraf dist", 13 | "build": "npm-run-all --serial clean build:ngc build:umd build:app", 14 | "build:ngc": "ngc -p tsconfig.ngc.json", 15 | "build:umd": "NODE_ENV=prod webpack", 16 | "build:app": "NODE_ENV=prod webpack --config app/webpack.config", 17 | "test": "npm-run-all --serial test:start test:webtest test:stop", 18 | "test:start": "forever start --silent node_modules/.bin/webpack-dev-server --quiet --port 9002 --content-base app --config app/webpack.config", 19 | "test:stop": "forever stop node_modules/.bin/webpack-dev-server --quiet --port 9002 --content-base app --config app/webpack.config", 20 | "test:webtest": "webtest webtest.txt", 21 | "upgrade": "npm-check-updates -a/--upgradeAll && npm i" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/ng2-ui/datetime-picker.git" 26 | }, 27 | "author": "", 28 | "bugs": { 29 | "url": "https://github.com/ng2-ui/datetime-picker/issues" 30 | }, 31 | "homepage": "https://github.com/ng2-ui/datetime-picker#readme", 32 | "dependencies": {}, 33 | "devDependencies": { 34 | "@angular/common": "2.2.2", 35 | "@angular/compiler": "2.2.2", 36 | "@angular/compiler-cli": "^2.2.4", 37 | "@angular/core": "2.2.2", 38 | "@angular/forms": "2.2.2", 39 | "@angular/http": "2.2.2", 40 | "@angular/material": "^2.0.0-beta.2", 41 | "@angular/platform-browser": "2.2.2", 42 | "@angular/platform-browser-dynamic": "2.2.2", 43 | "@angular/router": "3.2.2", 44 | "@angular/upgrade": "2.2.2", 45 | "@types/google-maps": "^3.1.27", 46 | "@types/hammerjs": "^2.0.34", 47 | "@types/node": "^6.0.31", 48 | "angular2-template-loader": "^0.5.0", 49 | "core-js": "^2.4.1", 50 | "hammerjs": "^2.0.8", 51 | "http-server": "^0.9.0", 52 | "@ngui/utils": "^0.7.0", 53 | "npm-check-updates": "^2.8.9", 54 | "npm-run-all": "^3.1.0", 55 | "raw-loader": "^0.5.1", 56 | "reflect-metadata": "^0.1.3", 57 | "rimraf": "^2.5.3", 58 | "rxjs": "5.0.0-beta.12", 59 | "strip-loader": "^0.1.2", 60 | "systemjs": "0.19.27", 61 | "ts-loader": "^0.8.2", 62 | "typescript": "2.0.10", 63 | "webpack": "^1.13.3", 64 | "webpack-dev-server": "^1.16.2", 65 | "webtest": "^0.3.6", 66 | "zone.js": "^0.6.21" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/datetime-picker.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Input, 3 | Output, 4 | Component, 5 | ElementRef, 6 | ViewEncapsulation, 7 | ChangeDetectorRef, 8 | EventEmitter, 9 | ViewChild 10 | } from '@angular/core'; 11 | import { NguiDatetime } from './datetime'; 12 | 13 | declare var moment: any; 14 | 15 | //@TODO 16 | // . display currently selected day 17 | 18 | /** 19 | * show a selected date in monthly calendar 20 | */ 21 | @Component({ 22 | providers: [NguiDatetime], 23 | selector: 'ngui-datetime-picker', 24 | template: ` 25 |
26 |
27 |
28 | 29 | 30 |
31 | « 32 | 33 | 34 | {{monthData?.shortName}} 35 | 36 | 37 | {{monthData.year}} 38 | 39 | » 40 | 41 |
42 | 43 | 44 |
46 | 47 |
48 |
49 | {{weekNumber}} 50 |
51 |
52 | 53 | 54 |
55 | 56 | 57 |
61 | {{dayOfWeek.shortName}} 62 |
63 | 64 | 65 |
66 |
69 | {{dayNum}} 70 |
71 |
72 | 73 |
83 | {{dayNum}} 84 |
85 | 86 | 87 |
88 |
91 | {{dayNum}} 92 |
93 |
94 |
95 |
96 | 97 |
98 | Today 99 |
100 | 101 | 102 |
103 |
{{locale.currentTime}}
104 | 105 | 106 | {{convertHours(hour)}} : {{("0"+minute).slice(-2)}} {{timeSuffix}} 107 |
108 |
109 | 110 | 117 |
118 |
119 | 120 | 125 |
126 |
127 | 128 | 129 |
130 |
131 | {{locale.year}} 132 |
133 | 136 | {{year}} 137 | 138 |
139 |
140 | `, 141 | styles: [ 142 | ` 143 | @keyframes slideDown { 144 | 0% { 145 | transform: translateY(-10px); 146 | } 147 | 100% { 148 | transform: translateY(0px); 149 | } 150 | } 151 | 152 | @keyframes slideUp { 153 | 0% { 154 | transform: translateY(100%); 155 | } 156 | 100% { 157 | transform: translateY(0%); 158 | } 159 | } 160 | 161 | .ngui-datetime-picker-wrapper { 162 | position: relative; 163 | } 164 | 165 | .ngui-datetime-picker { 166 | color: #333; 167 | outline-width: 0; 168 | font: normal 14px sans-serif; 169 | border: 1px solid #ddd; 170 | display: inline-block; 171 | background: #fff; 172 | animation: slideDown 0.1s ease-in-out; 173 | animation-fill-mode: both; 174 | } 175 | .ngui-datetime-picker .days { 176 | width: 210px; /* 30 x 7 days */ 177 | box-sizing: content-box; 178 | } 179 | .ngui-datetime-picker .close-button { 180 | position: absolute; 181 | width: 1em; 182 | height: 1em; 183 | right: 0; 184 | z-index: 1; 185 | padding: 0 5px; 186 | box-sizing: content-box; 187 | } 188 | .ngui-datetime-picker .close-button:before { 189 | content: 'X'; 190 | cursor: pointer; 191 | color: #ff0000; 192 | } 193 | .ngui-datetime-picker > .month { 194 | text-align: center; 195 | line-height: 22px; 196 | padding: 10px; 197 | background: #fcfcfc; 198 | text-transform: uppercase; 199 | font-weight: bold; 200 | border-bottom: 1px solid #ddd; 201 | position: relative; 202 | } 203 | 204 | .ngui-datetime-picker > .month > .prev_next { 205 | color: #555; 206 | display: block; 207 | font: normal 24px sans-serif; 208 | outline: none; 209 | background: transparent; 210 | border: none; 211 | cursor: pointer; 212 | width: 25px; 213 | text-align: center; 214 | box-sizing: content-box; 215 | } 216 | .ngui-datetime-picker > .month > .prev_next:hover { 217 | background-color: #333; 218 | color: #fff; 219 | } 220 | .ngui-datetime-picker > .month > .prev_next.prev { 221 | float: left; 222 | } 223 | .ngui-datetime-picker > .month > .prev_next.next { 224 | float: right; 225 | } 226 | 227 | .ngui-datetime-picker .week-numbers-and-days { 228 | text-align: center; 229 | } 230 | .ngui-datetime-picker .week-numbers { 231 | line-height: 30px; 232 | display: inline-block; 233 | padding: 30px 0 0 0; 234 | color: #ddd; 235 | text-align: right; 236 | width: 21px; 237 | vertical-align: top; 238 | box-sizing: content-box; 239 | } 240 | 241 | .ngui-datetime-picker .days { 242 | display: inline-block; 243 | width: 210px; /* 30 x 7 */ 244 | text-align: center; 245 | padding: 0 10px; 246 | box-sizing: content-box; 247 | } 248 | .ngui-datetime-picker .days .day-of-week, 249 | .ngui-datetime-picker .days .day { 250 | box-sizing: border-box; 251 | border: 1px solid transparent; 252 | width: 30px; 253 | line-height: 28px; 254 | float: left; 255 | } 256 | .ngui-datetime-picker .days .day-of-week { 257 | font-weight: bold; 258 | } 259 | .ngui-datetime-picker .days .day-of-week.weekend { 260 | color: #ccc; 261 | background-color: inherit; 262 | } 263 | .ngui-datetime-picker .days .day:not(.selectable) { 264 | color: #ccc; 265 | cursor: default; 266 | } 267 | .ngui-datetime-picker .days .weekend { 268 | color: #ccc; 269 | background-color: #eee; 270 | } 271 | .ngui-datetime-picker .days .day.selectable { 272 | cursor: pointer; 273 | } 274 | .ngui-datetime-picker .days .day.selected { 275 | background: gray; 276 | color: #fff; 277 | } 278 | .ngui-datetime-picker .days .day:not(.selected).selectable:hover { 279 | background: #eee; 280 | } 281 | .ngui-datetime-picker .days:after { 282 | content: ''; 283 | display: block; 284 | clear: left; 285 | height: 0; 286 | } 287 | .ngui-datetime-picker .time { 288 | position: relative; 289 | padding: 10px; 290 | text-transform: Capitalize; 291 | } 292 | .ngui-datetime-picker .year-selector { 293 | position: absolute; 294 | top: 0; 295 | left: 0; 296 | background: #fff; 297 | height: 100%; 298 | overflow: auto; 299 | padding: 5px; 300 | z-index: 2; 301 | } 302 | .ngui-datetime-picker .year-selector .locale{ 303 | text-align: center; 304 | } 305 | .ngui-datetime-picker .year-selector .year { 306 | display: inline-block; 307 | cursor: pointer; 308 | padding: 2px 5px; 309 | } 310 | .ngui-datetime-picker .year-selector .year:hover { 311 | background-color: #ddd; 312 | } 313 | .ngui-datetime-picker .select-current-time { 314 | position: absolute; 315 | top: 1em; 316 | right: 5px; 317 | z-index: 1; 318 | cursor: pointer; 319 | color: #0000ff; 320 | } 321 | .ngui-datetime-picker .hourLabel, 322 | .ngui-datetime-picker .minutesLabel { 323 | display: inline-block; 324 | width: 45px; 325 | vertical-align: top; 326 | box-sizing: content-box; 327 | } 328 | .closing-layer { 329 | display: block; 330 | position: fixed; 331 | top: 0; 332 | left: 0; 333 | bottom: 0; 334 | right: 0; 335 | background: rgba(0,0,0,0); 336 | } 337 | 338 | .ngui-datetime-picker .shortcuts { 339 | padding: 10px; 340 | text-align: center; 341 | } 342 | 343 | .ngui-datetime-picker .shortcuts a { 344 | font-family: Sans-serif; 345 | margin: 0 0.5em; 346 | text-decoration: none; 347 | } 348 | 349 | @media (max-width: 767px) { 350 | .ngui-datetime-picker { 351 | position: fixed; 352 | bottom: 0; 353 | left: 0; 354 | right: 0; 355 | width: auto !important; 356 | animation: slideUp 0.1s ease-in-out; 357 | } 358 | 359 | .ngui-datetime-picker > .days { 360 | display: block; 361 | margin: 0 auto; 362 | } 363 | 364 | .closing-layer { 365 | display: block; 366 | position: fixed; 367 | top: 0; 368 | left: 0; 369 | bottom: 0; 370 | right: 0; 371 | background: rgba(0,0,0,0.2); 372 | } 373 | } 374 | ` 375 | ], 376 | encapsulation: ViewEncapsulation.None 377 | }) 378 | export class NguiDatetimePickerComponent { 379 | @Input('date-format') dateFormat: string; 380 | @Input('date-only') dateOnly: boolean; 381 | @Input('time-only') timeOnly: boolean; 382 | @Input('selected-date') selectedDate: Date; 383 | @Input('hour') hour: number; 384 | @Input('minute') minute: number; 385 | @Input('minuteStep') minuteStep: number = 1; 386 | @Input('default-value') defaultValue: Date; 387 | @Input('min-date') minDate: Date; 388 | @Input('max-date') maxDate: Date; 389 | @Input('min-hour') minHour: number; 390 | @Input('max-hour') maxHour: number; 391 | @Input('disabled-dates') disabledDates: Date[]; 392 | @Input('show-close-button') showCloseButton: boolean; 393 | @Input('show-close-layer') showCloseLayer: boolean; 394 | @Input('show-week-numbers') showWeekNumbers: boolean = false; 395 | @Input('show-today-shortcut') showTodayShortcut: boolean = false; 396 | @Input('show-am-pm') showAmPm: boolean = false; 397 | 398 | @Output('selected$') selected$: EventEmitter = new EventEmitter(); 399 | @Output('closing$') closing$: EventEmitter = new EventEmitter(); 400 | 401 | @ViewChild('hours') hours: ElementRef; 402 | @ViewChild('minutes') minutes: ElementRef; 403 | 404 | public el: HTMLElement; // this component element 405 | public disabledDatesInTime: number[]; 406 | public locale = NguiDatetime.locale; 407 | public showYearSelector = false; 408 | 409 | private _monthData: any; 410 | private timeSuffix: string; 411 | 412 | public constructor( 413 | elementRef: ElementRef, 414 | public nguiDatetime: NguiDatetime, 415 | public cdRef: ChangeDetectorRef 416 | ) { 417 | this.el = elementRef.nativeElement; 418 | } 419 | 420 | public get yearsSelectable(): number[] { 421 | let startYear = this.year - 100; 422 | let endYear = this.year + 50; 423 | let years: number[] = []; 424 | for (let year = startYear; year < endYear; year++) { 425 | years.push(year); 426 | } 427 | return years; 428 | } 429 | 430 | public get year(): number { 431 | return this.selectedDate.getFullYear(); 432 | } 433 | 434 | public get month(): number { 435 | return this.selectedDate.getMonth(); 436 | } 437 | 438 | public get day(): number { 439 | return this.selectedDate.getDate(); 440 | } 441 | 442 | public get monthData(): any { 443 | return this._monthData; 444 | } 445 | 446 | public get today(): Date { 447 | let dt = new Date(); 448 | dt.setHours(0); 449 | dt.setMinutes(0); 450 | dt.setSeconds(0); 451 | dt.setMilliseconds(0); 452 | return dt; 453 | } 454 | 455 | public set year(year) { } 456 | public set month(month) { } 457 | public set day(day) { } 458 | public set today(today) { } 459 | 460 | public ngOnInit() { 461 | if (!this.defaultValue || isNaN(this.defaultValue.getTime())) { 462 | this.defaultValue = new Date(); 463 | } 464 | this.selectedDate = this.defaultValue; 465 | 466 | // set hour and minute using moment if available to avoid having Javascript change timezones 467 | if (typeof moment === 'undefined') { 468 | this.hour = this.selectedDate.getHours(); 469 | this.minute = this.selectedDate.getMinutes(); 470 | } else { 471 | let m = moment(this.selectedDate); 472 | this.hour = m.hours(); 473 | this.minute = m.minute(); 474 | } 475 | 476 | this._monthData = this.nguiDatetime.getMonthData(this.year, this.month); 477 | } 478 | 479 | public isWeekend(dayNum: number, month?: number): boolean { 480 | if (typeof month === 'undefined') { 481 | return NguiDatetime.weekends.indexOf(dayNum % 7) !== -1; //weekday index 482 | } else { 483 | let weekday = this.toDate(dayNum, month).getDay(); 484 | return NguiDatetime.weekends.indexOf(weekday) !== -1; 485 | } 486 | } 487 | 488 | public selectYear(year) { 489 | this._monthData = this.nguiDatetime.getMonthData(year, this._monthData.month); 490 | this.showYearSelector = false; 491 | } 492 | 493 | public toDate(day: number, month?: number): Date { 494 | return new Date(this._monthData.year, month || this._monthData.month, day); 495 | } 496 | 497 | public toDateOnly(date: Date) { 498 | return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0); 499 | } 500 | 501 | public selectCurrentTime() { 502 | this.hour = (new Date()).getHours(); 503 | this.minute = (new Date()).getMinutes(); 504 | this.selectDateTime(); 505 | } 506 | 507 | /** 508 | * set the hour and minute 509 | * @param hour {string} 510 | * @param minute {string} 511 | */ 512 | public selectTime (hour, minute) { 513 | //NOTE: must get hour & minute because 2-way binding does not work with range input in IE <= 11 514 | this.hour = parseInt(hour, 10) || 0; 515 | this.minute = parseInt(minute, 10) || 0; 516 | this.selectDateTime(); 517 | } 518 | 519 | /** 520 | * set the selected date and close it when closeOnSelect is true 521 | * @param date {Date} 522 | */ 523 | public selectDateTime(date?: Date) { 524 | this.selectedDate = date || this.selectedDate; 525 | if (this.isDateDisabled(this.selectedDate)) { 526 | return false; 527 | } 528 | 529 | // editing hours and minutes via javascript date methods causes date to lose timezone info, 530 | // so edit using moment if available 531 | let hour = parseInt('' + this.hour || '0', 10); 532 | let minute = parseInt('' + this.minute || '0', 10); 533 | 534 | if (typeof moment !== 'undefined') { 535 | // here selected date has a time of 00:00 in local time, 536 | // so build moment by getting year/month/day separately 537 | // to avoid it saving as a day earlier 538 | let m = moment([this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate()]); 539 | m.hours(hour); 540 | m.minutes(minute); 541 | this.selectedDate = m.toDate(); 542 | } else { 543 | this.selectedDate.setHours(hour); 544 | this.selectedDate.setMinutes(minute); 545 | } 546 | //console.log('this.selectedDate', this.selectedDate) 547 | 548 | this.selectedDate.toString = () => { 549 | return NguiDatetime.formatDate(this.selectedDate, this.dateFormat, this.dateOnly); 550 | }; 551 | this.selected$.emit(this.selectedDate); 552 | }; 553 | 554 | /** 555 | * show prev/next month calendar 556 | */ 557 | public updateMonthData(num: number) { 558 | this._monthData = this.nguiDatetime.getMonthData(this._monthData.year, this._monthData.month + num); 559 | } 560 | 561 | public isDateDisabled(date: Date) { 562 | let dateInTime = date.getTime(); 563 | this.disabledDatesInTime = 564 | this.disabledDatesInTime || (this.disabledDates || []).map(d => d.getTime()); 565 | 566 | if (this.minDate && (dateInTime < this.minDate.getTime())) { 567 | return true; 568 | } else if (this.maxDate && (dateInTime > this.maxDate.getTime())) { 569 | return true; 570 | } else if (this.disabledDatesInTime.indexOf(dateInTime) >= 0) { 571 | return true 572 | } 573 | 574 | return false; 575 | } 576 | 577 | public close() { 578 | this.closing$.emit(true); 579 | } 580 | 581 | public selectToday() { 582 | this.selectDateTime(new Date()); 583 | } 584 | 585 | private convertHours(hours) { 586 | if (this.showAmPm) { 587 | this.timeSuffix = (hours >= 12) ? 'PM' : 'AM'; 588 | hours = (hours == 0) ? 12 : (hours > 12) ? hours - 12 : hours; 589 | } else { 590 | this.timeSuffix = null; 591 | } 592 | return ("0" + hours).slice(-2); 593 | } 594 | } 595 | -------------------------------------------------------------------------------- /src/datetime-picker.directive.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ComponentFactoryResolver, ComponentRef, Directive, EventEmitter, Host, 3 | Input, OnChanges, OnInit, Optional, Output, 4 | SimpleChanges, SkipSelf, ViewContainerRef 5 | } from '@angular/core'; 6 | import { AbstractControl, ControlContainer, FormGroup, FormGroupDirective } from '@angular/forms'; 7 | import { NguiDatetimePickerComponent } from './datetime-picker.component'; 8 | import { NguiDatetime } from './datetime'; 9 | 10 | declare var moment: any; 11 | 12 | function isInteger(value) { 13 | if (Number.isInteger) { 14 | return Number.isInteger(value); 15 | } 16 | return typeof value === "number" && 17 | isFinite(value) && 18 | Math.floor(value) === value; 19 | }; 20 | 21 | function isNaN(value) { 22 | if (Number.isNaN) { 23 | return Number.isNaN(value); 24 | } 25 | return value !== value; 26 | }; 27 | 28 | /** 29 | * If the given string is not a valid date, it defaults back to today 30 | */ 31 | @Directive({ 32 | selector: '[ngui-datetime-picker]', 33 | providers: [NguiDatetime] 34 | }) 35 | export class NguiDatetimePickerDirective implements OnInit, OnChanges { 36 | @Input('date-format') dateFormat: string; 37 | @Input('parse-format') parseFormat: string; 38 | @Input('date-only') dateOnly: boolean; 39 | @Input('time-only') timeOnly: boolean; 40 | @Input('close-on-select') closeOnSelect: boolean = true; 41 | @Input('default-value') defaultValue: Date | string; 42 | @Input('minute-step') minuteStep: number; 43 | @Input('min-date') minDate: Date | string; 44 | @Input('max-date') maxDate: Date | string; 45 | @Input('min-hour') minHour: Date | number; 46 | @Input('max-hour') maxHour: Date | number; 47 | @Input('disabled-dates') disabledDates: Date[]; 48 | @Input('show-close-layer') showCloseLayer: boolean; 49 | @Input('show-today-shortcut') showTodayShortcut: boolean = false; 50 | @Input('show-week-numbers') showWeekNumbers: boolean; 51 | @Input() formControlName: string; 52 | @Input('is-draggable') isDraggable: boolean = true; 53 | 54 | @Input('ngModel') ngModel: any; 55 | @Output('ngModelChange') ngModelChange = new EventEmitter(); 56 | @Output('valueChanged') valueChanged$ = new EventEmitter(); 57 | @Output('popupClosed') popupClosed$ = new EventEmitter(); 58 | 59 | private el: HTMLInputElement; /* input element */ 60 | private nguiDatetimePickerEl: HTMLElement; /* dropdown element */ 61 | private componentRef: ComponentRef; /* dropdown component reference */ 62 | private ctrl: AbstractControl; 63 | private sub: any; 64 | // private justShown: boolean; 65 | 66 | inputEl: HTMLInputElement; 67 | clickedDatetimePicker: boolean; 68 | userModifyingValue: boolean = false; 69 | 70 | constructor( 71 | private resolver: ComponentFactoryResolver, 72 | private viewContainerRef: ViewContainerRef, 73 | @Optional() @Host() @SkipSelf() private parent: ControlContainer 74 | ) { 75 | this.el = this.viewContainerRef.element.nativeElement; 76 | } 77 | 78 | /** 79 | * convert defaultValue, minDate, maxDate, minHour, and maxHour to proper types 80 | */ 81 | normalizeInput() { 82 | if (this.defaultValue && typeof this.defaultValue === 'string') { 83 | let d = NguiDatetime.parseDate(this.defaultValue); 84 | this.defaultValue = isNaN(d.getTime()) ? new Date() : d; 85 | } 86 | 87 | if (this.minDate && typeof this.minDate == 'string') { 88 | let d = NguiDatetime.parseDate(this.minDate); 89 | this.minDate = isNaN(d.getTime()) ? new Date() : d; 90 | } 91 | 92 | if (this.maxDate && typeof this.maxDate == 'string') { 93 | let d = NguiDatetime.parseDate(this.maxDate); 94 | this.maxDate = isNaN(d.getTime()) ? new Date() : d; 95 | } 96 | 97 | if (this.minHour) { 98 | if (this.minHour instanceof Date) { 99 | this.minHour = (this.minHour).getHours(); 100 | } else { 101 | let hour = Number(this.minHour.toString()); 102 | if (!isInteger(hour) || hour > 23 || hour < 0) { 103 | this.minHour = undefined; 104 | } 105 | } 106 | } 107 | 108 | if (this.maxHour) { 109 | if (this.maxHour instanceof Date) { 110 | this.maxHour = (this.maxHour).getHours(); 111 | } else { 112 | let hour = Number(this.maxHour.toString()); 113 | if (!isInteger(hour) || hour > 23 || hour < 0) { 114 | this.maxHour = undefined; 115 | } 116 | } 117 | } 118 | } 119 | 120 | ngOnInit(): void { 121 | if (this.parent && this.formControlName) { 122 | if (this.parent["form"]) { 123 | this.ctrl = (this.parent["form"]).get(this.formControlName); 124 | } else if (this.parent["path"]) { 125 | let formDir = this.parent.formDirective; 126 | if (formDir instanceof FormGroupDirective && formDir.form.get(this.parent["path"])) { 127 | this.ctrl = formDir.form.get(this.parent["path"]).get(this.formControlName); 128 | } 129 | } 130 | if (this.ctrl) { 131 | this.sub = this.ctrl.valueChanges.subscribe((date) => { 132 | this.setInputElDateValue(date); 133 | this.updateDatepicker(); 134 | }); 135 | } 136 | } 137 | 138 | this.normalizeInput(); 139 | 140 | //wrap this element with a
tag, so that we can position dynamic element correctly 141 | let wrapper = document.createElement("div"); 142 | wrapper.className = 'ngui-datetime-picker-wrapper'; 143 | this.el.parentElement.insertBefore(wrapper, this.el.nextSibling); 144 | wrapper.appendChild(this.el); 145 | 146 | if (this.ngModel && this.ngModel.getTime) { // if it is a Date object given, set dateValue and toString method 147 | this.ngModel.toString = () => NguiDatetime.formatDate(this.ngModel, this.dateFormat, this.dateOnly); 148 | } 149 | setTimeout(() => { // after [(ngModel)] is applied 150 | if (this.el.tagName === 'INPUT') { 151 | this.inputElValueChanged(this.el.value); //set this.el.dateValue and reformat this.el.value 152 | } 153 | if (this.ctrl) { 154 | this.ctrl.markAsPristine(); 155 | } 156 | }); 157 | } 158 | 159 | ngAfterViewInit() { 160 | // if this element is not an input tag, move dropdown after input tag 161 | // so that it displays correctly 162 | this.inputEl = this.el.tagName === "INPUT" ? 163 | this.el : this.el.querySelector("input"); 164 | 165 | if (this.inputEl) { 166 | this.inputEl.addEventListener('focus', this.showDatetimePicker); 167 | this.inputEl.addEventListener('blur', this.hideDatetimePicker); 168 | this.inputEl.addEventListener('keydown', this.handleKeyDown); 169 | } 170 | } 171 | 172 | handleKeyDown = (event) => { 173 | this.userModifyingValue = true; 174 | } 175 | 176 | 177 | ngOnChanges(changes: SimpleChanges) { 178 | let date; 179 | if (changes && changes['ngModel']) { 180 | date = changes['ngModel'].currentValue; 181 | 182 | if (date && typeof date !== 'string') { 183 | date.toString = () => NguiDatetime.formatDate(date, this.dateFormat, this.dateOnly); 184 | this.setInputElDateValue(date); 185 | this.updateDatepicker(); 186 | } else if (date && typeof date === 'string') { 187 | /** if program assigns a string value, then format to date later */ 188 | if (!this.userModifyingValue) { 189 | setTimeout(() => { 190 | let dt = this.getDate(date); 191 | dt.toString = () => NguiDatetime.formatDate(dt, this.dateFormat, this.dateOnly); 192 | this.ngModel = dt; 193 | this.inputEl.value = '' + dt; 194 | }) 195 | } else { 196 | let changeDate: any = new Date(date); 197 | if (changeDate.toString() !== "Invalid Date") { 198 | this.setInputElDateValue(date); 199 | this.updateDatepicker(); 200 | } 201 | } 202 | } 203 | } 204 | this.userModifyingValue = false; 205 | } 206 | 207 | updateDatepicker() { 208 | if (this.componentRef) { 209 | let component = this.componentRef.instance; 210 | component.defaultValue = this.el['dateValue']; 211 | } 212 | } 213 | 214 | setInputElDateValue(date) { 215 | if (typeof date === 'string' && date) { 216 | this.el['dateValue'] = this.getDate(date); 217 | } else if (typeof date === 'object') { 218 | this.el['dateValue'] = date 219 | } else if (typeof date === 'undefined') { 220 | this.el['dateValue'] = null; 221 | } 222 | 223 | if (this.ctrl) { 224 | this.ctrl.markAsDirty(); 225 | } 226 | } 227 | 228 | ngOnDestroy(): void { 229 | if (this.sub) { 230 | this.sub.unsubscribe(); 231 | } 232 | } 233 | 234 | /* input element string value is changed */ 235 | inputElValueChanged = (date: string | Date): void => { 236 | this.setInputElDateValue(date); 237 | this.el.value = date.toString(); 238 | if (this.ctrl) { 239 | this.ctrl.patchValue(this.el.value); 240 | } 241 | this.ngModel = this.el['dateValue']; 242 | if (this.ngModel) { 243 | this.ngModel.toString = () => { return this.el.value; }; 244 | this.ngModelChange.emit(this.ngModel); 245 | } 246 | }; 247 | 248 | //show datetimePicker element below the current element 249 | showDatetimePicker = (event?): void => { 250 | if (this.componentRef) { /* if already shown, do nothing */ 251 | return; 252 | } 253 | 254 | let factory = this.resolver.resolveComponentFactory(NguiDatetimePickerComponent); 255 | 256 | this.componentRef = this.viewContainerRef.createComponent(factory); 257 | this.nguiDatetimePickerEl = this.componentRef.location.nativeElement; 258 | this.nguiDatetimePickerEl.setAttribute('tabindex', '32767'); 259 | this.nguiDatetimePickerEl.setAttribute('draggable', String(this.isDraggable)); 260 | this.nguiDatetimePickerEl.addEventListener('mousedown', (event) => { 261 | this.clickedDatetimePicker = true 262 | }); 263 | this.nguiDatetimePickerEl.addEventListener('mouseup', (event) => { 264 | this.clickedDatetimePicker = false; 265 | }); 266 | //This is for material design. MD has click event to make blur to happen 267 | this.nguiDatetimePickerEl.addEventListener('click', (event) => { 268 | event.stopPropagation(); 269 | }); 270 | this.nguiDatetimePickerEl.addEventListener('blur', (event) => { 271 | this.hideDatetimePicker(); 272 | }); 273 | this.nguiDatetimePickerEl.addEventListener('dragstart', this.drag_start, false); 274 | document.body.addEventListener('dragover', this.drag_over, false); 275 | document.body.addEventListener('drop', this.drop, false); 276 | 277 | let component = this.componentRef.instance; 278 | component.defaultValue = this.defaultValue || this.el['dateValue']; 279 | component.dateFormat = this.dateFormat; 280 | component.dateOnly = this.dateOnly; 281 | component.timeOnly = this.timeOnly; 282 | component.minuteStep = this.minuteStep; 283 | component.minDate = this.minDate; 284 | component.maxDate = this.maxDate; 285 | component.minHour = this.minHour; 286 | component.maxHour = this.maxHour; 287 | component.disabledDates = this.disabledDates; 288 | component.showCloseButton = this.closeOnSelect === false; 289 | component.showCloseLayer = this.showCloseLayer; 290 | component.showTodayShortcut = this.showTodayShortcut; 291 | component.showWeekNumbers = this.showWeekNumbers; 292 | 293 | this.styleDatetimePicker(); 294 | 295 | component.selected$.subscribe(this.dateSelected); 296 | component.closing$.subscribe(() => { 297 | this.hideDatetimePicker(); 298 | }); 299 | 300 | //Hack not to fire tab keyup event 301 | // this.justShown = true; 302 | // setTimeout(() => this.justShown = false, 100); 303 | }; 304 | 305 | dateSelected = (date) => { 306 | this.el.tagName === 'INPUT' && this.inputElValueChanged(date); 307 | this.valueChanged$.emit(date); 308 | if (this.closeOnSelect !== false) { 309 | this.hideDatetimePicker(); 310 | } else { 311 | this.nguiDatetimePickerEl.focus(); 312 | } 313 | }; 314 | 315 | hideDatetimePicker = (event?): any => { 316 | if (this.clickedDatetimePicker) { 317 | return false; 318 | } else { /* invoked by function call */ 319 | setTimeout(() => { //having exception without setTimeout 320 | if (this.componentRef) { 321 | this.componentRef.destroy(); 322 | this.componentRef = undefined; 323 | } 324 | this.popupClosed$.emit(true); 325 | }) 326 | } 327 | event && event.stopPropagation(); 328 | }; 329 | 330 | private elementIn(el: Node, containerEl: Node): boolean { 331 | while (el = el.parentNode) { 332 | if (el === containerEl) return true; 333 | } 334 | return false; 335 | } 336 | 337 | private styleDatetimePicker() { 338 | // setting position, width, and height of auto complete dropdown 339 | let thisElBCR = this.el.getBoundingClientRect(); 340 | // this.nguiDatetimePickerEl.style.minWidth = thisElBCR.width + 'px'; 341 | this.nguiDatetimePickerEl.style.position = 'absolute'; 342 | this.nguiDatetimePickerEl.style.zIndex = '1000'; 343 | this.nguiDatetimePickerEl.style.left = '0'; 344 | this.nguiDatetimePickerEl.style.transition = 'height 0.3s ease-in'; 345 | 346 | this.nguiDatetimePickerEl.style.visibility = 'hidden'; 347 | 348 | setTimeout(() => { 349 | let thisElBcr = this.el.getBoundingClientRect(); 350 | let nguiDatetimePickerElBcr = this.nguiDatetimePickerEl.getBoundingClientRect(); 351 | 352 | if (thisElBcr.bottom + nguiDatetimePickerElBcr.height > window.innerHeight) { 353 | this.nguiDatetimePickerEl.style.bottom = 354 | (thisElBcr.bottom - window.innerHeight + 15) + 'px'; 355 | } 356 | else { 357 | // otherwise, show below 358 | this.nguiDatetimePickerEl.style.top = thisElBcr.height + 'px'; 359 | } 360 | this.nguiDatetimePickerEl.style.visibility = 'visible'; 361 | }); 362 | }; 363 | 364 | private getDate = (arg: any): Date => { 365 | let date: Date = arg; 366 | if (typeof arg === 'string') { 367 | date = NguiDatetime.parseDate(arg, this.parseFormat, this.dateFormat); 368 | } 369 | return date; 370 | } 371 | 372 | private drag_start = (event) => { 373 | if (document.activeElement.tagName == 'INPUT') { 374 | event.preventDefault(); 375 | return false; // block dragging 376 | } 377 | var style = window.getComputedStyle(event.target, null); 378 | event.dataTransfer.setData("text/plain", 379 | (parseInt(style.getPropertyValue("left"), 10) - event.clientX) 380 | + ',' 381 | + (parseInt(style.getPropertyValue("top"), 10) - event.clientY) 382 | ); 383 | } 384 | 385 | private drag_over(event) { 386 | event.preventDefault(); 387 | return false; 388 | } 389 | 390 | private drop = (event) => { 391 | var offset = event.dataTransfer.getData("text/plain").split(','); 392 | this.nguiDatetimePickerEl.style.left = (event.clientX + parseInt(offset[0], 10)) + 'px'; 393 | this.nguiDatetimePickerEl.style.top = (event.clientY + parseInt(offset[1], 10)) + 'px'; 394 | this.nguiDatetimePickerEl.style.bottom = ''; 395 | event.preventDefault(); 396 | return false; 397 | } 398 | } 399 | -------------------------------------------------------------------------------- /src/datetime-picker.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from "@angular/forms"; 3 | import { CommonModule } from '@angular/common'; 4 | 5 | import { NguiDatetime } from './datetime'; 6 | import { NguiDatetimePickerComponent } from './datetime-picker.component'; 7 | import { NguiDatetimePickerDirective } from './datetime-picker.directive'; 8 | 9 | @NgModule({ 10 | imports: [ CommonModule, FormsModule ], 11 | declarations: [NguiDatetimePickerComponent, NguiDatetimePickerDirective], 12 | exports: [NguiDatetimePickerComponent, NguiDatetimePickerDirective], 13 | entryComponents: [NguiDatetimePickerComponent], 14 | providers: [ NguiDatetime ] 15 | }) 16 | export class NguiDatetimePickerModule {} 17 | -------------------------------------------------------------------------------- /src/datetime.ts: -------------------------------------------------------------------------------- 1 | declare var moment: any; 2 | 3 | import {Injectable} from "@angular/core"; 4 | 5 | /** 6 | * Static variables that you can override 7 | * 1. days. default 1,2,....31 8 | * 2. daysOfWeek, default Sunday, Monday, ..... 9 | * 3. firstDayOfWeek, default 0 as in Sunday 10 | * 4. months, default January, February 11 | * 5. formatDate(d) default returns YYYY-MM-DD HH:MM 12 | * 6. parseDate(str) default returns date from YYYY-MM-DD HH:MM 13 | */ 14 | @Injectable() 15 | export class NguiDatetime { 16 | static locale: any = { 17 | date: 'date', 18 | time: 'time', 19 | 20 | year: 'year', 21 | month: 'month', 22 | day: 'day', 23 | hour: 'hour', 24 | minute: 'minute', 25 | currentTime: "current time" 26 | }; 27 | 28 | static days: number[] = 29 | [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]; 30 | 31 | static weekends: number[] = [0,6]; 32 | 33 | static daysOfWeek: any[] = 34 | typeof moment === 'undefined' ? [ 35 | {fullName: 'Sunday', shortName: 'Su'}, 36 | {fullName: 'Monday', shortName: 'Mo'}, 37 | {fullName: 'Tuesday', shortName: 'Tu'}, 38 | {fullName: 'Wednesday', shortName: 'We'}, 39 | {fullName: 'Thursday', shortName: 'Th'}, 40 | {fullName: 'Friday', shortName: 'Fr'}, 41 | {fullName: 'Saturday', shortName: 'Sa'} 42 | ] : moment.weekdays().map((el, index) => { 43 | return { 44 | fullName: el, 45 | shortName: moment.weekdaysShort()[index].substr(0, 2) 46 | } 47 | }); 48 | 49 | static firstDayOfWeek: number = 50 | typeof moment === 'undefined' ? 0 : moment.localeData().firstDayOfWeek(); 51 | 52 | static months: any[] = typeof moment === 'undefined' ? [ 53 | {fullName: 'January', shortName: 'Jan'}, 54 | {fullName: 'February', shortName: 'Feb'}, 55 | {fullName: 'March', shortName: 'Mar'}, 56 | {fullName: 'April', shortName: 'Apr'}, 57 | {fullName: 'May', shortName: 'May'}, 58 | {fullName: 'June', shortName: 'Jun'}, 59 | {fullName: 'July', shortName: 'Jul'}, 60 | {fullName: 'August', shortName: 'Aug'}, 61 | {fullName: 'September', shortName: 'Sep'}, 62 | {fullName: 'October', shortName: 'Oct'}, 63 | {fullName: 'November', shortName: 'Nov'}, 64 | {fullName: 'December', shortName: 'Dec'} 65 | ] : moment.months().map((el, index) => { 66 | return { 67 | fullName: el, 68 | shortName: moment['monthsShort']()[index] 69 | } 70 | }); 71 | 72 | static formatDate(d: Date, format?: string, dateOnly?: boolean): string { 73 | let ret: string; 74 | if (d && !format) { 75 | // return d.toLocaleString('en-us', hash); // IE11 does not understand this 76 | let pad0 = number => ("0" + number).slice(-2); 77 | ret = d.getFullYear() + '-' + pad0(d.getMonth() + 1) + '-' + pad0(d.getDate()); 78 | ret += dateOnly ? '' : ' ' + pad0(d.getHours()) + ':' + pad0(d.getMinutes()); 79 | return ret; 80 | } else if (d && typeof moment !== 'undefined') { 81 | return moment(d).format(format); 82 | } else { 83 | return ''; 84 | } 85 | } 86 | 87 | static parseDate(dateStr: string, parseFormat?: string, dateFormat?: string): Date { 88 | if (typeof moment === 'undefined') { 89 | dateStr = NguiDatetime.removeTimezone(dateStr); 90 | dateStr = dateStr + NguiDatetime.addDSTOffset(dateStr); 91 | return NguiDatetime.parseFromDefaultFormat(dateStr); 92 | } else if (dateFormat || parseFormat) { 93 | // try parse using each format because changing format programmatically calls this twice, 94 | // once with string in parse format and once in date format 95 | let formats = []; 96 | if (parseFormat) { 97 | formats.push(parseFormat); 98 | } 99 | if (dateFormat) { 100 | formats.push(dateFormat); 101 | } 102 | let m = moment(dateStr, formats); 103 | let date = m.toDate(); 104 | if (!m.isValid()) { // if moment is invalid 105 | date = moment(dateStr, moment.ISO_8601).toDate(); // parse as ISO format 106 | } 107 | return date; 108 | } else if (dateStr.length > 4) { //at least requires an year 109 | let date = moment(dateStr, 'YYYY-MM-DD HH:mm').toDate(); 110 | return date; 111 | } else { 112 | return new Date(); 113 | } 114 | } 115 | 116 | static getWeekNumber(date) { 117 | if (!(date instanceof Date)) date = new Date(); 118 | 119 | // ISO week date weeks start on Monday, so correct the day number 120 | var nDay = (date.getDay() + 6) % 7; 121 | 122 | // ISO 8601 states that week 1 is the week with the first Thursday of that year 123 | // Set the target date to the Thursday in the target week 124 | date.setDate(date.getDate() - nDay + 3); 125 | 126 | // Store the millisecond value of the target date 127 | var n1stThursday = date.valueOf(); 128 | 129 | // Set the target to the first Thursday of the year 130 | // First, set the target to January 1st 131 | date.setMonth(0, 1); 132 | 133 | // Not a Thursday? Correct the date to the next Thursday 134 | if (date.getDay() !== 4) { 135 | date.setMonth(0, 1 + ((4 - date.getDay()) + 7) % 7); 136 | } 137 | 138 | // The week number is the number of weeks between the first Thursday of the year 139 | // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000) 140 | return 1 + Math.ceil((n1stThursday - date) / 604800000); 141 | } 142 | 143 | //remove timezone 144 | private static removeTimezone(dateStr): string { 145 | // if no time is given, add 00:00:00 at the end 146 | let matches = dateStr.match(/[0-9]{2}:/); 147 | dateStr += matches ? '' : ' 00:00:00'; 148 | return dateStr.replace(/([0-9]{2}-[0-9]{2})-([0-9]{4})/, '$2-$1') //mm-dd-yyyy to yyyy-mm-dd 149 | .replace(/([\/-][0-9]{2,4})\ ([0-9]{2}\:[0-9]{2}\:)/, '$1T$2') //reformat for FF 150 | .replace(/EDT|EST|CDT|CST|MDT|PDT|PST|UT|GMT/g, '') //remove timezone 151 | .replace(/\s*\(\)\s*/, '') //remove timezone 152 | .replace(/[\-\+][0-9]{2}:?[0-9]{2}$/, '') //remove timezone 153 | .replace(/000Z$/, '00'); //remove timezone 154 | } 155 | 156 | private static addDSTOffset(dateStr): string { 157 | let date = NguiDatetime.parseFromDefaultFormat(dateStr); 158 | let jan = new Date(date.getFullYear(), 0, 1); 159 | let jul = new Date(date.getFullYear(), 6, 1); 160 | let stdTimezoneOffset = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); 161 | let isDST = date.getTimezoneOffset() < stdTimezoneOffset; 162 | let offset = isDST ? stdTimezoneOffset - 60 : stdTimezoneOffset; 163 | let diff = offset >= 0 ? '-' : '+'; 164 | offset = Math.abs(offset); 165 | return diff + 166 | ('0' + (offset / 60)).slice(-2) + ':' + 167 | ('0' + (offset % 60)).slice(-2); 168 | }; 169 | 170 | private static parseFromDefaultFormat(dateStr): Date { 171 | let tmp = dateStr.split(/[\+\-:\ T]/); // split by dash, colon or space 172 | return new Date( 173 | parseInt(tmp[0], 10), 174 | parseInt(tmp[1], 10) - 1, 175 | parseInt(tmp[2], 10), 176 | parseInt(tmp[3] || '0', 10), 177 | parseInt(tmp[4] || '0', 10), 178 | parseInt(tmp[5] || '0', 10) 179 | ); 180 | } 181 | 182 | getMonthData(year: number, month: number): any { 183 | year = month > 11 ? year + 1 : 184 | month < 0 ? year - 1 : year; 185 | month = (month + 12) % 12; 186 | 187 | let firstDayOfMonth = new Date(year, month, 1); 188 | let lastDayOfMonth = new Date(year, month + 1, 0); 189 | let lastDayOfPreviousMonth = new Date(year, month, 0); 190 | let daysInMonth = lastDayOfMonth.getDate(); 191 | let daysInLastMonth = lastDayOfPreviousMonth.getDate(); 192 | let dayOfWeek = firstDayOfMonth.getDay(); 193 | 194 | // Ensure there are always leading days to give context 195 | let leadingDays = (dayOfWeek - NguiDatetime.firstDayOfWeek + 7) % 7 || 7; 196 | let trailingDays = NguiDatetime.days.slice(0, 6 * 7 - (leadingDays + daysInMonth)); 197 | if (trailingDays.length > 7) { 198 | trailingDays = trailingDays.slice(0, trailingDays.length - 7); 199 | } 200 | 201 | let firstDay = new Date(firstDayOfMonth); 202 | firstDay.setDate(firstDayOfMonth.getDate() - (leadingDays % 7)); 203 | let firstWeekNumber = NguiDatetime.getWeekNumber(firstDay); 204 | let numWeeks = Math.ceil((daysInMonth + leadingDays%7) / 7); 205 | let weekNumbers =Array(numWeeks).fill(0).map( 206 | (el,ndx) => { 207 | let weekNum = (ndx + firstWeekNumber + 52) % 52; 208 | return weekNum === 0 ? 52 : weekNum; 209 | } 210 | ); 211 | 212 | let localizedDaysOfWeek = 213 | NguiDatetime.daysOfWeek 214 | .concat(NguiDatetime.daysOfWeek) 215 | .splice(NguiDatetime.firstDayOfWeek, 7); 216 | 217 | 218 | let monthData = { 219 | year: year, 220 | month: month, 221 | weekends: NguiDatetime.weekends, 222 | firstDayOfWeek: NguiDatetime.firstDayOfWeek, 223 | fullName: NguiDatetime.months[month].fullName, 224 | shortName: NguiDatetime.months[month].shortName, 225 | localizedDaysOfWeek: localizedDaysOfWeek, 226 | days: NguiDatetime.days.slice(0, daysInMonth), 227 | leadingDays: NguiDatetime.days.slice(-leadingDays - (31 - daysInLastMonth), daysInLastMonth), 228 | trailingDays: trailingDays, 229 | weekNumbers: weekNumbers 230 | }; 231 | 232 | return monthData; 233 | } 234 | 235 | } 236 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { NguiDatetime } from './datetime'; 2 | import { NguiDatetimePickerComponent } from './datetime-picker.component'; 3 | import { NguiDatetimePickerDirective } from './datetime-picker.directive'; 4 | import { NguiDatetimePickerModule } from './datetime-picker.module'; 5 | 6 | export { 7 | NguiDatetime, 8 | NguiDatetimePickerComponent, 9 | NguiDatetimePickerDirective, 10 | NguiDatetimePickerModule 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["es5", "es6", "dom"], 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "sourceMap": true, 10 | "pretty": true, 11 | "allowUnreachableCode": true, 12 | "allowUnusedLabels": true, 13 | "noImplicitAny": false, 14 | "noImplicitReturns": false, 15 | "noImplicitUseStrict": false, 16 | "allowSyntheticDefaultImports": true, 17 | "suppressExcessPropertyErrors": true, 18 | "suppressImplicitAnyIndexErrors": true, 19 | "skipDefaultLibCheck": true, 20 | "noEmitHelpers": false, 21 | "isolatedModules": false, 22 | "strictNullChecks": false, 23 | "outDir": "dist", 24 | "baseUrl": "src", 25 | "paths": { 26 | "@ngui/datetime-picker": ["./index"] 27 | } 28 | }, 29 | "files": [ 30 | "src/index.ts" 31 | ], 32 | "exclude": [ 33 | "node_modules" 34 | ], 35 | "compileOnSave": false, 36 | "buildOnSave": false, 37 | "angularCompilerOptions": { 38 | "strictMetadataEmit": true, 39 | "skipTemplateCodegen": true 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tsconfig.ngc.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["es5", "es6", "dom"], 5 | "module": "commonjs", 6 | "declaration": true, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "sourceMap": true, 11 | "pretty": true, 12 | "allowUnreachableCode": true, 13 | "allowUnusedLabels": true, 14 | "noImplicitAny": false, 15 | "noImplicitReturns": false, 16 | "noImplicitUseStrict": false, 17 | "allowSyntheticDefaultImports": true, 18 | "suppressExcessPropertyErrors": true, 19 | "suppressImplicitAnyIndexErrors": true, 20 | "skipDefaultLibCheck": true, 21 | "noEmitHelpers": false, 22 | "isolatedModules": false, 23 | "strictNullChecks": false, 24 | "outDir": "dist", 25 | "baseUrl": "src", 26 | "paths": { 27 | "@ngui/datetime-picker": ["./index"] 28 | } 29 | }, 30 | "files": [ 31 | "src/index.ts" 32 | ], 33 | "exclude": [ 34 | "node_modules" 35 | ], 36 | "compileOnSave": false, 37 | "buildOnSave": false, 38 | "angularCompilerOptions": { 39 | "strictMetadataEmit": true, 40 | "skipTemplateCodegen": true 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var webpack = require('webpack'); 3 | 4 | var config = { 5 | entry: { 6 | '@ngui/datetime-picker': path.join(__dirname, 'src', 'index.ts') 7 | }, 8 | resolve: { 9 | extensions: ['', '.ts', '.js', '.json', '.css', '.html'] 10 | }, 11 | resolveLoader: { 12 | root: path.join(__dirname, 'node_modules') 13 | }, 14 | output: { 15 | path: path.join(__dirname, 'dist'), 16 | filename: "datetime-picker.umd.js", 17 | library: ["datetime-picker"], 18 | libraryTarget: "umd" 19 | }, 20 | externals: [ 21 | /^rxjs\//, //.... any other way? rx.umd.min.js does work? 22 | /^@angular\// 23 | ], 24 | devtool: 'source-map', 25 | module: { 26 | loaders: [ 27 | { // Support for .ts files. 28 | test: /\.ts$/, 29 | loaders: ['ts', 'angular2-template-loader'] 30 | } 31 | ] 32 | } 33 | }; 34 | 35 | if (process.env.NODE_ENV === 'prod') { 36 | config.module.loaders.push({ 37 | test: /\.ts$/, loader: 'strip-loader?strip[]=debug,strip[]=console.log' 38 | }); 39 | } 40 | 41 | module.exports = config; 42 | -------------------------------------------------------------------------------- /webtest.txt: -------------------------------------------------------------------------------- 1 | DateTime Picker Test On Browser 2 | To Run this, run $ `npm start`first to start the web server with port 9002 3 | 4 | START 5 | open browser 6 | go to http://localhost:9002 7 | 8 | TEST2 9 | click "#test2 input" 10 | click "#test2 div.month b.prev_next.prev" 11 | verify element "#test2 div.day[title='2016-1-20']" without class selectable 12 | click "#test2 div.month b.prev_next.next" 13 | verify element "#test2 div.day[title='2017-1-10']" without class selectable 14 | verify element "#test2 div.day[title='2017-1-20']" without class selectable 15 | click "#test2 div.month b.prev_next.next" 16 | verify element "#test2 div.day[title='2018-1-20']" without class selectable 17 | click "#test2 div.month b.prev_next.prev" 18 | click "#test2 div.day.selectable[title='2017-1-25']" 19 | verify element "#test2 input" value is "2017-01-25" 20 | click "#test2 #set-date" 21 | verify element "#test2 input" value is "2017-12-31" 22 | 23 | 24 | TEST3 25 | click "#test3 input" 26 | verify element "#test3 .month" is not present 27 | verify element "#test3 .days" is not present 28 | verify element "#test3 .time" is visible 29 | 30 | TEST4 31 | verify element "#test4 input" value matches "15/01/2017 15:22 [+-]" 32 | click "#test4 input" 33 | click "#test4 div.day.selectable[title='2017-1-25']" 34 | verify element "#test4 input" value matches "25/01/2017" 35 | 36 | TEST5 37 | verify element "#test5 input" value is "2016-02-15" 38 | see "2015-12-31" 39 | click 40 | verify element "#test5 input" value is "2015-12-31" 41 | click "#test5 input" 42 | click "#test5 div.day.selectable[title='2015-12-30']" 43 | set element "#test5 input.hourInput" value 11 44 | set element "#test5 input.minutesInput" value as 19 45 | click body 46 | verify element "#test5 input" value is "2015-12-30 11:19" 47 | 48 | TEST6 49 | verify element "#test6 input" value is "2017-01-28" 50 | click "#test6 input" 51 | click "#test6 div.month b.prev_next.prev.month" 52 | click "#test6 div.month b.prev_next.next.month" 53 | click "#test6 div.close-button" 54 | verify element "#test6 input" value is "2017-01-28" 55 | 56 | END 57 | close browser 58 | 59 | 60 | --------------------------------------------------------------------------------