Compare commits

...

25 Commits

Author SHA1 Message Date
Faris Ansari
ed37b94d95
Merge pull request #1 from gbm001/fix_seconds
fix: Fix display of seconds between 0 and 9.
2019-03-14 20:59:49 +05:30
Andrew McLeod
e5307a4037 fix: Fix display of seconds between 0 and 9. 2019-01-21 17:11:52 +00:00
Faris Ansari
7911fb1de7 added seconds in timepicker 2016-12-31 21:23:00 +05:30
t1m0n
004188d948 v2.2.3 2016-09-26 10:54:54 +03:00
t1m0n
9bd8b00110 fixed min/max dates in decade mode, fixes #125 2016-09-26 10:50:00 +03:00
t1m0n
f59bf95d34 v2.2.2 2016-09-21 12:31:32 +03:00
t1m0n
ec46ba154e fixed min max dates handling, closes #123 2016-09-21 12:27:33 +03:00
t1m0n
28c56d2cf4 v2.2.1, fixes #118 2016-09-17 20:43:33 +03:00
t1m0n
590dc25664 updated jquery version to range 2016-09-17 20:37:55 +03:00
t1m0n
a4000953e5 simplified RegExp for matching date parts, fixes #120 2016-09-17 20:34:06 +03:00
t1m0n
e412c9cffe version v2.2.0 2016-08-28 16:21:59 +03:00
t1m0n
eca97ca219 added Slovak language to src 2016-08-28 16:05:38 +03:00
t1m0n
e1547c753a Merge branch 'RobiNN1-patch-2' 2016-08-28 16:04:02 +03:00
t1m0n
203ecea090 Merge branch 'patch-2' of https://github.com/RobiNN1/air-datepicker into RobiNN1-patch-2 2016-08-28 16:03:41 +03:00
t1m0n
354896e97b modified English docs 2016-08-28 15:59:22 +03:00
t1m0n
ee143e5dc4 modified Russian docs 2016-08-28 15:45:48 +03:00
t1m0n
701df87dbe changed handling of selection of already selected dates, closes #105
Now for selecting single date in range mode, `toggleSelected` must be `false`
2016-08-28 14:43:26 +03:00
t1m0n
e8facd22b0 added onlyTimepicker option, closes #102, #75, #108 2016-08-28 13:16:14 +03:00
t1m0n
d3a578daab begin onlyTimepicker feature 2016-08-18 11:26:24 +03:00
t1m0n
2440a1168b fixed range slider hour value in 12hrs mode, fixes #102 2016-08-18 10:40:21 +03:00
t1m0n
d38e51532e remove second call of onRenderCell callback, fixes #96 2016-08-16 10:27:12 +03:00
t1m0n
a71611bde3 added onShow & onHide events, resolves #95 2016-08-11 14:01:18 +03:00
t1m0n
42f6d4c76d added 'á' symbol to word boundary regexp, fixes #92 2016-08-11 12:30:47 +03:00
t1m0n
ea1806c4ce added VERSION to prototype 2016-08-11 12:18:05 +03:00
RobiNN1
82ed085934 Add new language 2016-08-01 19:33:43 +02:00
29 changed files with 3200 additions and 2543 deletions

View File

@ -26,6 +26,28 @@ $('.my-datepicker').datepicker([options])
## Change log ## Change log
### v2.2.3
* fixed min,max dates in decade mode
### v2.2.2
* fixed min,max dates handling
### v2.2.1
* changed RegExp for recognizing date parts
* changed jquery version dependency
### v2.2.0
* added `onlyTimepicker` option
* added `onShow` and `onHide` callbacks
* added `VERSION` field to plugin's prototype
* now for selecting same date in `range` mode, you should set `{toggleSelected: false}`
* fixed `dateFormat` method (fixed wrong month name in Hungarian language)
* fixed second call of `onRenderCallback`
* fixed `_getCell()` throwing exception
* new language:
- `sk` thanks to [RobiNN1](https://github.com/RobiNN1)
### v2.1.0 ### v2.1.0
* added possibility to select single date when `{range: true}` * added possibility to select single date when `{range: true}`
* added support of 12 hours mode in `altFieldDateFormat` * added support of 12 hours mode in `altFieldDateFormat`

View File

@ -1,6 +1,6 @@
{ {
"name": "air-datepicker", "name": "air-datepicker",
"version": "2.1.0", "version": "2.2.3",
"authors": [ "authors": [
"t1m0n <t1m0n.tr@gmail.com>" "t1m0n <t1m0n.tr@gmail.com>"
], ],
@ -30,6 +30,6 @@
"tests" "tests"
], ],
"dependencies": { "dependencies": {
"jquery": "^3.0.0" "jquery": ">=2.0.0 <4.0.0"
} }
} }

View File

