import {
Component, OnInit, Input, Output, EventEmitter, SimpleChanges, ChangeDetectionStrategy, OnChanges,
HostListener, ViewChild, ElementRef
} from '@angular/core';
@Component({
selector: 'dc-ng-datepicker',
template: `
{{pickerTitle}}
-
{{yearArray[i]}}年
{{list}}月
{{isChooseTimes?'返回':'时间'}}
确定
现在
时间
时
分
秒
-
{{hours}}
-
{{minutes}}
-
{{seconds}}
`,
styles: [`
ul, li {
list-style: none;
margin: 0;
padding: 0;
}
.date-more {
display: inline-block;
width: 8px;
height: 10px;
border: solid 4px transparent;
border-top-width: 6px;
border-top-color: #fff;
position: relative;
top: 3px;
}
.showYearMonthMore .date-more{
top: 0;
transform:rotate(180deg);
-ms-transform:rotate(180deg); /* Internet Explorer */
-moz-transform:rotate(180deg); /* Firefox */
-webkit-transform:rotate(180deg); /* Safari 和 Chrome */
-o-transform:rotate(180deg); /* Opera */
}
.form-control {
display: block;
width: 100%;
height: 34px;
padding: 0 0 0 5px;
font-size: inherit;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
input.form-control {
border: 1px solid #ccc;
}
input::placeholder {
color: #bbb
}
div.date-picker-box {
position: relative;
display: inline-block;
width: 150px;
}
div.date-picker-input {
position: relative;
display: inline-block;
width: 100%;
background-color: white;
color: #333;
font-size: 12px;
}
div.date-picker-input input {
height: 30px;
border-radius: 3px;
}
div.date-picker-input i.show {
position: absolute;
right: 2px;
top: 0;
font-size: inherit;
cursor: pointer;
width: 20px;
height: 30px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAYklEQVQokdWQUQrAIAxDU9m/O6XHn97A/awQ2w4s+1qgIA3h1UhrDaQB4ESsxSsA5jOsSTNoX3VfTOCN5rzDUCLVyLPEbSlRkjn3Ry6DS3MFfj5VJRvvkPijU1PEDuBK5voNJIwdJa4Jkp0AAAAASUVORK5CYII=) no-repeat center center transparent;
}
div.date-picker-input i.clear {
position: absolute;
right: 22px;
top: 0;
font-size: inherit;
cursor: pointer;
width: 20px;
height: 30px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAOVJREFUKJF90DFKA1EQBuAvj2Cu8MBqe8FokedeQb2A6WzU0uN4gxTbxkM8CKKSfqvAXsAi2lj4dlkh5Icp5p9/Zv6ZSdM0Ck7whDucFW6LFV7wDdNSOMUac/9xVeIet9iFMvmQeIw5XjELeOzFdV2LMQ6qGKO6rvv0HA8By55p21ZKSYxRjFFKSdu2403LKS77rOs6OWcpJZBz1nXduOEiHPF9CD8Bb2PPKSU552HT+CZsg78/g6qqBhu9vaqqxg2rSdM0M+TyhWP4xCJgjxu8HxF/4Br7/ugdEp6xwVeJTeEWReMX1Y9FK/4RDOgAAAAASUVORK5CYII=) no-repeat center center transparent;
}
div.date-picker-input i.clear:hover{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAOtJREFUKJF90b1NAzEcBfBfriCVm2vR3S2ABFXYAViADACUjMMGWQCGQIoQWJngrLTXWBSBIhRxooBCnuTCz++9/4dHMUYFJ3jALc4Kt8AMT/iCUTGc4hkXDuMdN1hWJfmYWHl7wbjC/VbcdZ0Qwk4VQtB13fZ6jrsK0y0zDIO2bYUQhBA0TWMYhv1K01GMcVXa2qW2bWu9XkspyTnvG1bVkb4P4bvC29/0vu+llDRN82smLCqbPYO6rvV9L+cs5yylpK7rfcNsFGMc47Vs4RgiJhVWuLb5nP/wgSt7Qy9xiUfM8VnOvHCTovEDCGVJpA/ldQoAAAAASUVORK5CYII=) no-repeat center center transparent;
}
div.date-picker {
position: absolute;
width: auto;
min-height: 220px;
background-color: white;
border: 1px #ccc solid;
z-index: 1000;
right: 0;
border-radius: 5px;
}
div.date-picker.offset-left {
right: auto;
left: 0;
}
.years-month-ul {
position: absolute;
width: 150px;
top: 30px;
right: 0;
margin-right: 40px;
background-color: white;
box-shadow: 0 0 5px gray;
z-index: 1001;
}
.years-month-ul li {
height: 22px;
display: flex;
line-height: 22px;
}
.years-month-ul li span {
width: 50%;
align-items: center;
justify-content: center;
text-align: center;
cursor: pointer;
font-size: 12px;
border-radius: 3px;
color: #212529;
}
.years-month-ul li span:hover {
background-color: #eeeeee;
}
.years-month-ul li span.selected {
background-color: #2bb1ff;
color: #fff;
}
.nav-bar ul {
list-style: none;
padding-top: 10px;
padding-left: 10px;
}
.nav-bar ul li {
font-size: 13px;
background: #f5f5f5;
border: 1px solid #f5f5f5;
border-radius: 4px;
color: #1165E5;
padding: 3px 12px;
margin-bottom: 8px;
}
.nav-bar ul li.active, .nav-bar ul li:hover {
background: #2bb1ff;
border: 1px solid #2bb1ff;
color: #ffffff;
}
div.calendar .control-bar,.times-title {
width: 100%;
display: flex;
height: 35px;
align-items: center;
justify-content: center;
background-color: #2bb1ff;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
color:#fff;
}
div.calendar .control-bar .material-icons {
cursor: pointer;
font-size: 21px;
margin: 2px;
display: flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
font-weight: bold;
opacity: 0.7;
}
div.calendar .control-bar .material-icons:hover{
/*opacity: 1;*/
}
div.calendar .control-bar .material-icons.de-year {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAH5JREFUKJGd0jsOwjAQRVHvgm/S0rD/KgWbgIQItsKhYCIlMJGQLbm5z9eyZ6agJHuHDqeMZcIeg8+6ZOxbOOAe4RCHf9hcOGKMsI/nZKxMQoNHhDdsV1iZpAbPCK/YrLAyl7oIXzhHkLGF1Ca3ZmwhVf2punrVfaqeiL9m7w36Lzv4T8TJHwAAAABJRU5ErkJggg==) no-repeat center center transparent;
}
div.calendar .control-bar .material-icons.de-month {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAANCAYAAACUwi84AAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAGtJREFUGJWN0TEOwjAMBVDfAlqgaxfuPzFwCaCt4Cp9DDhSVSo1kTw9xf5xArFRDW7ot7DF4HfuazxhTBzQLvGMKfGVY6LgBe/EJ47lYsFP4gOH5djItDDjug4d6PY67GaoekXVHqo2+fcXX7YeWEIOj0dbAAAAAElFTkSuQmCC) no-repeat center center transparent;
}
div.calendar .control-bar .material-icons.in-month {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAANCAYAAACUwi84AAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAHJJREFUGJWF0T0OwjAMBlDfovyvnbj/1IFDAC2Cq/R1wENICkTKEOXF+uwEegzYIuoduHivEbs1sMeUaMrzB4h8OSZ64FCDyAz3RE8caxDY4JbohVOTGmfMiYb6ssP1W4WyfJOhDNh0Uba4Ooe/k/z5Fwscj1hR3883OgAAAABJRU5ErkJggg==) no-repeat center center transparent;
}
div.calendar .control-bar .material-icons.in-year {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAI5JREFUKJGl0jsSwjAMhGHdgjctFfevUnAIHmHgKnwUKBmSKAWDZ1T4964trx04oMEKkVWxvgInn3HDOhcqNjBt0KaozXnFBqbI3W4pumM7wwamyP6vKXpgN8NifMklLil6Yl+xSTI44pWipmJjwwLn0UkTNtda13/FogqhS6pifXrf0XZvUrH/f8TPf+8N2YY8FsbUCEUAAAAASUVORK5CYII=) no-repeat center center transparent;
}
div.calendar .control-bar .monthTitle {
font-size: inherit;
font-weight: normal;
width: 160px;
color: #fff;
text-align: center;
cursor: pointer;
height: 30px;
line-height: 30px;
}
div.calendar .control-bar .monthTitle:hover .date-more {
color: #fff;
border-top-color: #fff;
}
div.calendar .days {
width: 100%;
align-items: center;
justify-content: center;
display: flex;
font-size: inherit;
}
table {
border-spacing: 0;
}
th, td {
text-align: center;
position: relative;
font-weight: normal;
}
th {
color: #333;
}
tr > td.disabled {
color: #999999;
text-decoration: line-through;
cursor: not-allowed;
}
tr > td.range {
background-color: #ebf4f8;
border-color: transparent;
}
tr > td.active, tr > td.active:hover {
border-radius: 4px;
background-color: #2bb1ff !important;
color: white;
}
.date {
width: 30px;
height: 30px;
text-align: center;
line-height: 30px;
}
.cancelArea {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
z-index: 9;
}
.pointer {
cursor: pointer;
}
.pull-left {
float: left !important;
}
.times{
width: 90%;
margin-left: 5%;
border-top:1px #ccc solid;
margin-top:8px;
padding:8px 0;
}
.times span{
line-height:28px;
padding:0 8px;
display:inline-block;
background-color:#2bb1ff;
border-radius: 4px;
color: #fff;
cursor: pointer;
}
.times span.times-now,.times span.times-sure{
float: right;
}
.times-now{
margin-right:2px;
}
.choose-times{
position: absolute;
width: 230px;
min-height: 245px;
background-color: #fff;
border-left: 1px #ccc solid;
border-top: 1px #ccc solid;
border-right: 1px #ccc solid;
z-index: 1001;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.times-cont{
float: left;
width:90%;
margin-left:5%;
}
.times-tip{
width:100%;
float:left;
}
.times-tip span{
text-align: center;
line-height: 30px;
width: 32%;
display: inline-block;
}
.times-list{
width:100%;
float: left;
border-top:1px #ccc solid;
border-left:1px #ccc solid;
border-bottom:1px #ccc solid;
height:168px;
}
.times-list li{
width:33%;
float: left;
text-align: center;
height: 100%;
border-right: 1px #ccc solid;
overflow-y: scroll;
position:relative;
}
.list-cont{
position: absolute;
left:0;
top:auto;
}
.times-list li span{
line-height:24px;
display: inline-block;
font-size: 12px;
cursor: pointer;
width:100%;
}
.times-list li span:hover{
background-color: #eef9ff;
color: #2bb1ff;
}
.times-list li span.active{
background-color: #2bb1ff;
color: #fff;
}
`],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class NgDatepickerComponent implements OnInit, OnChanges {
@Input() width: string;
@Input() toph: string;
@Input() initDate: any;
@Input() isHidden: boolean;
@Input() defaultShow: boolean;
@Input() minDate: Date;
@Input() maxDate: Date;
@Input() disabledDates: any[];
@Input() availableDates: any[];
@Input() displayDateType: boolean;
@Input() quickDateBars: QuickDateBar[];
@Input() selectedQuickDateBar: QuickDateBar;
@Input() daysOfWeekDisabled: number[] = [];
@Input() language: string;
@Input() placeholder: string;
@Input() offset: string;
@Input() format: string;
@Input() now: boolean;
@ViewChild('datePickerBox') datePickerBox: ElementRef;
@Output() ngModelChange: EventEmitter = new EventEmitter();
changeDateFlag = false;
weekTitleEn = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
weekTitleZh = ['日', '一', '二', '三', '四', '五', '六'];
showYearMonth: boolean = false;
monthArray: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
yearArray: Array = [];
displayDate: string = null;
dates: Array = [[]];
hoursArray: Array = [];
minutesArray: Array = [];
curHours:number=0;
curMinutes:number=0;
curSeconds:number=0;
titleYear: number;
titleMonth: number;
pickerTitle: string;
hours:number=0;
minutes:number=0;
seconds:number=0;
today: Date;
monthDays: number[] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
monthFullName: string[] =
['January', 'Febuary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
monthName: string[] =
['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
_minDate: Date = new Date('01/01/1900');
_maxDate: Date = new Date('12/31/2117');
_disabledDates: (Date | string)[];
_availableDates: (Date | string)[];
_daysOfWeekDisabled: number[];
minYear: number;
minMonth: number;
maxYear: number;
maxMonth: number;
selectedDate: SelectedDate;
outputDate: OutputDate;
startDate: Date;
endDate: Date;
hasSelectedBar: boolean;
hasInitDate: boolean;
isInited: boolean;
isFormat: boolean=false;
isChooseTimes: boolean=false;
constructor() {
if (this.isHidden === undefined) {
this.isHidden = true;
}
this.createEmptyDatePicker();
}
ngOnInit() {
this.minDate = this.minDate || new Date('1900/01/01');
this.maxDate = this.maxDate || new Date('2117/12/31');
if (!this.isInited) {
let times = new Date() > this.minDate ? new Date() : this.minDate;
this.initDatePicker(times);
}
if(this.format){
let formatArr = this.format.split(" ");
if(formatArr.length==2){
this.isFormat = true;
this.displayDate = this.initDate;
for(let i=0;i<24;i++){
if(i<10){
this.hoursArray[i]= '0' + i;
}else{
this.hoursArray[i]='' + i;
}
}
for(let j=0;j<60;j++){
if(j<10){
this.minutesArray[j] = '0' + j;
}else{
this.minutesArray[j] = '' + j;
}
}
}
}
}
@HostListener('document:click', ['$event'])
onDocumentClick(ev: any) {
if (!this.datePickerBox.nativeElement.contains(ev.target)) {
if (!this.isHidden) {
this.isChooseTimes = false;
this.toggleCalendar(true);
}
}
}
ngOnChanges(changes: SimpleChanges) {
if (changes['selectedQuickDateBar']) this.hasSelectedBar = true;
if (changes['initDate']) this.hasInitDate = true;
if (changes['selectedQuickDateBar'] && changes['selectedQuickDateBar'].currentValue) {
if (!this.hasInitDate && !this.isInited) {
this.initDatePicker(new Date());
}
if (this.hasInitDate) {
this.setAvailableDates(this.selectedQuickDateBar);
} else {
this.selectBar(this.selectedQuickDateBar);
}
}
if (changes['maxDate'] && changes['maxDate'].currentValue) {
this._maxDate = this.maxDate;
}
if (changes['minDate'] && changes['minDate'].currentValue) {
this._minDate = this.minDate;
}
if (changes['availableDates'] && changes['availableDates'].currentValue) {
this._availableDates = this.availableDates;
}
if (changes['disabledDates'] && changes['disabledDates'].currentValue) {
this._disabledDates = this.disabledDates;
}
if (changes['daysOfWeekDisabled'] && changes['daysOfWeekDisabled'].currentValue) {
this._daysOfWeekDisabled = this.daysOfWeekDisabled;
}
if (changes['initDate'] && changes['initDate'].currentValue) {
this.changeDateFlag = true;
let _initDate: Date;
let ieInitDate;
let ieInitArr;
let dateStr = this.initDate.toString();
let newYear = new Date().getFullYear();
let newDay = new Date().getDate();
if (dateStr.indexOf('/') < 0 && dateStr.indexOf('-') < 0 && dateStr.indexOf('月') < 0) {
if (dateStr.length == 6 || dateStr.length == 5) { // 201903 20193
ieInitDate = dateStr.substr(0,4) + '/' + dateStr.substring(4);
} else if (dateStr.length == 4) { // 0321
ieInitDate = newYear + '/' + dateStr.substr(0,2) + '/' + dateStr.substr(2,2);
} else { // 20190321
ieInitDate = dateStr.substr(0,4) + '/' + dateStr.substr(4,2) + '/' + dateStr.substr(6,2);
}
} else if (dateStr.indexOf('月') > -1) {
if (dateStr.indexOf('日') < 0) { // 2019年03月
ieInitDate = dateStr.substr(0,4) + '/' + dateStr.substring(5, dateStr.length - 1);
} else if (dateStr.indexOf('年') < 0) { // 03月22日
ieInitDate = newYear + '/' + dateStr.substr(0,2) + '/' + dateStr.substr(3,2);
} else { // 2019年03月21日
ieInitDate = dateStr.substr(0,4) + '/' + dateStr.split('年')[1].split('月')[0] + '/' + dateStr.split('月')[1].split('日')[0];
}
} else { // 2019-03-21 或者 2019/03/21 或者 2019-03 或者 03/21
if (dateStr.length == 5) {
ieInitDate = newYear + '/' + dateStr.substr(0,2) + '/' + dateStr.substr(3,2);
} else {
ieInitDate = dateStr.replace(/-/g,"/");
}
}
ieInitArr = ieInitDate.split('/');
let len = ieInitArr.length;
let day = len == 2 ? newDay : ieInitArr[2];
_initDate = new Date(ieInitArr[0],(ieInitArr[1]-1),day);
if (!_initDate.getMonth()) {
_initDate = new Date();
}
this.initDatePicker(_initDate);
this.selectionEmitter(new Day(_initDate.getDate()));
}
}
decreaseYear() {
// 向前推年份
this.yearArray = this.calcYear(this.yearArray[0] - 12);
}
increaseYear() {
// 向后推年份
this.yearArray = this.calcYear(this.yearArray[this.yearArray.length - 1] + 1);
}
selectMonth(ev: any, month: number) {
this.titleMonth = month;
this.showYearMonth = false;
this.pickerTitle = this.renderTitle();
this.calCalendar();
}
selectYear(ev: any, year: number) {
this.titleYear = year;
this.pickerTitle = this.renderTitle();
}
calcYear(minYear: number) {
let tempArray: Array = [minYear];
for (let i = 0; i < 11; i++) {
tempArray.push(minYear + i + 1);
}
return tempArray;
}
clearDate() {
this.selectionEmitter(new Day(Date.now()), true);
}
selectYearMonth() {
this.yearArray = this.calcYear(this.titleYear - 5);
this.showYearMonth = !this.showYearMonth;
// todo 设置年月
// this.titleYear = 2017;
// this.titleMonth = 7;
//
// this.pickerTitle = this.renderTitle();
// this.calCalendar();
}
createEmptyDatePicker(): void {
for (let i = 0; i < 6; i++) {
this.dates.push([]);
for (let j = 0; j < 7; j++) {
this.dates[i].push();
}
}
}
initDatePicker(date: Date): void {
let today: Date = date;
this.titleYear = today.getFullYear();
this.titleMonth = today.getMonth() + 1;
this.pickerTitle = this.renderTitle();
this.curHours = this.hours = today.getHours();
this.curMinutes = this.minutes = today.getMinutes();
this.curSeconds = this.seconds = today.getSeconds();
this.selectedDate = new SelectedDate(today.getFullYear(), today.getMonth() + 1, today.getDate(),today.getHours(),today.getMinutes(),today.getSeconds());
this.calCalendar();
this.initInput();
if (!this.hasInitDate && !this.hasSelectedBar) {
this.selectionEmitter(new Day(today.getDate()), true);
}
this.isInited = true;
}
clearDateByOther() {
this.changeDateFlag = true;
this.selectionEmitter(new Day(Date.now()), true);
}
//点击现在
timenow(){
this.isHidden = true;
this.isChooseTimes = false;
let timeDate = new Date();
this.displayDate = timeDate.getFullYear() + '-' + (timeDate.getMonth()+1) + '-' +
this.toZero(timeDate.getDate()) + ' ' + this.toZero(timeDate.getHours()) + ':' + this.toZero(timeDate.getMinutes()) + ':' + this.toZero(timeDate.getSeconds());
}
toZero(num:number){
if(num<10){
return '0'+num;
}else{
return num;
}
}
//点击时间
showTimes(){
this.isChooseTimes = !this.isChooseTimes;
}
//点击确定
timeSure(){
this.isHidden = true;
this.isChooseTimes = false;
this.timeChange();
}
//改变时间
timeChange(){
let resArr = this.displayDate.split(' ');
this.displayDate = resArr[0] + ' ' + this.toZero(this.curHours) + ':' + this.toZero(this.curMinutes) + ':' + this.toZero(this.curSeconds);
this.outputEvent();
}
//选择小时
chooseHours(i:number){
this.curHours = i;
this.timeChange();
}
//选择分钟
chooseMinutes(i:number){
this.curMinutes = i;
this.timeChange();
}
//选择秒
chooseSeconds(i:number){
this.curSeconds = i;
this.timeChange();
}
selectionEmitter(d: Day, isInit?: boolean): void {
if(!this.isFormat){
this.isHidden = true;
}
this.startDate = new Date(this.titleMonth + '/' + d.date + '/' + this.titleYear);
this.endDate = null;
this.selectedDate = new SelectedDate(this.titleYear, this.titleMonth, d.date,this.hours,this.minutes,this.seconds);
if (isInit) {
this.displayDate = '';
} else {
/*this.displayDate = (this.displayDateType && this.selectedQuickDateBar ? this.selectedQuickDateBar.value : '')
+ (this.selectedDate.day < 10 ? ('0' + this.selectedDate.day) : this.selectedDate.day)
+ '-' + this.monthName[this.selectedDate.month - 1] + '-' + this.selectedDate.year;*/
this.displayDate = (this.displayDateType && this.selectedQuickDateBar ? this.selectedQuickDateBar.value : '')
+ this.selectedDate.year + '-' + (this.selectedDate.month) + '-'
+ (this.selectedDate.day < 10 ? ('0' + this.selectedDate.day) : this.selectedDate.day);
if(this.isFormat){
this.displayDate += ' '
+ (this.selectedDate.hours < 10 ? ('0' + this.selectedDate.hours) : this.selectedDate.hours) + ':'
+ (this.selectedDate.minutes < 10 ? ('0' + this.selectedDate.minutes) : this.selectedDate.minutes) + ':'
+ (this.selectedDate.seconds < 10 ? ('0' + this.selectedDate.seconds) : this.selectedDate.seconds);
}
}
this.outputEvent();
}
selectDate(d: Day): void {
this.showYearMonth = false;
if (!d.isDisabled) {
if (d.num > 0) this.increaseMonth();
if (d.num < 0) this.decreaseMonth();
this.selectionEmitter(d);
}
}
isDateSelected(d: Day): boolean {
// const date: Date = new Date((this.titleMonth + (d.num | 0)) + '/' + d.date + '/' + this.titleYear);
const date: Date = new Date((d.month + (d.num || 0)) + '/' + d.date + '/' + d.year);
d.isSelected = (this.startDate && this.startDate.getTime() === date.getTime()) || (this.endDate && this.endDate.getTime() === date.getTime());
d.isInRange = (this.startDate && this.startDate.getTime() < date.getTime()) && (this.endDate && this.endDate.getTime() > date.getTime());
d.isDisabled = this.isDateDisbalbed(date);
return d.isSelected;
}
isDateDisbalbed(date: Date): boolean {
if (date.getTime() > this.maxDate.getTime() || date.getTime() < this.minDate.getTime()) {
return true;
}
if (this.disabledDates && this.disabledDates.length > 0
&& this.disabledDates.filter((disabledDate: any) => date.getTime() === new Date(disabledDate).getTime()).length > 0) {
return true;
}
if (this.availableDates && this.availableDates.length > 0
&& this.availableDates.filter((availableDate: any) => date.getTime() === new Date(availableDate).getTime()).length === 0) {
return true;
}
if (this.daysOfWeekDisabled && this.daysOfWeekDisabled.length > 0
&& this.daysOfWeekDisabled.indexOf(date.getDay()) > -1) {
return true;
}
return false;
}
/**
* Formate displaying month to full name
*/
renderTitle(): string {
return this.titleYear + '年 ' + this.titleMonth + '月';
}
initInput(): void {
this.maxYear = this.maxDate && this.maxDate.getFullYear();
this.maxMonth = this.maxDate && this.maxDate.getMonth() + 1;
this.minYear = this.minDate && this.minDate.getFullYear();
this.minMonth = this.minDate && this.minDate.getMonth() + 1;
}
calCalendar(): void {
this.clearCalendar();
let startTime: Date = new Date(this.titleMonth + '/01/' + this.titleYear);
let startDay: number = startTime.getDay();
let monthDays: number = this.calMonthEndDay(this.titleYear, this.titleMonth, 0);
for (let i = 0, k = 1, l = 1; i < 6; i++) {
if (i === 0) {
for (let j = 0; j < 7; j++) {
let temp = null;
if (j < startDay) {
let lastMonthEndDay: number = this.calMonthEndDay(this.titleYear, this.titleMonth, -1);
let lastDay: number = lastMonthEndDay - startDay + j + 1;
temp = new Day(lastDay, -1, this.isHoliday(this.titleYear, this.titleMonth, lastDay, -1), false, this.isSelectedDay(this.titleYear, this.titleMonth, lastDay, -1));
if (this.titleMonth == 1) {
temp.year = this.titleYear - 1;
temp.month = 13;
temp.num = -1;
} else {
temp.year = this.titleYear;
temp.month = this.titleMonth;
}
this.dates[i][j] = temp;
} else {
temp = new Day(k, 0, this.isHoliday(this.titleYear, this.titleMonth, k, 0), true, this.isSelectedDay(this.titleYear, this.titleMonth, k, 0));
temp.year = this.titleYear;
temp.month = this.titleMonth;
this.dates[i][j] = temp;
k++;
}
}
} else {
for (let j = 0; j < 7; j++ , k++) {
let temp = null;
if (k > monthDays) {
temp = new Day(l, 1, this.isHoliday(this.titleYear, this.titleMonth, l, 1), false, this.isSelectedDay(this.titleYear, this.titleMonth, l, 1));
if (this.titleMonth == 12) {
temp.year = this.titleYear + 1;
temp.month = 1;
temp.num = 1;
} else {
temp.year = this.titleYear;
temp.month = this.titleMonth;
}
this.dates[i][j] = temp;
l++;
} else {
temp = new Day(k, 0, this.isHoliday(this.titleYear, this.titleMonth, k, 0), true, this.isSelectedDay(this.titleYear, this.titleMonth, k, 0));
temp.year = this.titleYear;
temp.month = this.titleMonth;
this.dates[i][j] = temp;
}
}
}
}
}
increaseMonth(): void {
this.titleMonth++;
if (this.titleMonth === 13) {
this.titleYear++;
this.titleMonth = 1;
}
this.pickerTitle = this.renderTitle();
this.calCalendar();
}
decreaseMonth(): void {
this.titleMonth--;
if (this.titleMonth === 0) {
this.titleYear--;
this.titleMonth = 12;
}
this.pickerTitle = this.renderTitle();
this.calCalendar();
}
isSelectedDay(y: number, m: number, d: number, num: number): boolean {
let year: number = y;
let month: number = m + num;
if (month === 0) {
year--;
month = 12;
}
if (month === 13) {
year++;
month = 1;
}
if (year !== this.selectedDate.year) return false;
if (month !== this.selectedDate.month) return false;
if (d !== this.selectedDate.day) return false;
return true;
}
isHoliday(y: number, m: number, d: number, num: number): boolean {
let year: number = y;
let month: number = m + num;
if (month === 0) {
year--;
month = 12;
}
if (month === 13) {
year++;
month = 1;
}
let day = new Date(month + '/' + d + '/' + year);
if (day.getDay() === 0 || day.getDay() === 6) return true;
return false;
}
calMonthEndDay(y: number, m: number, num: number): number {
let year: number = y;
let month: number = m + num;
if (month === 0) {
year--;
month = 12;
}
if (month === 13) {
year++;
month = 1;
}
return (year % 4 === 0) && (month === 2) ? this.monthDays[month - 1] + 1 : this.monthDays[month - 1];
}
clearCalendar(): void {
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 7; j++) {
this.dates[i][j] = null;
}
}
}
resetCalendar(year: number, month: number): void {
this.titleMonth = month;
this.titleYear = year;
// if (this.titleMonth === 12) {
// this.titleYear++;
// this.titleMonth = 1;
// }
if (this.titleMonth === 0) {
this.titleYear--;
this.titleMonth = 12;
}
this.pickerTitle = this.renderTitle();
this.calCalendar();
}
selectBar(bar: QuickDateBar): void {
if (bar.startDate && bar.endDate) {
this.startDate = bar.startDate;
this.endDate = bar.endDate;
this.displayDate = (this.displayDateType ? bar.value : '')
+ this.renderDisplayDate(this.startDate) + ' - ' + this.renderDisplayDate(this.endDate);
} else {
this.startDate = bar.date || bar.startDate || bar.endDate;
this.endDate = null;
this.displayDate = (this.displayDateType ? bar.value : '') + this.renderDisplayDate(this.startDate);
}
this.isHidden = true;
this.resetCalendar(this.startDate.getFullYear(), this.startDate.getMonth() + 1);
this.selectedQuickDateBar = bar;
this.outputEvent();
}
setAvailableDates(bar: QuickDateBar): void {
this.maxDate = (bar && bar.maxDate) ? bar.maxDate : this._maxDate;
this.minDate = (bar && bar.minDate) ? bar.minDate : this._minDate;
this.disabledDates = (bar && bar.disabledDates) ? bar.disabledDates : this._disabledDates;
this.availableDates = (bar && bar.availableDates) ? bar.availableDates : this._availableDates;
this._daysOfWeekDisabled = (bar && bar.daysOfWeekDisabled) ? bar.daysOfWeekDisabled : this._daysOfWeekDisabled;
this.initInput();
}
isBarSelected(bar: QuickDateBar): boolean {
return this.selectedQuickDateBar === bar;
}
renderDisplayDate(date: Date): string {
if (date)
return (date.getDate() < 10 ? ('0' + date.getDate()) : date.getDate()) + '-' + this.monthName[date.getMonth()] + '-' + date.getFullYear();
}
toggleCalendar(isHidden?: boolean): void {
if (this.showYearMonth) {
this.showYearMonth = false;
}
this.isHidden = isHidden ? isHidden : !this.isHidden;
if (this.isHidden && this.startDate && this.startDate.toString() !== 'Invalid Date') {
this.resetCalendar(this.startDate.getFullYear(), this.startDate.getMonth() + 1);
}
}
outputEvent(): void {
this.outputDate = {
date: this.startDate,
startDate: this.startDate,
endDate: this.endDate,
dateType: this.selectedQuickDateBar,
dateStr: this.startDate?this.startDate.getFullYear() + '-' + this.toZero(this.startDate.getMonth()+1) + '-' + this.toZero(this.startDate.getDate()):'',
startDateStr: this.startDate?this.startDate.getFullYear() + '-' + this.toZero(this.startDate.getMonth()+1) + '-' + this.toZero(this.startDate.getDate()):'',
endDateStr: this.endDate?this.endDate.getFullYear() + '-' + this.toZero(this.endDate.getMonth()+1) + '-' + this.toZero(this.endDate.getDate()):''
};
if(this.isFormat){
this.outputDate.time = this.toZero(this.curHours) + ':' + this.toZero(this.curMinutes) + ':' + this.toZero(this.curSeconds);
}
if (!this.changeDateFlag) {
this.ngModelChange.emit(this.outputDate);
}
this.changeDateFlag = false;
}
}
export class Day {
constructor(public date: number,
public num?: number,
public isHoliday?: boolean,
public isInMonth?: boolean,
public isSelected?: boolean,
public isInRange?: boolean,
public isDisabled?: boolean,
public year?: number,
public month?: number) {
}
}
export class SelectedDate {
constructor(public year: number,
public month: number,
public day: number,
public hours: number,
public minutes: number,
public seconds: number) {
}
}
export interface QuickDateBar {
date?: Date;
startDate?: Date;
endDate?: Date;
minDate?: Date;
maxDate?: Date;
disabledDates?: (Date | string)[];
availableDates?: (Date | string)[];
daysOfWeekDisabled?: number[];
label?: string;
value?: string;
monthly?: true;
children?: QuickDateBar;
}
export interface OutputDate {
date?: Date;
startDate?: Date;
endDate?: Date;
dateType?: QuickDateBar;
time?: String;
dateStr?: String;
startDateStr?: String;
endDateStr?: String;
}