@ -18,31 +18,46 @@
background: none; background: none;
border: none; } border: none; }
.datepicker--cell-day.-other-month-, .datepicker--cell-year.-other-decade- {
color: #dedede; }
.datepicker--cell-day.-other-month-:hover, .datepicker--cell-year.-other-decade-:hover {
color: #c5c5c5; }
.-disabled-.-focus-.datepicker--cell-day.-other-month-, .-disabled-.-focus-.datepicker--cell-year.-other-decade- {
color: #dedede; }
.-selected-.datepicker--cell-day.-other-month-, .-selected-.datepicker--cell-year.-other-decade- {
color: #fff;
background: #a2ddf6; }
.-selected-.-focus-.datepicker--cell-day.-other-month-, .-selected-.-focus-.datepicker--cell-year.-other-decade- {
background: #8ad5f4; }
.-in-range-.datepicker--cell-day.-other-month-, .-in-range-.datepicker--cell-year.-other-decade- {
background-color: rgba(92, 196, 239, 0.1);
color: #cccccc; }
.-in-range-.-focus-.datepicker--cell-day.-other-month-, .-in-range-.-focus-.datepicker--cell-year.-other-decade- {
background-color: rgba(92, 196, 239, 0.2); }
.datepicker--cell-day.-other-month-:empty, .datepicker--cell-year.-other-decade-:empty {
background: none;
border: none; }
/* ------------------------------------------------- /* -------------------------------------------------
Datepicker cells Datepicker cells
------------------------------------------------- */ ------------------------------------------------- */
.datepicker--cells { .datepicker--cells {
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-flex-wrap: wrap; -ms-flex-wrap: wrap;
-ms-flex-wrap: wrap; flex-wrap: wrap; }
flex-wrap: wrap; }
.datepicker--cell { .datepicker--cell {
border-radius: 4px; border-radius: 4px;
box-sizing: border-box; box-sizing: border-box;
cursor: pointer; cursor: pointer;
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
position: relative; position: relative;
-webkit-align-items: center; -ms-flex-align: center;
-ms-flex-align: center; align-items: center;
align-items: center; -ms-flex-pack: center;
-webkit-justify-content: center; justify-content: center;
-ms-flex-pack: center;
justify-content: center;
height: 32px; height: 32px;
z-index: 1; } z-index: 1; }
.datepicker--cell.-focus- { .datepicker--cell.-focus- {
@ -91,28 +106,22 @@
cursor: default; } cursor: default; }
.datepicker--days-names { .datepicker--days-names {
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-flex-wrap: wrap; -ms-flex-wrap: wrap;
-ms-flex-wrap: wrap; flex-wrap: wrap;
flex-wrap: wrap;
margin: 8px 0 3px; } margin: 8px 0 3px; }
.datepicker--day-name { .datepicker--day-name {
color: #FF9A19; color: #FF9A19;
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-align-items: center; -ms-flex-align: center;
-ms-flex-align: center; align-items: center;
align-items: center; -ms-flex-pack: center;
-webkit-justify-content: center; justify-content: center;
-ms-flex-pack: center; -ms-flex: 1;
justify-content: center; flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
text-align: center; text-align: center;
text-transform: uppercase; text-transform: uppercase;
font-size: .8em; } font-size: .8em; }
@ -181,29 +190,20 @@
position: absolute; position: absolute;
left: -100000px; left: -100000px;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease, left 0s 0.3s, -webkit-transform 0.3s ease;
transition: opacity 0.3s ease, transform 0.3s ease, left 0s 0.3s; transition: opacity 0.3s ease, transform 0.3s ease, left 0s 0.3s;
transition: opacity 0.3s ease, transform 0.3s ease, left 0s 0.3s, -webkit-transform 0.3s ease;
z-index: 100; } z-index: 100; }
.datepicker.-from-top- { .datepicker.-from-top- {
-webkit-transform: translateY(-8px); transform: translateY(-8px); }
transform: translateY(-8px); }
.datepicker.-from-right- { .datepicker.-from-right- {
-webkit-transform: translateX(8px); transform: translateX(8px); }
transform: translateX(8px); }
.datepicker.-from-bottom- { .datepicker.-from-bottom- {
-webkit-transform: translateY(8px); transform: translateY(8px); }
transform: translateY(8px); }
.datepicker.-from-left- { .datepicker.-from-left- {
-webkit-transform: translateX(-8px); transform: translateX(-8px); }
transform: translateX(-8px); }
.datepicker.active { .datepicker.active {
opacity: 1; opacity: 1;
-webkit-transform: translate(0); transform: translate(0);
transform: translate(0); transition: opacity 0.3s ease, transform 0.3s ease, left 0s 0s; }
transition: opacity 0.3s ease, left 0s 0s, -webkit-transform 0.3s ease;
transition: opacity 0.3s ease, transform 0.3s ease, left 0s 0s;
transition: opacity 0.3s ease, transform 0.3s ease, left 0s 0s, -webkit-transform 0.3s ease; }
.datepicker-inline .datepicker { .datepicker-inline .datepicker {
border-color: #d7d7d7; border-color: #d7d7d7;
@ -212,8 +212,7 @@
left: auto; left: auto;
right: auto; right: auto;
opacity: 1; opacity: 1;
-webkit-transform: none; transform: none; }
transform: none; }
.datepicker-inline .datepicker--pointer { .datepicker-inline .datepicker--pointer {
display: none; } display: none; }
@ -221,6 +220,8 @@
.datepicker--content { .datepicker--content {
box-sizing: content-box; box-sizing: content-box;
padding: 4px; } padding: 4px; }
.-only-timepicker- .datepicker--content {
display: none; }
.datepicker--pointer { .datepicker--pointer {
position: absolute; position: absolute;
@ -232,20 +233,16 @@
z-index: -1; } z-index: -1; }
.-top-left- .datepicker--pointer, .-top-center- .datepicker--pointer, .-top-right- .datepicker--pointer { .-top-left- .datepicker--pointer, .-top-center- .datepicker--pointer, .-top-right- .datepicker--pointer {
top: calc(100% - 4px); top: calc(100% - 4px);
-webkit-transform: rotate(135deg); transform: rotate(135deg); }
transform: rotate(135deg); }
.-right-top- .datepicker--pointer, .-right-center- .datepicker--pointer, .-right-bottom- .datepicker--pointer { .-right-top- .datepicker--pointer, .-right-center- .datepicker--pointer, .-right-bottom- .datepicker--pointer {
right: calc(100% - 4px); right: calc(100% - 4px);
-webkit-transform: rotate(225deg); transform: rotate(225deg); }
transform: rotate(225deg); }
.-bottom-left- .datepicker--pointer, .-bottom-center- .datepicker--pointer, .-bottom-right- .datepicker--pointer { .-bottom-left- .datepicker--pointer, .-bottom-center- .datepicker--pointer, .-bottom-right- .datepicker--pointer {
bottom: calc(100% - 4px); bottom: calc(100% - 4px);
-webkit-transform: rotate(315deg); transform: rotate(315deg); }
transform: rotate(315deg); }
.-left-top- .datepicker--pointer, .-left-center- .datepicker--pointer, .-left-bottom- .datepicker--pointer { .-left-top- .datepicker--pointer, .-left-center- .datepicker--pointer, .-left-bottom- .datepicker--pointer {
left: calc(100% - 4px); left: calc(100% - 4px);
-webkit-transform: rotate(45deg); transform: rotate(45deg); }
transform: rotate(45deg); }
.-top-left- .datepicker--pointer, .-bottom-left- .datepicker--pointer { .-top-left- .datepicker--pointer, .-bottom-left- .datepicker--pointer {
left: 10px; } left: 10px; }
.-top-right- .datepicker--pointer, .-bottom-right- .datepicker--pointer { .-top-right- .datepicker--pointer, .-bottom-right- .datepicker--pointer {
@ -288,28 +285,25 @@
Navigation Navigation
------------------------------------------------- */ ------------------------------------------------- */
.datepicker--nav { .datepicker--nav {
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-justify-content: space-between; -ms-flex-pack: justify;
-ms-flex-pack: justify; justify-content: space-between;
justify-content: space-between;
border-bottom: 1px solid #efefef; border-bottom: 1px solid #efefef;
min-height: 32px; min-height: 32px;
padding: 4px; } padding: 4px; }
.-only-timepicker- .datepicker--nav {
display: none; }
.datepicker--nav-title, .datepicker--nav-title,
.datepicker--nav-action { .datepicker--nav-action {
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
cursor: pointer; cursor: pointer;
-webkit-align-items: center; -ms-flex-align: center;
-ms-flex-align: center; align-items: center;
align-items: center; -ms-flex-pack: center;
-webkit-justify-content: center; justify-content: center; }
-ms-flex-pack: center;
justify-content: center; }
.datepicker--nav-action { .datepicker--nav-action {
width: 32px; width: 32px;
@ -344,7 +338,6 @@
background: none; } background: none; }
.datepicker--buttons { .datepicker--buttons {
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
padding: 4px; padding: 4px;
@ -354,18 +347,14 @@
color: #4EB5E6; color: #4EB5E6;
cursor: pointer; cursor: pointer;
border-radius: 4px; border-radius: 4px;
-webkit-flex: 1; -ms-flex: 1;
-ms-flex: 1; flex: 1;
flex: 1;
display: -webkit-inline-flex;
display: -ms-inline-flexbox; display: -ms-inline-flexbox;
display: inline-flex; display: inline-flex;
-webkit-justify-content: center; -ms-flex-pack: center;
-ms-flex-pack: center; justify-content: center;
justify-content: center; -ms-flex-align: center;
-webkit-align-items: center; align-items: center;
-ms-flex-align: center;
align-items: center;
height: 32px; } height: 32px; }
.datepicker--button:hover { .datepicker--button:hover {
color: #4a4a4a; color: #4a4a4a;
@ -396,24 +385,22 @@
------------------------------------------------- */ ------------------------------------------------- */
.datepicker--time { .datepicker--time {
border-top: 1px solid #efefef; border-top: 1px solid #efefef;
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-align-items: center; -ms-flex-align: center;
-ms-flex-align: center; align-items: center;
align-items: center;
padding: 4px; padding: 4px;
position: relative; } position: relative; }
.datepicker--time.-am-pm- .datepicker--time-sliders { .datepicker--time.-am-pm- .datepicker--time-sliders {
-webkit-flex: 0 1 138px; -ms-flex: 0 1 138px;
-ms-flex: 0 1 138px; flex: 0 1 138px;
flex: 0 1 138px;
max-width: 138px; } max-width: 138px; }
.-only-timepicker- .datepicker--time {
border-top: none; }
.datepicker--time-sliders { .datepicker--time-sliders {
-webkit-flex: 0 1 153px; -ms-flex: 0 1 153px;
-ms-flex: 0 1 153px; flex: 0 1 153px;
flex: 0 1 153px;
margin-right: 10px; margin-right: 10px;
max-width: 153px; } max-width: 153px; }
@ -422,32 +409,31 @@
font-size: 12px; } font-size: 12px; }
.datepicker--time-current { .datepicker--time-current {
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-align-items: center; -ms-flex-align: center;
-ms-flex-align: center; align-items: center;
align-items: center; -ms-flex: 1;
-webkit-flex: 1; flex: 1;
-ms-flex: 1;
flex: 1;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
margin: 0 0 0 10px; } margin: 0 10px; }
.datepicker--time-current-colon { .datepicker--time-current-colon {
margin: 0 2px 3px; margin: 0 2px 3px;
line-height: 1; } line-height: 1; }
.datepicker--time-current-hours, .datepicker--time-current-hours,
.datepicker--time-current-minutes { .datepicker--time-current-minutes,
.datepicker--time-current-seconds {
line-height: 1; line-height: 1;
font-size: 19px; font-size: 14px;
font-family: "Century Gothic", CenturyGothic, AppleGothic, sans-serif; font-family: "Century Gothic", CenturyGothic, AppleGothic, sans-serif;
position: relative; position: relative;
z-index: 1; } z-index: 1; }
.datepicker--time-current-hours:after, .datepicker--time-current-hours:after,
.datepicker--time-current-minutes:after { .datepicker--time-current-minutes:after,
.datepicker--time-current-seconds:after {
content: ''; content: '';
background: #f0f0f0; background: #f0f0f0;
border-radius: 4px; border-radius: 4px;
@ -459,26 +445,24 @@
z-index: -1; z-index: -1;
opacity: 0; } opacity: 0; }
.datepicker--time-current-hours.-focus-:after, .datepicker--time-current-hours.-focus-:after,
.datepicker--time-current-minutes.-focus-:after { .datepicker--time-current-minutes.-focus-:after,
.datepicker--time-current-seconds.-focus-:after {
opacity: 1; } opacity: 1; }
.datepicker--time-current-ampm { .datepicker--time-current-ampm {
text-transform: uppercase; text-transform: uppercase;
-webkit-align-self: flex-end; -ms-flex-item-align: start;
-ms-flex-item-align: end; align-self: flex-start;
align-self: flex-end;
color: #9c9c9c; color: #9c9c9c;
margin-left: 6px; margin-left: 6px;
font-size: 11px; font-size: 11px;
margin-bottom: 1px; } margin-bottom: 1px; }
.datepicker--time-row { .datepicker--time-row {
display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-align-items: center; -ms-flex-align: center;
-ms-flex-align: center; align-items: center;
align-items: center;
font-size: 11px; font-size: 11px;
height: 17px; height: 17px;
background: linear-gradient(to right, #dedede, #dedede) left 50%/100% 1px no-repeat; } background: linear-gradient(to right, #dedede, #dedede) left 50%/100% 1px no-repeat; }
@ -487,9 +471,8 @@
.datepicker--time-row input[type='range'] { .datepicker--time-row input[type='range'] {
background: none; background: none;
cursor: pointer; cursor: pointer;
-webkit-flex: 1; -ms-flex: 1;
-ms-flex: 1; flex: 1;
flex: 1;
height: 100%; height: 100%;
padding: 0; padding: 0;
margin: 0; margin: 0;
@ -587,30 +570,9 @@
width: 1px; width: 1px;
left: calc(50% - 1px); left: calc(50% - 1px);
top: calc(50% + 1px); top: calc(50% + 1px);
-webkit-transform: translateY(-100%); transform: translateY(-100%); }
transform: translateY(-100%); }
.datepicker--time-icon:before { .datepicker--time-icon:before {
width: .4em; width: .4em;
height: 1px; height: 1px;
top: calc(50% + 1px); top: calc(50% + 1px);
left: calc(50% - 1px); } left: calc(50% - 1px); }
.datepicker--cell-day.-other-month-, .datepicker--cell-year.-other-decade- {
color: #dedede; }
.datepicker--cell-day.-other-month-:hover, .datepicker--cell-year.-other-decade-:hover {
color: #c5c5c5; }
.-disabled-.-focus-.datepicker--cell-day.-other-month-, .-disabled-.-focus-.datepicker--cell-year.-other-decade- {
color: #dedede; }
.-selected-.datepicker--cell-day.-other-month-, .-selected-.datepicker--cell-year.-other-decade- {
color: #fff;
background: #a2ddf6; }
.-selected-.-focus-.datepicker--cell-day.-other-month-, .-selected-.-focus-.datepicker--cell-year.-other-decade- {
background: #8ad5f4; }
.-in-range-.datepicker--cell-day.-other-month-, .-in-range-.datepicker--cell-year.-other-decade- {
background-color: rgba(92, 196, 239, 0.1);
color: #cccccc; }
.-in-range-.-focus-.datepicker--cell-day.-other-month-, .-in-range-.-focus-.datepicker--cell-year.-other-decade- {
background-color: rgba(92, 196, 239, 0.2); }
.datepicker--cell-day.-other-month-:empty, .datepicker--cell-year.-other-decade-:empty {
background: none;
border: none; }

File diff suppressed because one or more lines are too long

233
dist/js/datepicker.js vendored
View File

@ -1,5 +1,6 @@
;(function (window, $, undefined) { ;(function () { ;(function (window, $, undefined) { ;(function () {
var pluginName = 'datepicker', var VERSION = '2.2.3',
pluginName = 'datepicker',
autoInitSelector = '.datepicker-here', autoInitSelector = '.datepicker-here',
$body, $datepickersContainer, $body, $datepickersContainer,
containerBuilt = false, containerBuilt = false,
@ -62,17 +63,23 @@
// timepicker // timepicker
timepicker: false, timepicker: false,
onlyTimepicker: false,
dateTimeSeparator: ' ', dateTimeSeparator: ' ',
timeFormat: '', timeFormat: '',
minHours: 0, minHours: 0,
maxHours: 24, maxHours: 24,
minMinutes: 0, minMinutes: 0,
maxMinutes: 59, maxMinutes: 59,
minSeconds: 0,
maxSeconds: 59,
hoursStep: 1, hoursStep: 1,
minutesStep: 1, minutesStep: 1,
secondsStep: 1,
// events // events
onSelect: '', onSelect: '',
onShow: '',
onHide: '',
onChangeMonth: '', onChangeMonth: '',
onChangeYear: '', onChangeYear: '',
onChangeDecade: '', onChangeDecade: '',
@ -138,6 +145,7 @@
datepicker = Datepicker; datepicker = Datepicker;
datepicker.prototype = { datepicker.prototype = {
VERSION: VERSION,
viewIndexes: ['days', 'months', 'years'], viewIndexes: ['days', 'months', 'years'],
init: function () { init: function () {
@ -154,7 +162,7 @@
this._setPositionClasses(this.opts.position); this._setPositionClasses(this.opts.position);
this._bindEvents() this._bindEvents()
} }
if (this.opts.keyboardNav) { if (this.opts.keyboardNav && !this.opts.onlyTimepicker) {
this._bindKeyboardEvents(); this._bindKeyboardEvents();
} }
this.$datepicker.on('mousedown', this._onMouseDownDatepicker.bind(this)); this.$datepicker.on('mousedown', this._onMouseDownDatepicker.bind(this));
@ -170,6 +178,10 @@
this._bindTimepickerEvents(); this._bindTimepickerEvents();
} }
if (this.opts.onlyTimepicker) {
this.$datepicker.addClass('-only-timepicker-');
}
this.views[this.currentView] = new $.fn.datepicker.Body(this, this.currentView, this.opts); this.views[this.currentView] = new $.fn.datepicker.Body(this, this.currentView, this.opts);
this.views[this.currentView].show(); this.views[this.currentView].show();
this.nav = new $.fn.datepicker.Navigation(this, this.opts); this.nav = new $.fn.datepicker.Navigation(this, this.opts);
@ -239,6 +251,10 @@
this.loc.dateFormat = [this.loc.dateFormat, this.loc.timeFormat].join(this.opts.dateTimeSeparator); this.loc.dateFormat = [this.loc.dateFormat, this.loc.timeFormat].join(this.opts.dateTimeSeparator);
} }
if (this.opts.onlyTimepicker) {
this.loc.dateFormat = this.loc.timeFormat;
}
var boundary = this._getWordBoundaryRegExp; var boundary = this._getWordBoundaryRegExp;
if (this.loc.timeFormat.match(boundary('aa')) || if (this.loc.timeFormat.match(boundary('aa')) ||
this.loc.timeFormat.match(boundary('AA')) this.loc.timeFormat.match(boundary('AA'))
@ -289,7 +305,8 @@
parsedSelected.month, parsedSelected.month,
parsedSelected.date, parsedSelected.date,
parsedSelected.hours, parsedSelected.hours,
parsedSelected.minutes parsedSelected.minutes,
parsedSelected.seconds
); );
formattedDates = selectedDates.map(function (date) { formattedDates = selectedDates.map(function (date) {
@ -305,11 +322,11 @@
parsedDate.month, parsedDate.month,
parsedDate.date, parsedDate.date,
parsedDate.hours, parsedDate.hours,
parsedDate.minutes parsedDate.minutes,
parsedDate.seconds
); );
}) })
} }
this._prevOnSelectValue = formattedDates; this._prevOnSelectValue = formattedDates;
this.opts.onSelect(formattedDates, dates, this); this.opts.onSelect(formattedDates, dates, this);
}, },
@ -364,6 +381,7 @@
hours = d.hours, hours = d.hours,
ampm = string.match(boundary('aa')) || string.match(boundary('AA')), ampm = string.match(boundary('aa')) || string.match(boundary('AA')),
dayPeriod = 'am', dayPeriod = 'am',
replacer = this._replacer,
validHours; validHours;
if (this.opts.timepicker && this.timepicker && ampm) { if (this.opts.timepicker && this.timepicker && ampm) {
@ -377,50 +395,63 @@
case /@/.test(result): case /@/.test(result):
result = result.replace(/@/, date.getTime()); result = result.replace(/@/, date.getTime());
case /aa/.test(result): case /aa/.test(result):
result = result.replace(boundary('aa'), dayPeriod); result = replacer(result, boundary('aa'), dayPeriod);
case /AA/.test(result): case /AA/.test(result):
result = result.replace(boundary('AA'), dayPeriod.toUpperCase()); result = replacer(result, boundary('AA'), dayPeriod.toUpperCase());
case /dd/.test(result): case /dd/.test(result):
result = result.replace(boundary('dd'), d.fullDate); result = replacer(result, boundary('dd'), d.fullDate);
case /d/.test(result): case /d/.test(result):
result = result.replace(boundary('d'), d.date); result = replacer(result, boundary('d'), d.date);
case /DD/.test(result): case /DD/.test(result):
result = result.replace(boundary('DD'), locale.days[d.day]); result = replacer(result, boundary('DD'), locale.days[d.day]);
case /D/.test(result): case /D/.test(result):
result = result.replace(boundary('D'), locale.daysShort[d.day]); result = replacer(result, boundary('D'), locale.daysShort[d.day]);
case /mm/.test(result): case /mm/.test(result):
result = result.replace(boundary('mm'), d.fullMonth); result = replacer(result, boundary('mm'), d.fullMonth);
case /m/.test(result): case /m/.test(result):
result = result.replace(boundary('m'), d.month + 1); result = replacer(result, boundary('m'), d.month + 1);
case /MM/.test(result): case /MM/.test(result):
result = result.replace(boundary('MM'), this.loc.months[d.month]); result = replacer(result, boundary('MM'), this.loc.months[d.month]);
case /M/.test(result): case /M/.test(result):
result = result.replace(boundary('M'), locale.monthsShort[d.month]); result = replacer(result, boundary('M'), locale.monthsShort[d.month]);
case /ss/.test(result):
result = replacer(result, boundary('ss'), d.fullSeconds);
case /s/.test(result):
result = replacer(result, boundary('s'), d.seconds);
case /ii/.test(result): case /ii/.test(result):
result = result.replace(boundary('ii'), d.fullMinutes); result = replacer(result, boundary('ii'), d.fullMinutes);
case /i/.test(result): case /i/.test(result):
result = result.replace(boundary('i'), d.minutes); result = replacer(result, boundary('i'), d.minutes);
case /hh/.test(result): case /hh/.test(result):
result = result.replace(boundary('hh'), fullHours); result = replacer(result, boundary('hh'), fullHours);
case /h/.test(result): case /h/.test(result):
result = result.replace(boundary('h'), hours); result = replacer(result, boundary('h'), hours);
case /yyyy/.test(result): case /yyyy/.test(result):
result = result.replace(boundary('yyyy'), d.year); result = replacer(result, boundary('yyyy'), d.year);
case /yyyy1/.test(result): case /yyyy1/.test(result):
result = result.replace(boundary('yyyy1'), decade[0]); result = replacer(result, boundary('yyyy1'), decade[0]);
case /yyyy2/.test(result): case /yyyy2/.test(result):
result = result.replace(boundary('yyyy2'), decade[1]); result = replacer(result, boundary('yyyy2'), decade[1]);
case /yy/.test(result): case /yy/.test(result):
result = result.replace(boundary('yy'), d.year.toString().slice(-2)); result = replacer(result, boundary('yy'), d.year.toString().slice(-2));
} }
return result; return result;
}, },
_getWordBoundaryRegExp: function (sign) { _replacer: function (str, reg, data) {
return new RegExp('\\b(?=[a-zA-Z0-9äöüßÄÖÜ<])' + sign + '(?![>a-zA-Z0-9äöüßÄÖÜ])'); return str.replace(reg, function (match, p1,p2,p3) {
return p1 + data + p3;
})
}, },
_getWordBoundaryRegExp: function (sign) {
var symbols = '\\s|\\.|-|/|\\\\|,|\\$|\\!|\\?|:|;';
return new RegExp('(^|>|' + symbols + ')(' + sign + ')($|<|' + symbols + ')', 'g');
},
selectDate: function (date) { selectDate: function (date) {
var _this = this, var _this = this,
opts = _this.opts, opts = _this.opts,
@ -454,6 +485,7 @@
if (this.timepicker) { if (this.timepicker) {
date.setHours(this.timepicker.hours); date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes) date.setMinutes(this.timepicker.minutes)
date.setSeconds(this.timepicker.seconds)
} }
if (_this.view == 'days') { if (_this.view == 'days') {
@ -595,7 +627,7 @@
this._syncWithMinMaxDates(); this._syncWithMinMaxDates();
this._defineLocale(this.opts.language); this._defineLocale(this.opts.language);
this.nav._addButtonsIfNeed(); this.nav._addButtonsIfNeed();
this.nav._render(); if (!this.opts.onlyTimepicker) this.nav._render();
this.views[this.currentView]._render(); this.views[this.currentView]._render();
if (this.elIsInput && !this.opts.inline) { if (this.elIsInput && !this.opts.inline) {
@ -609,6 +641,10 @@
this.$datepicker.addClass(this.opts.classes) this.$datepicker.addClass(this.opts.classes)
} }
if (this.opts.onlyTimepicker) {
this.$datepicker.addClass('-only-timepicker-');
}
if (this.opts.timepicker) { if (this.opts.timepicker) {
if (lastSelectedDate) this.timepicker._handleDate(lastSelectedDate); if (lastSelectedDate) this.timepicker._handleDate(lastSelectedDate);
this.timepicker._updateRanges(); this.timepicker._updateRanges();
@ -617,6 +653,7 @@
if (lastSelectedDate) { if (lastSelectedDate) {
lastSelectedDate.setHours(this.timepicker.hours); lastSelectedDate.setHours(this.timepicker.hours);
lastSelectedDate.setMinutes(this.timepicker.minutes); lastSelectedDate.setMinutes(this.timepicker.minutes);
lastSelectedDate.setSeconds(this.timepicker.seconds);
} }
} }
@ -782,12 +819,20 @@
}, },
show: function () { show: function () {
var onShow = this.opts.onShow;
this.setPosition(this.opts.position); this.setPosition(this.opts.position);
this.$datepicker.addClass('active'); this.$datepicker.addClass('active');
this.visible = true; this.visible = true;
if (onShow) {
this._bindVisionEvents(onShow)
}
}, },
hide: function () { hide: function () {
var onHide = this.opts.onHide;
this.$datepicker this.$datepicker
.removeClass('active') .removeClass('active')
.css({ .css({
@ -800,6 +845,10 @@
this.inFocus = false; this.inFocus = false;
this.visible = false; this.visible = false;
this.$el.blur(); this.$el.blur();
if (onHide) {
this._bindVisionEvents(onHide)
}
}, },
down: function (date) { down: function (date) {
@ -810,6 +859,12 @@
this._changeView(date, 'up'); this._changeView(date, 'up');
}, },
_bindVisionEvents: function (event) {
this.$datepicker.off('transitionend.dp');
event(this, false);
this.$datepicker.one('transitionend.dp', event.bind(this, this, true))
},
_changeView: function (date, dir) { _changeView: function (date, dir) {
date = date || this.focused || this.date; date = date || this.focused || this.date;
@ -1023,7 +1078,7 @@
} }
$cell = this.views[this.currentView].$el.find(selector); $cell = this.views[this.currentView].$el.find(selector);
return $cell.length ? $cell : ''; return $cell.length ? $cell : $('');
}, },
destroy: function () { destroy: function () {
@ -1046,6 +1101,30 @@
} }
}, },
_handleAlreadySelectedDates: function (alreadySelected, selectedDate) {
if (this.opts.range) {
if (!this.opts.toggleSelected) {
// Add possibility to select same date when range is true
if (this.selectedDates.length != 2) {
this._trigger('clickCell', selectedDate);
}
} else {
this.removeDate(selectedDate);
}
} else if (this.opts.toggleSelected){
this.removeDate(selectedDate);
}
// Change last selected date to be able to change time when clicking on this cell
if (!this.opts.toggleSelected) {
this.lastSelectedDate = alreadySelected;
if (this.opts.timepicker) {
this.timepicker._setTime(alreadySelected);
this.timepicker.update();
}
}
},
_onShowEvent: function (e) { _onShowEvent: function (e) {
if (!this.visible) { if (!this.visible) {
this.show(); this.show();
@ -1118,11 +1197,12 @@
if (this.timepicker) { if (this.timepicker) {
this.focused.setHours(this.timepicker.hours); this.focused.setHours(this.timepicker.hours);
this.focused.setMinutes(this.timepicker.minutes); this.focused.setMinutes(this.timepicker.minutes);
this.focused.setSeconds(this.timepicker.seconds);
} }
this.selectDate(this.focused); this.selectDate(this.focused);
} else if (alreadySelected && this.opts.toggleSelected){ return;
this.removeDate(this.focused);
} }
this._handleAlreadySelectedDates(alreadySelected, this.focused)
} }
} }
} }
@ -1179,7 +1259,7 @@
this.silent = false; this.silent = false;
}, },
_onTimeChange: function (e, h, m) { _onTimeChange: function (e, h, m, s) {
var date = new Date(), var date = new Date(),
selectedDates = this.selectedDates, selectedDates = this.selectedDates,
selected = false; selected = false;
@ -1191,6 +1271,7 @@
date.setHours(h); date.setHours(h);
date.setMinutes(m); date.setMinutes(m);
date.setSeconds(s);
if (!selected && !this._getCell(date).hasClass('-disabled-')) { if (!selected && !this._getCell(date).hasClass('-disabled-')) {
this.selectDate(date); this.selectDate(date);
@ -1206,6 +1287,7 @@
if (this.timepicker) { if (this.timepicker) {
date.setHours(this.timepicker.hours); date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes); date.setMinutes(this.timepicker.minutes);
date.setSeconds(this.timepicker.seconds)
} }
this.selectDate(date); this.selectDate(date);
}, },
@ -1329,7 +1411,9 @@
hours: date.getHours(), hours: date.getHours(),
fullHours: date.getHours() < 10 ? '0' + date.getHours() : date.getHours() , fullHours: date.getHours() < 10 ? '0' + date.getHours() : date.getHours() ,
minutes: date.getMinutes(), minutes: date.getMinutes(),
fullMinutes: date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() fullMinutes: date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(),
seconds: date.getSeconds(),
fullSeconds: date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
} }
}; };
@ -1446,7 +1530,9 @@
this.d = d; this.d = d;
this.type = type; this.type = type;
this.opts = opts; this.opts = opts;
this.$el = $('');
if (this.opts.onlyTimepicker) return;
this.init(); this.init();
}; };
@ -1492,12 +1578,6 @@
render = {}, render = {},
html = d.date; html = d.date;
if (opts.onRenderCell) {
render = opts.onRenderCell(date, type) || {};
html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : '';
}
switch (type) { switch (type) {
case 'day': case 'day':
if (parent.isWeekend(d.day)) classes += " -weekend-"; if (parent.isWeekend(d.day)) classes += " -weekend-";
@ -1530,6 +1610,7 @@
html = render.html ? render.html : html; html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : ''; classes += render.classes ? ' ' + render.classes : '';
} }
if (opts.range) { if (opts.range) {
if (dp.isSame(minRange, date, type)) classes += ' -range-from-'; if (dp.isSame(minRange, date, type)) classes += ' -range-from-';
if (dp.isSame(maxRange, date, type)) classes += ' -range-to-'; if (dp.isSame(maxRange, date, type)) classes += ' -range-to-';
@ -1673,6 +1754,7 @@
}, },
_render: function () { _render: function () {
if (this.opts.onlyTimepicker) return;
this._renderTypes[this.type].bind(this)(); this._renderTypes[this.type].bind(this)();
}, },
@ -1691,6 +1773,7 @@
}, },
show: function () { show: function () {
if (this.opts.onlyTimepicker) return;
this.$el.addClass('active'); this.$el.addClass('active');
this.acitve = true; this.acitve = true;
}, },
@ -1719,27 +1802,11 @@
if (!alreadySelected) { if (!alreadySelected) {
dp._trigger('clickCell', selectedDate); dp._trigger('clickCell', selectedDate);
return;
} }
if (alreadySelected && this.opts.range) { dp._handleAlreadySelectedDates.bind(dp, alreadySelected, selectedDate)();
// Add possibility to select same date when range is true
if (dp.selectedDates.length != 2 && !this.opts.toggleSelected || this.opts.toggleSelected) {
dp._trigger('clickCell', selectedDate);
// Change last selected date to be able to change time on last date
dp.lastSelectedDate = alreadySelected;
}
} else if (alreadySelected && this.opts.toggleSelected){
dp.removeDate(selectedDate);
}
// Change last selected date to be able to change time when clicking on this cell
if (alreadySelected && !this.opts.toggleSelected) {
dp.lastSelectedDate = alreadySelected;
if (dp.opts.timepicker) {
dp.timepicker._setTime(alreadySelected);
dp.timepicker.update();
}
}
}, },
_onClickCell: function (e) { _onClickCell: function (e) {
@ -1784,7 +1851,9 @@
}, },
_buildBaseHtml: function () { _buildBaseHtml: function () {
this._render(); if (!this.opts.onlyTimepicker) {
this._render();
}
this._addButtonsIfNeed(); this._addButtonsIfNeed();
}, },
@ -1841,10 +1910,10 @@
switch (this.d.view) { switch (this.d.view) {
case 'days': case 'days':
if (!this.d._isInRange(new Date(y, m-1, d), 'month')) { if (!this.d._isInRange(new Date(y, m-1, 1), 'month')) {
this._disableNav('prev') this._disableNav('prev')
} }
if (!this.d._isInRange(new Date(y, m+1, d), 'month')) { if (!this.d._isInRange(new Date(y, m+1, 1), 'month')) {
this._disableNav('next') this._disableNav('next')
} }
break; break;
@ -1857,10 +1926,11 @@
} }
break; break;
case 'years': case 'years':
if (!this.d._isInRange(new Date(y-10, m, d), 'year')) { var decade = dp.getDecade(this.d.date);
if (!this.d._isInRange(new Date(decade[0] - 1, 0, 1), 'year')) {
this._disableNav('prev') this._disableNav('prev')
} }
if (!this.d._isInRange(new Date(y+10, m, d), 'year')) { if (!this.d._isInRange(new Date(decade[1] + 1, 0, 1), 'year')) {
this._disableNav('next') this._disableNav('next')
} }
break; break;
@ -1898,9 +1968,11 @@
;(function () { ;(function () {
var template = '<div class="datepicker--time">' + var template = '<div class="datepicker--time">' +
'<div class="datepicker--time-current">' + '<div class="datepicker--time-current">' +
' <span class="datepicker--time-current-hours">#{hourValue}</span>' + ' <span class="datepicker--time-current-hours">#{hourVisible}</span>' +
' <span class="datepicker--time-current-colon">:</span>' + ' <span class="datepicker--time-current-colon">:</span>' +
' <span class="datepicker--time-current-minutes">#{minValue}</span>' + ' <span class="datepicker--time-current-minutes">#{minValue}</span>' +
' <span class="datepicker--time-current-colon">:</span>' +
' <span class="datepicker--time-current-seconds">#{secValue}</span>' +
'</div>' + '</div>' +
'<div class="datepicker--time-sliders">' + '<div class="datepicker--time-sliders">' +
' <div class="datepicker--time-row">' + ' <div class="datepicker--time-row">' +
@ -1909,6 +1981,9 @@
' <div class="datepicker--time-row">' + ' <div class="datepicker--time-row">' +
' <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' + ' <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' +
' </div>' + ' </div>' +
' <div class="datepicker--time-row">' +
' <input type="range" name="seconds" value="#{secValue}" min="#{secMin}" max="#{secMax}" step="#{secStep}"/>' +
' </div>' +
'</div>' + '</div>' +
'</div>', '</div>',
datepicker = $.fn.datepicker, datepicker = $.fn.datepicker,
@ -1944,6 +2019,7 @@
this._handleDate(date); this._handleDate(date);
this.hours = _date.hours < this.minHours ? this.minHours : _date.hours; this.hours = _date.hours < this.minHours ? this.minHours : _date.hours;
this.minutes = _date.minutes < this.minMinutes ? this.minMinutes : _date.minutes; this.minutes = _date.minutes < this.minMinutes ? this.minMinutes : _date.minutes;
this.seconds = _date.seconds < this.minSeconds ? this.minSeconds : _date.seconds;
}, },
/** /**
@ -1955,6 +2031,7 @@
_setMinTimeFromDate: function (date) { _setMinTimeFromDate: function (date) {
this.minHours = date.getHours(); this.minHours = date.getHours();
this.minMinutes = date.getMinutes(); this.minMinutes = date.getMinutes();
this.minSeconds = date.getSeconds();
// If, for example, min hours are 10, and current hours are 12, // If, for example, min hours are 10, and current hours are 12,
// update minMinutes to default value, to be able to choose whole range of values // update minMinutes to default value, to be able to choose whole range of values
@ -1968,6 +2045,7 @@
_setMaxTimeFromDate: function (date) { _setMaxTimeFromDate: function (date) {
this.maxHours = date.getHours(); this.maxHours = date.getHours();
this.maxMinutes = date.getMinutes(); this.maxMinutes = date.getMinutes();
this.maxSeconds = date.getSeconds();
if (this.d.lastSelectedDate) { if (this.d.lastSelectedDate) {
if (this.d.lastSelectedDate.getHours() < date.getHours()) { if (this.d.lastSelectedDate.getHours() < date.getHours()) {
@ -1979,12 +2057,15 @@
_setDefaultMinMaxTime: function () { _setDefaultMinMaxTime: function () {
var maxHours = 23, var maxHours = 23,
maxMinutes = 59, maxMinutes = 59,
maxSeconds = 59,
opts = this.opts; opts = this.opts;
this.minHours = opts.minHours < 0 || opts.minHours > maxHours ? 0 : opts.minHours; this.minHours = opts.minHours < 0 || opts.minHours > maxHours ? 0 : opts.minHours;
this.minMinutes = opts.minMinutes < 0 || opts.minMinutes > maxMinutes ? 0 : opts.minMinutes; this.minMinutes = opts.minMinutes < 0 || opts.minMinutes > maxMinutes ? 0 : opts.minMinutes;
this.maxHours = opts.maxHours < 0 || opts.maxHours > maxHours ? maxHours : opts.maxHours; this.maxHours = opts.maxHours < 0 || opts.maxHours > maxHours ? maxHours : opts.maxHours;
this.maxMinutes = opts.maxMinutes < 0 || opts.maxMinutes > maxMinutes ? maxMinutes : opts.maxMinutes; this.maxMinutes = opts.maxMinutes < 0 || opts.maxMinutes > maxMinutes ? maxMinutes : opts.maxMinutes;
this.minSeconds = opts.minSeconds < 0 || opts.minSeconds > maxSeconds ? 0 : opts.minSeconds;
this.maxSeconds = opts.maxSeconds < 0 || opts.maxSeconds > maxSeconds ? maxSeconds : opts.maxSeconds;
}, },
/** /**
@ -2004,6 +2085,12 @@
} else if (this.minutes > this.maxMinutes) { } else if (this.minutes > this.maxMinutes) {
this.minutes = this.maxMinutes; this.minutes = this.maxMinutes;
} }
if (this.seconds < this.minSeconds) {
this.seconds = this.minSeconds;
} else if (this.seconds > this.maxSeconds) {
this.seconds = this.maxSeconds;
}
}, },
_buildHTML: function () { _buildHTML: function () {
@ -2012,11 +2099,16 @@
hourMin: this.minHours, hourMin: this.minHours,
hourMax: lz(this.maxHours), hourMax: lz(this.maxHours),
hourStep: this.opts.hoursStep, hourStep: this.opts.hoursStep,
hourValue: lz(this.displayHours), hourValue: this.hours,
hourVisible: lz(this.displayHours),
minMin: this.minMinutes, minMin: this.minMinutes,
minMax: lz(this.maxMinutes), minMax: lz(this.maxMinutes),
minStep: this.opts.minutesStep, minStep: this.opts.minutesStep,
minValue: lz(this.minutes) minValue: lz(this.minutes),
secMin: this.minSeconds,
secMax: lz(this.maxSeconds),
secStep: this.opts.secondsStep,
secValue: lz(this.seconds)
}, },
_template = dp.template(template, data); _template = dp.template(template, data);
@ -2024,8 +2116,10 @@
this.$ranges = $('[type="range"]', this.$timepicker); this.$ranges = $('[type="range"]', this.$timepicker);
this.$hours = $('[name="hours"]', this.$timepicker); this.$hours = $('[name="hours"]', this.$timepicker);
this.$minutes = $('[name="minutes"]', this.$timepicker); this.$minutes = $('[name="minutes"]', this.$timepicker);
this.$seconds = $('[name="seconds"]', this.$timepicker);
this.$hoursText = $('.datepicker--time-current-hours', this.$timepicker); this.$hoursText = $('.datepicker--time-current-hours', this.$timepicker);
this.$minutesText = $('.datepicker--time-current-minutes', this.$timepicker); this.$minutesText = $('.datepicker--time-current-minutes', this.$timepicker);
this.$secondsText = $('.datepicker--time-current-seconds', this.$timepicker);
if (this.d.ampm) { if (this.d.ampm) {
this.$ampm = $('<span class="datepicker--time-current-ampm">') this.$ampm = $('<span class="datepicker--time-current-ampm">')
@ -2038,10 +2132,12 @@
_updateCurrentTime: function () { _updateCurrentTime: function () {
var h = dp.getLeadingZeroNum(this.displayHours), var h = dp.getLeadingZeroNum(this.displayHours),
m = dp.getLeadingZeroNum(this.minutes); m = dp.getLeadingZeroNum(this.minutes),
s = dp.getLeadingZeroNum(this.seconds);
this.$hoursText.html(h); this.$hoursText.html(h);
this.$minutesText.html(m); this.$minutesText.html(m);
this.$secondsText.html(s);
if (this.d.ampm) { if (this.d.ampm) {
this.$ampm.html(this.dayPeriod); this.$ampm.html(this.dayPeriod);
@ -2057,7 +2153,12 @@
this.$minutes.attr({ this.$minutes.attr({
min: this.minMinutes, min: this.minMinutes,
max: this.maxMinutes max: this.maxMinutes
}).val(this.minutes) }).val(this.minutes);
this.$seconds.attr({
min: this.minSeconds,
max: this.maxSeconds
}).val(this.seconds);
}, },
/** /**
@ -2150,7 +2251,7 @@
this[name] = $target.val(); this[name] = $target.val();
this._updateCurrentTime(); this._updateCurrentTime();
this.d._trigger('timeChange', [this.hours, this.minutes]); this.d._trigger('timeChange', [this.hours, this.minutes, this.seconds]);
this._handleDate(this.d.lastSelectedDate); this._handleDate(this.d.lastSelectedDate);
this.update() this.update()

File diff suppressed because one or more lines are too long

12
dist/js/i18n/datepicker.sk.js vendored Normal file
View File

@ -0,0 +1,12 @@
;(function ($) { $.fn.datepicker.language['sk'] = {
days: ['Nedeľa', 'Pondelok', 'Utorok', 'Streda', 'Štvrtok', 'Piatok', 'Sobota'],
daysShort: ['Ned', 'Pon', 'Uto', 'Str', 'Štv', 'Pia', 'Sob'],
daysMin: ['Ne', 'Po', 'Ut', 'St', 'Št', 'Pi', 'So'],
months: ['Január','Február','Marec','Apríl','Máj','Jún', 'Júl','August','September','Október','November','December'],
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'Máj', 'Jún', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'],
today: 'Dnes',
clear: 'Vymazať',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
}; })(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@ html
script(src='http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js') script(src='http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js')
script(src='../dist/js/datepicker.js') script(src='../dist/js/datepicker.js')
script(src='../dist/js/i18n/datepicker.en.js') script(src='../dist/js/i18n/datepicker.en.js')
script(src='js/logger.js')
body body
div.wrapper div.wrapper
main.main(role='main') main.main(role='main')

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

29
docs/js/logger.js Normal file
View File

@ -0,0 +1,29 @@
var logger;
(function (window) {
logger = function (el, clearText) {
var $el = $(el);
addContent($el);
addClearButton(clearText, $el);
$('.logger--clear', $el).on('click', clear.bind('', $el));
return function(text) {
var count = $('p', $el).length,
$content = $('.logger--content', $el);
$content.append('<p><span>' + ++count + '.</span> ' + text + '</p>').scrollTop(100000)
}
};
function addClearButton (text, el) {
el.append('<span class="logger--clear">' + text + '</span>')
}
function addContent (el) {
el.html('<div class="logger--content"></div>')
}
function clear (el) {
$('.logger--content', el).html('');
}
})(window);

View File

@ -42,6 +42,13 @@ h4 {
margin: 24px 0 0; margin: 24px 0 0;
} }
.row {
display: flex;
> * {
flex: 1;
}
}
article { article {
h2, h3 { h2, h3 {
position: relative; position: relative;
@ -506,4 +513,57 @@ a {
span { span {
color: #ddd; color: #ddd;
} }
}
// Logger
// -------------------------------------------------
.logger {
background: rgba(0, 0, 0, .7);
border-radius: 4px;
font-size: 12px;
font-family: Monospace, monospace;
height: 150px;
overflow: auto;
position: relative;
}
.logger--content {
padding: 4px 8px;
height: 100%;
overflow: auto;
p {
margin: 0;
color: greenyellow;
}
span {
color: #ddd;
}
}
.logger--clear {
color: #333;
border-radius: 4px 4px 0 0;
cursor: pointer;
position: absolute;
height: 32px;
padding: 0 8px;
font-family: 'Tahoma', sans-serif;
font-size: 13px;
display: inline-flex;
justify-content: center;
align-items: center;
background: rgba(255, 255, 255, .5);
right: 24px;
bottom: 0;
&:hover {
background: rgba(255, 255, 255, .8);
}
&:active {
background: rgba(255, 255, 255, .3);
}
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "air-datepicker", "name": "air-datepicker",
"version": "2.1.0", "version": "2.2.3",
"devDependencies": { "devDependencies": {
"autoprefixer": "^6.1.0", "autoprefixer": "^6.1.0",
"browserify": "^13.0.0", "browserify": "^13.0.0",
@ -25,7 +25,7 @@
"vinyl-source-stream": "^1.1.0" "vinyl-source-stream": "^1.1.0"
}, },
"dependencies": { "dependencies": {
"jquery": "^3.0.0" "jquery": ">=2.0.0 <4.0.0"
}, },
"description": "Lightweight customizable cross-browser jQuery datepicker, built with es5 and css-flexbox. Works in all modern desktop and mobile browsers (tested no Android 4.4+ and iOS8+)\r ![air datepicker image](https://github.com/t1m0n/air-datepicker/raw/master/docs/img/promo-img.png)", "description": "Lightweight customizable cross-browser jQuery datepicker, built with es5 and css-flexbox. Works in all modern desktop and mobile browsers (tested no Android 4.4+ and iOS8+)\r ![air datepicker image](https://github.com/t1m0n/air-datepicker/raw/master/docs/img/promo-img.png)",
"main": "src/js/air-datepicker.js", "main": "src/js/air-datepicker.js",

View File

@ -21,7 +21,9 @@
this.d = d; this.d = d;
this.type = type; this.type = type;
this.opts = opts; this.opts = opts;
this.$el = $('');
if (this.opts.onlyTimepicker) return;
this.init(); this.init();
}; };
@ -67,12 +69,6 @@
render = {}, render = {},
html = d.date; html = d.date;
if (opts.onRenderCell) {
render = opts.onRenderCell(date, type) || {};
html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : '';
}
switch (type) { switch (type) {
case 'day': case 'day':
if (parent.isWeekend(d.day)) classes += " -weekend-"; if (parent.isWeekend(d.day)) classes += " -weekend-";
@ -105,6 +101,7 @@
html = render.html ? render.html : html; html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : ''; classes += render.classes ? ' ' + render.classes : '';
} }
if (opts.range) { if (opts.range) {
if (dp.isSame(minRange, date, type)) classes += ' -range-from-'; if (dp.isSame(minRange, date, type)) classes += ' -range-from-';
if (dp.isSame(maxRange, date, type)) classes += ' -range-to-'; if (dp.isSame(maxRange, date, type)) classes += ' -range-to-';
@ -248,6 +245,7 @@
}, },
_render: function () { _render: function () {
if (this.opts.onlyTimepicker) return;
this._renderTypes[this.type].bind(this)(); this._renderTypes[this.type].bind(this)();
}, },
@ -266,6 +264,7 @@
}, },
show: function () { show: function () {
if (this.opts.onlyTimepicker) return;
this.$el.addClass('active'); this.$el.addClass('active');
this.acitve = true; this.acitve = true;
}, },
@ -294,27 +293,11 @@
if (!alreadySelected) { if (!alreadySelected) {
dp._trigger('clickCell', selectedDate); dp._trigger('clickCell', selectedDate);
return;
} }
if (alreadySelected && this.opts.range) { dp._handleAlreadySelectedDates.bind(dp, alreadySelected, selectedDate)();
// Add possibility to select same date when range is true
if (dp.selectedDates.length != 2 && !this.opts.toggleSelected || this.opts.toggleSelected) {
dp._trigger('clickCell', selectedDate);
// Change last selected date to be able to change time on last date
dp.lastSelectedDate = alreadySelected;
}
} else if (alreadySelected && this.opts.toggleSelected){
dp.removeDate(selectedDate);
}
// Change last selected date to be able to change time when clicking on this cell
if (alreadySelected && !this.opts.toggleSelected) {
dp.lastSelectedDate = alreadySelected;
if (dp.opts.timepicker) {
dp.timepicker._setTime(alreadySelected);
dp.timepicker.update();
}
}
}, },
_onClickCell: function (e) { _onClickCell: function (e) {

View File

@ -1,5 +1,6 @@
;(function () { ;(function () {
var pluginName = 'datepicker', var VERSION = '2.2.3',
pluginName = 'datepicker',
autoInitSelector = '.datepicker-here', autoInitSelector = '.datepicker-here',
$body, $datepickersContainer, $body, $datepickersContainer,
containerBuilt = false, containerBuilt = false,
@ -62,17 +63,23 @@
// timepicker // timepicker
timepicker: false, timepicker: false,
onlyTimepicker: false,
dateTimeSeparator: ' ', dateTimeSeparator: ' ',
timeFormat: '', timeFormat: '',
minHours: 0, minHours: 0,
maxHours: 24, maxHours: 24,
minMinutes: 0, minMinutes: 0,
maxMinutes: 59, maxMinutes: 59,
minSeconds: 0,
maxSeconds: 59,
hoursStep: 1, hoursStep: 1,
minutesStep: 1, minutesStep: 1,
secondsStep: 1,
// events // events
onSelect: '', onSelect: '',
onShow: '',
onHide: '',
onChangeMonth: '', onChangeMonth: '',
onChangeYear: '', onChangeYear: '',
onChangeDecade: '', onChangeDecade: '',
@ -138,6 +145,7 @@
datepicker = Datepicker; datepicker = Datepicker;
datepicker.prototype = { datepicker.prototype = {
VERSION: VERSION,
viewIndexes: ['days', 'months', 'years'], viewIndexes: ['days', 'months', 'years'],
init: function () { init: function () {
@ -154,7 +162,7 @@
this._setPositionClasses(this.opts.position); this._setPositionClasses(this.opts.position);
this._bindEvents() this._bindEvents()
} }
if (this.opts.keyboardNav) { if (this.opts.keyboardNav && !this.opts.onlyTimepicker) {
this._bindKeyboardEvents(); this._bindKeyboardEvents();
} }
this.$datepicker.on('mousedown', this._onMouseDownDatepicker.bind(this)); this.$datepicker.on('mousedown', this._onMouseDownDatepicker.bind(this));
@ -170,6 +178,10 @@
this._bindTimepickerEvents(); this._bindTimepickerEvents();
} }
if (this.opts.onlyTimepicker) {
this.$datepicker.addClass('-only-timepicker-');
}
this.views[this.currentView] = new $.fn.datepicker.Body(this, this.currentView, this.opts); this.views[this.currentView] = new $.fn.datepicker.Body(this, this.currentView, this.opts);
this.views[this.currentView].show(); this.views[this.currentView].show();
this.nav = new $.fn.datepicker.Navigation(this, this.opts); this.nav = new $.fn.datepicker.Navigation(this, this.opts);
@ -239,6 +251,10 @@
this.loc.dateFormat = [this.loc.dateFormat, this.loc.timeFormat].join(this.opts.dateTimeSeparator); this.loc.dateFormat = [this.loc.dateFormat, this.loc.timeFormat].join(this.opts.dateTimeSeparator);
} }
if (this.opts.onlyTimepicker) {
this.loc.dateFormat = this.loc.timeFormat;
}
var boundary = this._getWordBoundaryRegExp; var boundary = this._getWordBoundaryRegExp;
if (this.loc.timeFormat.match(boundary('aa')) || if (this.loc.timeFormat.match(boundary('aa')) ||
this.loc.timeFormat.match(boundary('AA')) this.loc.timeFormat.match(boundary('AA'))
@ -289,7 +305,8 @@
parsedSelected.month, parsedSelected.month,
parsedSelected.date, parsedSelected.date,
parsedSelected.hours, parsedSelected.hours,
parsedSelected.minutes parsedSelected.minutes,
parsedSelected.seconds
); );
formattedDates = selectedDates.map(function (date) { formattedDates = selectedDates.map(function (date) {
@ -305,11 +322,11 @@
parsedDate.month, parsedDate.month,
parsedDate.date, parsedDate.date,
parsedDate.hours, parsedDate.hours,
parsedDate.minutes parsedDate.minutes,
parsedDate.seconds
); );
}) })
} }
this._prevOnSelectValue = formattedDates; this._prevOnSelectValue = formattedDates;
this.opts.onSelect(formattedDates, dates, this); this.opts.onSelect(formattedDates, dates, this);
}, },
@ -364,6 +381,7 @@
hours = d.hours, hours = d.hours,
ampm = string.match(boundary('aa')) || string.match(boundary('AA')), ampm = string.match(boundary('aa')) || string.match(boundary('AA')),
dayPeriod = 'am', dayPeriod = 'am',
replacer = this._replacer,
validHours; validHours;
if (this.opts.timepicker && this.timepicker && ampm) { if (this.opts.timepicker && this.timepicker && ampm) {
@ -377,50 +395,63 @@
case /@/.test(result): case /@/.test(result):
result = result.replace(/@/, date.getTime()); result = result.replace(/@/, date.getTime());
case /aa/.test(result): case /aa/.test(result):
result = result.replace(boundary('aa'), dayPeriod); result = replacer(result, boundary('aa'), dayPeriod);
case /AA/.test(result): case /AA/.test(result):
result = result.replace(boundary('AA'), dayPeriod.toUpperCase()); result = replacer(result, boundary('AA'), dayPeriod.toUpperCase());
case /dd/.test(result): case /dd/.test(result):
result = result.replace(boundary('dd'), d.fullDate); result = replacer(result, boundary('dd'), d.fullDate);
case /d/.test(result): case /d/.test(result):
result = result.replace(boundary('d'), d.date); result = replacer(result, boundary('d'), d.date);
case /DD/.test(result): case /DD/.test(result):
result = result.replace(boundary('DD'), locale.days[d.day]); result = replacer(result, boundary('DD'), locale.days[d.day]);
case /D/.test(result): case /D/.test(result):
result = result.replace(boundary('D'), locale.daysShort[d.day]); result = replacer(result, boundary('D'), locale.daysShort[d.day]);
case /mm/.test(result): case /mm/.test(result):
result = result.replace(boundary('mm'), d.fullMonth); result = replacer(result, boundary('mm'), d.fullMonth);
case /m/.test(result): case /m/.test(result):
result = result.replace(boundary('m'), d.month + 1); result = replacer(result, boundary('m'), d.month + 1);
case /MM/.test(result): case /MM/.test(result):
result = result.replace(boundary('MM'), this.loc.months[d.month]); result = replacer(result, boundary('MM'), this.loc.months[d.month]);
case /M/.test(result): case /M/.test(result):
result = result.replace(boundary('M'), locale.monthsShort[d.month]); result = replacer(result, boundary('M'), locale.monthsShort[d.month]);
case /ss/.test(result):
result = replacer(result, boundary('ss'), d.fullSeconds);
case /s/.test(result):
result = replacer(result, boundary('s'), d.seconds);
case /ii/.test(result): case /ii/.test(result):
result = result.replace(boundary('ii'), d.fullMinutes); result = replacer(result, boundary('ii'), d.fullMinutes);
case /i/.test(result): case /i/.test(result):
result = result.replace(boundary('i'), d.minutes); result = replacer(result, boundary('i'), d.minutes);
case /hh/.test(result): case /hh/.test(result):
result = result.replace(boundary('hh'), fullHours); result = replacer(result, boundary('hh'), fullHours);
case /h/.test(result): case /h/.test(result):
result = result.replace(boundary('h'), hours); result = replacer(result, boundary('h'), hours);
case /yyyy/.test(result): case /yyyy/.test(result):
result = result.replace(boundary('yyyy'), d.year); result = replacer(result, boundary('yyyy'), d.year);
case /yyyy1/.test(result): case /yyyy1/.test(result):
result = result.replace(boundary('yyyy1'), decade[0]); result = replacer(result, boundary('yyyy1'), decade[0]);
case /yyyy2/.test(result): case /yyyy2/.test(result):
result = result.replace(boundary('yyyy2'), decade[1]); result = replacer(result, boundary('yyyy2'), decade[1]);
case /yy/.test(result): case /yy/.test(result):
result = result.replace(boundary('yy'), d.year.toString().slice(-2)); result = replacer(result, boundary('yy'), d.year.toString().slice(-2));
} }
return result; return result;
}, },
_getWordBoundaryRegExp: function (sign) { _replacer: function (str, reg, data) {
return new RegExp('\\b(?=[a-zA-Z0-9äöüßÄÖÜ<])' + sign + '(?![>a-zA-Z0-9äöüßÄÖÜ])'); return str.replace(reg, function (match, p1,p2,p3) {
return p1 + data + p3;
})
}, },
_getWordBoundaryRegExp: function (sign) {
var symbols = '\\s|\\.|-|/|\\\\|,|\\$|\\!|\\?|:|;';
return new RegExp('(^|>|' + symbols + ')(' + sign + ')($|<|' + symbols + ')', 'g');
},
selectDate: function (date) { selectDate: function (date) {
var _this = this, var _this = this,
opts = _this.opts, opts = _this.opts,
@ -454,6 +485,7 @@
if (this.timepicker) { if (this.timepicker) {
date.setHours(this.timepicker.hours); date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes) date.setMinutes(this.timepicker.minutes)
date.setSeconds(this.timepicker.seconds)
} }
if (_this.view == 'days') { if (_this.view == 'days') {
@ -595,7 +627,7 @@
this._syncWithMinMaxDates(); this._syncWithMinMaxDates();
this._defineLocale(this.opts.language); this._defineLocale(this.opts.language);
this.nav._addButtonsIfNeed(); this.nav._addButtonsIfNeed();
this.nav._render(); if (!this.opts.onlyTimepicker) this.nav._render();
this.views[this.currentView]._render(); this.views[this.currentView]._render();
if (this.elIsInput && !this.opts.inline) { if (this.elIsInput && !this.opts.inline) {
@ -609,6 +641,10 @@
this.$datepicker.addClass(this.opts.classes) this.$datepicker.addClass(this.opts.classes)
} }
if (this.opts.onlyTimepicker) {
this.$datepicker.addClass('-only-timepicker-');
}
if (this.opts.timepicker) { if (this.opts.timepicker) {
if (lastSelectedDate) this.timepicker._handleDate(lastSelectedDate); if (lastSelectedDate) this.timepicker._handleDate(lastSelectedDate);
this.timepicker._updateRanges(); this.timepicker._updateRanges();
@ -617,6 +653,7 @@
if (lastSelectedDate) { if (lastSelectedDate) {
lastSelectedDate.setHours(this.timepicker.hours); lastSelectedDate.setHours(this.timepicker.hours);
lastSelectedDate.setMinutes(this.timepicker.minutes); lastSelectedDate.setMinutes(this.timepicker.minutes);
lastSelectedDate.setSeconds(this.timepicker.seconds);
} }
} }
@ -782,12 +819,20 @@
}, },
show: function () { show: function () {
var onShow = this.opts.onShow;
this.setPosition(this.opts.position); this.setPosition(this.opts.position);
this.$datepicker.addClass('active'); this.$datepicker.addClass('active');
this.visible = true; this.visible = true;
if (onShow) {
this._bindVisionEvents(onShow)
}
}, },
hide: function () { hide: function () {
var onHide = this.opts.onHide;
this.$datepicker this.$datepicker
.removeClass('active') .removeClass('active')
.css({ .css({
@ -800,6 +845,10 @@
this.inFocus = false; this.inFocus = false;
this.visible = false; this.visible = false;
this.$el.blur(); this.$el.blur();
if (onHide) {
this._bindVisionEvents(onHide)
}
}, },
down: function (date) { down: function (date) {
@ -810,6 +859,12 @@
this._changeView(date, 'up'); this._changeView(date, 'up');
}, },
_bindVisionEvents: function (event) {
this.$datepicker.off('transitionend.dp');
event(this, false);
this.$datepicker.one('transitionend.dp', event.bind(this, this, true))
},
_changeView: function (date, dir) { _changeView: function (date, dir) {
date = date || this.focused || this.date; date = date || this.focused || this.date;
@ -1023,7 +1078,7 @@
} }
$cell = this.views[this.currentView].$el.find(selector); $cell = this.views[this.currentView].$el.find(selector);
return $cell.length ? $cell : ''; return $cell.length ? $cell : $('');
}, },
destroy: function () { destroy: function () {
@ -1046,6 +1101,30 @@
} }
}, },
_handleAlreadySelectedDates: function (alreadySelected, selectedDate) {
if (this.opts.range) {
if (!this.opts.toggleSelected) {
// Add possibility to select same date when range is true
if (this.selectedDates.length != 2) {
this._trigger('clickCell', selectedDate);
}
} else {
this.removeDate(selectedDate);
}
} else if (this.opts.toggleSelected){
this.removeDate(selectedDate);
}
// Change last selected date to be able to change time when clicking on this cell
if (!this.opts.toggleSelected) {
this.lastSelectedDate = alreadySelected;
if (this.opts.timepicker) {
this.timepicker._setTime(alreadySelected);
this.timepicker.update();
}
}
},
_onShowEvent: function (e) { _onShowEvent: function (e) {
if (!this.visible) { if (!this.visible) {
this.show(); this.show();
@ -1118,11 +1197,12 @@
if (this.timepicker) { if (this.timepicker) {
this.focused.setHours(this.timepicker.hours); this.focused.setHours(this.timepicker.hours);
this.focused.setMinutes(this.timepicker.minutes); this.focused.setMinutes(this.timepicker.minutes);
this.focused.setSeconds(this.timepicker.seconds);
} }
this.selectDate(this.focused); this.selectDate(this.focused);
} else if (alreadySelected && this.opts.toggleSelected){ return;
this.removeDate(this.focused);
} }
this._handleAlreadySelectedDates(alreadySelected, this.focused)
} }
} }
} }
@ -1179,7 +1259,7 @@
this.silent = false; this.silent = false;
}, },
_onTimeChange: function (e, h, m) { _onTimeChange: function (e, h, m, s) {
var date = new Date(), var date = new Date(),
selectedDates = this.selectedDates, selectedDates = this.selectedDates,
selected = false; selected = false;
@ -1191,6 +1271,7 @@
date.setHours(h); date.setHours(h);
date.setMinutes(m); date.setMinutes(m);
date.setSeconds(s);
if (!selected && !this._getCell(date).hasClass('-disabled-')) { if (!selected && !this._getCell(date).hasClass('-disabled-')) {
this.selectDate(date); this.selectDate(date);
@ -1206,6 +1287,7 @@
if (this.timepicker) { if (this.timepicker) {
date.setHours(this.timepicker.hours); date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes); date.setMinutes(this.timepicker.minutes);
date.setSeconds(this.timepicker.seconds)
} }
this.selectDate(date); this.selectDate(date);
}, },
@ -1329,7 +1411,9 @@
hours: date.getHours(), hours: date.getHours(),
fullHours: date.getHours() < 10 ? '0' + date.getHours() : date.getHours() , fullHours: date.getHours() < 10 ? '0' + date.getHours() : date.getHours() ,
minutes: date.getMinutes(), minutes: date.getMinutes(),
fullMinutes: date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() fullMinutes: date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(),
seconds: date.getSeconds(),
fullSeconds: date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
} }
}; };

View File

@ -0,0 +1,12 @@
$.fn.datepicker.language['sk'] = {
days: ['Nedeľa', 'Pondelok', 'Utorok', 'Streda', 'Štvrtok', 'Piatok', 'Sobota'],
daysShort: ['Ned', 'Pon', 'Uto', 'Str', 'Štv', 'Pia', 'Sob'],
daysMin: ['Ne', 'Po', 'Ut', 'St', 'Št', 'Pi', 'So'],
months: ['Január','Február','Marec','Apríl','Máj','Jún', 'Júl','August','September','Október','November','December'],
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'Máj', 'Jún', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'],
today: 'Dnes',
clear: 'Vymazať',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
};

View File

@ -30,7 +30,9 @@
}, },
_buildBaseHtml: function () { _buildBaseHtml: function () {
this._render(); if (!this.opts.onlyTimepicker) {
this._render();
}
this._addButtonsIfNeed(); this._addButtonsIfNeed();
}, },
@ -87,10 +89,10 @@
switch (this.d.view) { switch (this.d.view) {
case 'days': case 'days':
if (!this.d._isInRange(new Date(y, m-1, d), 'month')) { if (!this.d._isInRange(new Date(y, m-1, 1), 'month')) {
this._disableNav('prev') this._disableNav('prev')
} }
if (!this.d._isInRange(new Date(y, m+1, d), 'month')) { if (!this.d._isInRange(new Date(y, m+1, 1), 'month')) {
this._disableNav('next') this._disableNav('next')
} }
break; break;
@ -103,10 +105,11 @@
} }
break; break;
case 'years': case 'years':
if (!this.d._isInRange(new Date(y-10, m, d), 'year')) { var decade = dp.getDecade(this.d.date);
if (!this.d._isInRange(new Date(decade[0] - 1, 0, 1), 'year')) {
this._disableNav('prev') this._disableNav('prev')
} }
if (!this.d._isInRange(new Date(y+10, m, d), 'year')) { if (!this.d._isInRange(new Date(decade[1] + 1, 0, 1), 'year')) {
this._disableNav('next') this._disableNav('next')
} }
break; break;

View File

@ -1,9 +1,11 @@
;(function () { ;(function () {
var template = '<div class="datepicker--time">' + var template = '<div class="datepicker--time">' +
'<div class="datepicker--time-current">' + '<div class="datepicker--time-current">' +
' <span class="datepicker--time-current-hours">#{hourValue}</span>' + ' <span class="datepicker--time-current-hours">#{hourVisible}</span>' +
' <span class="datepicker--time-current-colon">:</span>' + ' <span class="datepicker--time-current-colon">:</span>' +
' <span class="datepicker--time-current-minutes">#{minValue}</span>' + ' <span class="datepicker--time-current-minutes">#{minValue}</span>' +
' <span class="datepicker--time-current-colon">:</span>' +
' <span class="datepicker--time-current-seconds">#{secValue}</span>' +
'</div>' + '</div>' +
'<div class="datepicker--time-sliders">' + '<div class="datepicker--time-sliders">' +
' <div class="datepicker--time-row">' + ' <div class="datepicker--time-row">' +
@ -12,6 +14,9 @@
' <div class="datepicker--time-row">' + ' <div class="datepicker--time-row">' +
' <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' + ' <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' +
' </div>' + ' </div>' +
' <div class="datepicker--time-row">' +
' <input type="range" name="seconds" value="#{secValue}" min="#{secMin}" max="#{secMax}" step="#{secStep}"/>' +
' </div>' +
'</div>' + '</div>' +
'</div>', '</div>',
datepicker = $.fn.datepicker, datepicker = $.fn.datepicker,
@ -47,6 +52,7 @@
this._handleDate(date); this._handleDate(date);
this.hours = _date.hours < this.minHours ? this.minHours : _date.hours; this.hours = _date.hours < this.minHours ? this.minHours : _date.hours;
this.minutes = _date.minutes < this.minMinutes ? this.minMinutes : _date.minutes; this.minutes = _date.minutes < this.minMinutes ? this.minMinutes : _date.minutes;
this.seconds = _date.seconds < this.minSeconds ? this.minSeconds : _date.seconds;
}, },
/** /**
@ -58,6 +64,7 @@
_setMinTimeFromDate: function (date) { _setMinTimeFromDate: function (date) {
this.minHours = date.getHours(); this.minHours = date.getHours();
this.minMinutes = date.getMinutes(); this.minMinutes = date.getMinutes();
this.minSeconds = date.getSeconds();
// If, for example, min hours are 10, and current hours are 12, // If, for example, min hours are 10, and current hours are 12,
// update minMinutes to default value, to be able to choose whole range of values // update minMinutes to default value, to be able to choose whole range of values
@ -71,6 +78,7 @@
_setMaxTimeFromDate: function (date) { _setMaxTimeFromDate: function (date) {
this.maxHours = date.getHours(); this.maxHours = date.getHours();
this.maxMinutes = date.getMinutes(); this.maxMinutes = date.getMinutes();
this.maxSeconds = date.getSeconds();
if (this.d.lastSelectedDate) { if (this.d.lastSelectedDate) {
if (this.d.lastSelectedDate.getHours() < date.getHours()) { if (this.d.lastSelectedDate.getHours() < date.getHours()) {
@ -82,12 +90,15 @@
_setDefaultMinMaxTime: function () { _setDefaultMinMaxTime: function () {
var maxHours = 23, var maxHours = 23,
maxMinutes = 59, maxMinutes = 59,
maxSeconds = 59,
opts = this.opts; opts = this.opts;
this.minHours = opts.minHours < 0 || opts.minHours > maxHours ? 0 : opts.minHours; this.minHours = opts.minHours < 0 || opts.minHours > maxHours ? 0 : opts.minHours;
this.minMinutes = opts.minMinutes < 0 || opts.minMinutes > maxMinutes ? 0 : opts.minMinutes; this.minMinutes = opts.minMinutes < 0 || opts.minMinutes > maxMinutes ? 0 : opts.minMinutes;
this.maxHours = opts.maxHours < 0 || opts.maxHours > maxHours ? maxHours : opts.maxHours; this.maxHours = opts.maxHours < 0 || opts.maxHours > maxHours ? maxHours : opts.maxHours;
this.maxMinutes = opts.maxMinutes < 0 || opts.maxMinutes > maxMinutes ? maxMinutes : opts.maxMinutes; this.maxMinutes = opts.maxMinutes < 0 || opts.maxMinutes > maxMinutes ? maxMinutes : opts.maxMinutes;
this.minSeconds = opts.minSeconds < 0 || opts.minSeconds > maxSeconds ? 0 : opts.minSeconds;
this.maxSeconds = opts.maxSeconds < 0 || opts.maxSeconds > maxSeconds ? maxSeconds : opts.maxSeconds;
}, },
/** /**
@ -107,6 +118,12 @@
} else if (this.minutes > this.maxMinutes) { } else if (this.minutes > this.maxMinutes) {
this.minutes = this.maxMinutes; this.minutes = this.maxMinutes;
} }
if (this.seconds < this.minSeconds) {
this.seconds = this.minSeconds;
} else if (this.seconds > this.maxSeconds) {
this.seconds = this.maxSeconds;
}
}, },
_buildHTML: function () { _buildHTML: function () {
@ -115,11 +132,16 @@
hourMin: this.minHours, hourMin: this.minHours,
hourMax: lz(this.maxHours), hourMax: lz(this.maxHours),
hourStep: this.opts.hoursStep, hourStep: this.opts.hoursStep,
hourValue: lz(this.displayHours), hourValue: this.hours,
hourVisible: lz(this.displayHours),
minMin: this.minMinutes, minMin: this.minMinutes,
minMax: lz(this.maxMinutes), minMax: lz(this.maxMinutes),
minStep: this.opts.minutesStep, minStep: this.opts.minutesStep,
minValue: lz(this.minutes) minValue: lz(this.minutes),
secMin: this.minSeconds,
secMax: lz(this.maxSeconds),
secStep: this.opts.secondsStep,
secValue: lz(this.seconds)
}, },
_template = dp.template(template, data); _template = dp.template(template, data);
@ -127,8 +149,10 @@
this.$ranges = $('[type="range"]', this.$timepicker); this.$ranges = $('[type="range"]', this.$timepicker);
this.$hours = $('[name="hours"]', this.$timepicker); this.$hours = $('[name="hours"]', this.$timepicker);
this.$minutes = $('[name="minutes"]', this.$timepicker); this.$minutes = $('[name="minutes"]', this.$timepicker);
this.$seconds = $('[name="seconds"]', this.$timepicker);
this.$hoursText = $('.datepicker--time-current-hours', this.$timepicker); this.$hoursText = $('.datepicker--time-current-hours', this.$timepicker);
this.$minutesText = $('.datepicker--time-current-minutes', this.$timepicker); this.$minutesText = $('.datepicker--time-current-minutes', this.$timepicker);
this.$secondsText = $('.datepicker--time-current-seconds', this.$timepicker);
if (this.d.ampm) { if (this.d.ampm) {
this.$ampm = $('<span class="datepicker--time-current-ampm">') this.$ampm = $('<span class="datepicker--time-current-ampm">')
@ -141,10 +165,12 @@
_updateCurrentTime: function () { _updateCurrentTime: function () {
var h = dp.getLeadingZeroNum(this.displayHours), var h = dp.getLeadingZeroNum(this.displayHours),
m = dp.getLeadingZeroNum(this.minutes); m = dp.getLeadingZeroNum(this.minutes),
s = dp.getLeadingZeroNum(this.seconds);
this.$hoursText.html(h); this.$hoursText.html(h);
this.$minutesText.html(m); this.$minutesText.html(m);
this.$secondsText.html(s);
if (this.d.ampm) { if (this.d.ampm) {
this.$ampm.html(this.dayPeriod); this.$ampm.html(this.dayPeriod);
@ -160,7 +186,12 @@
this.$minutes.attr({ this.$minutes.attr({
min: this.minMinutes, min: this.minMinutes,
max: this.maxMinutes max: this.maxMinutes
}).val(this.minutes) }).val(this.minutes);
this.$seconds.attr({
min: this.minSeconds,
max: this.maxSeconds
}).val(this.seconds);
}, },
/** /**
@ -253,7 +284,7 @@
this[name] = $target.val(); this[name] = $target.val();
this._updateCurrentTime(); this._updateCurrentTime();
this.d._trigger('timeChange', [this.hours, this.minutes]); this.d._trigger('timeChange', [this.hours, this.minutes, this.seconds]);
this._handleDate(this.d.lastSelectedDate); this._handleDate(this.d.lastSelectedDate);
this.update() this.update()

View File

@ -70,6 +70,10 @@
.datepicker--content { .datepicker--content {
box-sizing: content-box; box-sizing: content-box;
padding: $datepickerPadding; padding: $datepickerPadding;
.-only-timepicker- & {
display: none;
}
} }
// Pointer // Pointer

View File

@ -10,6 +10,10 @@
border-bottom: 1px solid map_get($datepickerBorderColor, nav); border-bottom: 1px solid map_get($datepickerBorderColor, nav);
min-height: $datepickerNavigationHeight; min-height: $datepickerNavigationHeight;
padding: $datepickerPadding; padding: $datepickerPadding;
.-only-timepicker- & {
display: none;
}
} }
.datepicker--nav-title, .datepicker--nav-title,

View File

@ -71,6 +71,10 @@ $rangeThumbBg: #dedede;
max-width: 138px; max-width: 138px;
} }
} }
.-only-timepicker- & {
border-top: none;
}
} }
.datepicker--time-sliders { .datepicker--time-sliders {
@ -90,7 +94,7 @@ $rangeThumbBg: #dedede;
flex: 1; flex: 1;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
margin: 0 0 0 10px; margin: 0 10px;
} }
.datepicker--time-current-colon { .datepicker--time-current-colon {
@ -99,9 +103,10 @@ $rangeThumbBg: #dedede;
} }
.datepicker--time-current-hours, .datepicker--time-current-hours,
.datepicker--time-current-minutes { .datepicker--time-current-minutes,
.datepicker--time-current-seconds {
line-height: 1; line-height: 1;
font-size: 19px; font-size: 14px;
font-family: "Century Gothic", CenturyGothic, AppleGothic, sans-serif; font-family: "Century Gothic", CenturyGothic, AppleGothic, sans-serif;
position: relative; position: relative;
z-index: 1; z-index: 1;
@ -128,7 +133,7 @@ $rangeThumbBg: #dedede;
.datepicker--time-current-ampm { .datepicker--time-current-ampm {
text-transform: uppercase; text-transform: uppercase;
align-self: flex-end; align-self: flex-start;
color: map_get($datepickerTextColor, navArrows); color: map_get($datepickerTextColor, navArrows);
margin-left: 6px; margin-left: 6px;
font-size: 11px; font-size: 11px;

View File

@ -23,7 +23,7 @@
<style type="text/css"> <style type="text/css">
/* Remove transitions to test position options*/ /* Remove transitions to test position options*/
.datepicker { .datepicker {
transition: none !important; transition-duration: 0s !important;
} }
</style> </style>
</head> </head>

View File

@ -15,6 +15,7 @@ var assert = chai.assert,
afterEach(function () { afterEach(function () {
if (dp && destroy) { if (dp && destroy) {
dp.destroy(); dp.destroy();
dp = '';
} }
destroy = true; destroy = true;
@ -78,6 +79,39 @@ var assert = chai.assert,
expect(dates).to.have.length(2) expect(dates).to.have.length(2)
}) })
}); });
describe('onShow', function () {
it('should add callback when datepicker is showing', function () {
var test = '';
dp = $input.datepicker({
onShow: function (dp, completed) {
if (!completed) {
test = dp;
}
}
}).data('datepicker');
dp.show();
expect(test).to.be.equal(dp);
})
});
describe('onHide', function () {
it('should add callback when datepicker is hiding (after transition completed)', function () {
var test = '';
dp = $input.datepicker({
onHide: function (dp, completed) {
if (!completed) {
test = dp;
}
}
}).data('datepicker');
dp.show();
dp.hide();
expect(test).to.be.equal(dp);
});
});
describe('onRenderCell', function () { describe('onRenderCell', function () {
it('should add callback when cell is rendered', function () { it('should add callback when cell is rendered', function () {

View File

@ -856,6 +856,26 @@ describe('Options', function () {
}) })
}); });
describe('onlyTimepicker', function () {
it('only timepicker should be visible', function () {
dp = $input.datepicker({
timepicker: true,
onlyTimepicker: true
}).data('datepicker');
var $time = $('.datepicker--time', dp.$datepicker),
$cells = $('.datepicker--cells', dp.$datepicker),
$nav = $('.datepicker--nav-title', dp.$datepicker),
_class = dp.$datepicker.hasClass('-only-timepicker-');
expect($time).to.have.length(1);
expect($cells).to.have.length(0);
expect($nav).to.have.length(0);
expect(_class).to.be.equal(true);
})
});
describe('dateTimeSeparator', function () { describe('dateTimeSeparator', function () {
it('should define separator between date string and time', function () { it('should define separator between date string and time', function () {
var date = new Date(2016,2,9,11,24); var date = new Date(2016,2,9,11,24);

View File

@ -5,7 +5,6 @@ var assert = chai.assert,
describe('Datepicker', function () { describe('Datepicker', function () {
describe('getDaysCount', function () { describe('getDaysCount', function () {
it('should return 31 days in December', function () { it('should return 31 days in December', function () {
console.log(plugin.getDaysCount);
assert.equal(plugin.getDaysCount(new Date(2015, 11)), 31) assert.equal(plugin.getDaysCount(new Date(2015, 11)), 31)
}); });
it('should return 30 days in September', function () { it('should return 30 days in September', function () {

View File

@ -3,8 +3,9 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Air datepicker visual tests</title> <title>Air datepicker visual tests</title>
<script type="text/javascript" src="bower_components/jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="dist/js/datepicker.js"></script> <script type="text/javascript" src="dist/js/datepicker.js"></script>
<script type="text/javascript" src="dist/js/i18n/datepicker.en.js"></script>
<link rel="stylesheet" href="dist/css/datepicker.css"/> <link rel="stylesheet" href="dist/css/datepicker.css"/>
<link rel="stylesheet" href="docs/css/style.css"/> <link rel="stylesheet" href="docs/css/style.css"/>
<script type="text/javascript"> <script type="text/javascript">
@ -31,7 +32,7 @@
<div class="row"> <div class="row">
<div class="vt-tile"> <div class="vt-tile">
<h2>Default</h2> <h2>Default</h2>
<div class="datepicker-here"></div> <div class="datepicker-here" data-language="en"></div>
</div> </div>
</div> </div>
</article> </article>
@ -41,11 +42,11 @@
<div class="row"> <div class="row">
<div class="vt-tile"> <div class="vt-tile">
<h2>{range: true}</h2> <h2>{range: true}</h2>
<div class="datepicker-here" data-range="true"></div> <div class="datepicker-here" data-language="en" data-range="true"></div>
</div> </div>
<div class="vt-tile"> <div class="vt-tile">
<h2>{range: true, onSelect: ...}</h2> <h2>{range: true, onSelect: ...}</h2>
<div class="datepicker-here" id="dp-3" data-range="true"></div> <div class="datepicker-here" data-language="en" id="dp-3" data-range="true"></div>
<script type="text/javascript"> <script type="text/javascript">
$('#dp-3').datepicker({ $('#dp-3').datepicker({
onSelect: function (fd) { onSelect: function (fd) {
@ -56,7 +57,7 @@
</div> </div>
<div class="vt-tile"> <div class="vt-tile">
<h2>{range: true, onSelect: ...}</h2> <h2>{range: true, onSelect: ...}</h2>
<input class="datepicker-here" id="dp-4" data-range="true"/> <input class="datepicker-here" data-language="en" id="dp-4" data-range="true"/>
<script type="text/javascript"> <script type="text/javascript">
$('#dp-4').datepicker({ $('#dp-4').datepicker({
onSelect: function (fd) { onSelect: function (fd) {
@ -73,17 +74,29 @@
<div class="row"> <div class="row">
<div class="vt-tile"> <div class="vt-tile">
<h2>{timepicker: true}</h2> <h2>{timepicker: true}</h2>
<div class="datepicker-here" data-timepicker="true"></div> <div id="test" class="datepicker-here" data-language="en" data-timepicker="true"></div>
<script type="text/javascript">
$('#test').datepicker({
toggleSelected: false,
inline: true,
timeFormat: 'hh:ii:ss',
onSelect: function (fd) {
console.log(arguments)
log(fd)
}
})
</script>
</div> </div>
<div class="vt-tile"> <div class="vt-tile">
<h2>{onChange: ..., toggleSelected: false, range: true}</h2> <h2>{onChange: ..., toggleSelected: false, range: true}</h2>
<input id="dp-5" class="datepicker-here" data-timepicker="true" /> <input id="dp-5" class="datepicker-here" data-language="en" data-timepicker="true" />
<script type="text/javascript"> <script type="text/javascript">
$('#dp-5').datepicker({ $('#dp-5').datepicker({
toggleSelected: false, toggleSelected: false,
inline: true, inline: true,
range: true, range: true,
onSelect: function (fd) { onSelect: function (fd) {
console.log(arguments)
log(fd) log(fd)
} }
}) })
@ -91,11 +104,11 @@
</div> </div>
<div class="vt-tile"> <div class="vt-tile">
<h2>{timepicker: true}</h2> <h2>{timepicker: true}</h2>
<input class="datepicker-here" data-timepicker="true" /> <input class="datepicker-here" data-language="en" data-timepicker="true" />
</div> </div>
<div class="vt-tile"> <div class="vt-tile">
<h2>{timepicker: true, minDate: new Date()}</h2> <h2>{timepicker: true, minDate: new Date()}</h2>
<input class="datepicker-here" id="dp-6"/> <input class="datepicker-here" data-language="en" id="dp-6"/>
<script type="text/javascript"> <script type="text/javascript">
$('#dp-6').datepicker({ $('#dp-6').datepicker({
minDate: new Date(), minDate: new Date(),