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
### 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
* added possibility to select single date when `{range: true}`
* added support of 12 hours mode in `altFieldDateFormat`

View File

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

View File

@ -18,31 +18,46 @@
background: 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 {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap; }
-ms-flex-wrap: wrap;
flex-wrap: wrap; }
.datepicker--cell {
border-radius: 4px;
box-sizing: border-box;
cursor: pointer;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
position: relative;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
height: 32px;
z-index: 1; }
.datepicker--cell.-focus- {
@ -91,28 +106,22 @@
cursor: default; }
.datepicker--days-names {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: 8px 0 3px; }
.datepicker--day-name {
color: #FF9A19;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-ms-flex: 1;
flex: 1;
text-align: center;
text-transform: uppercase;
font-size: .8em; }
@ -181,29 +190,20 @@
position: absolute;
left: -100000px;
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, -webkit-transform 0.3s ease;
z-index: 100; }
.datepicker.-from-top- {
-webkit-transform: translateY(-8px);
transform: translateY(-8px); }
transform: translateY(-8px); }
.datepicker.-from-right- {
-webkit-transform: translateX(8px);
transform: translateX(8px); }
transform: translateX(8px); }
.datepicker.-from-bottom- {
-webkit-transform: translateY(8px);
transform: translateY(8px); }
transform: translateY(8px); }
.datepicker.-from-left- {
-webkit-transform: translateX(-8px);
transform: translateX(-8px); }
transform: translateX(-8px); }
.datepicker.active {
opacity: 1;
-webkit-transform: translate(0);
transform: translate(0);
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; }
transform: translate(0);
transition: opacity 0.3s ease, transform 0.3s ease, left 0s 0s; }
.datepicker-inline .datepicker {
border-color: #d7d7d7;
@ -212,8 +212,7 @@
left: auto;
right: auto;
opacity: 1;
-webkit-transform: none;
transform: none; }
transform: none; }
.datepicker-inline .datepicker--pointer {
display: none; }
@ -221,6 +220,8 @@
.datepicker--content {
box-sizing: content-box;
padding: 4px; }
.-only-timepicker- .datepicker--content {
display: none; }
.datepicker--pointer {
position: absolute;
@ -232,20 +233,16 @@
z-index: -1; }
.-top-left- .datepicker--pointer, .-top-center- .datepicker--pointer, .-top-right- .datepicker--pointer {
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: 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: 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: calc(100% - 4px);
-webkit-transform: rotate(45deg);
transform: rotate(45deg); }
transform: rotate(45deg); }
.-top-left- .datepicker--pointer, .-bottom-left- .datepicker--pointer {
left: 10px; }
.-top-right- .datepicker--pointer, .-bottom-right- .datepicker--pointer {
@ -288,28 +285,25 @@
Navigation
------------------------------------------------- */
.datepicker--nav {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
border-bottom: 1px solid #efefef;
min-height: 32px;
padding: 4px; }
.-only-timepicker- .datepicker--nav {
display: none; }
.datepicker--nav-title,
.datepicker--nav-action {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
cursor: pointer;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center; }
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center; }
.datepicker--nav-action {
width: 32px;
@ -344,7 +338,6 @@
background: none; }
.datepicker--buttons {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 4px;
@ -354,18 +347,14 @@
color: #4EB5E6;
cursor: pointer;
border-radius: 4px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
display: -webkit-inline-flex;
-ms-flex: 1;
flex: 1;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
height: 32px; }
.datepicker--button:hover {
color: #4a4a4a;
@ -396,24 +385,22 @@
------------------------------------------------- */
.datepicker--time {
border-top: 1px solid #efefef;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-ms-flex-align: center;
align-items: center;
padding: 4px;
position: relative; }
.datepicker--time.-am-pm- .datepicker--time-sliders {
-webkit-flex: 0 1 138px;
-ms-flex: 0 1 138px;
flex: 0 1 138px;
-ms-flex: 0 1 138px;
flex: 0 1 138px;
max-width: 138px; }
.-only-timepicker- .datepicker--time {
border-top: none; }
.datepicker--time-sliders {
-webkit-flex: 0 1 153px;
-ms-flex: 0 1 153px;
flex: 0 1 153px;
-ms-flex: 0 1 153px;
flex: 0 1 153px;
margin-right: 10px;
max-width: 153px; }
@ -422,32 +409,31 @@
font-size: 12px; }
.datepicker--time-current {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
-ms-flex-align: center;
align-items: center;
-ms-flex: 1;
flex: 1;
font-size: 14px;
text-align: center;
margin: 0 0 0 10px; }
margin: 0 10px; }
.datepicker--time-current-colon {
margin: 0 2px 3px;
line-height: 1; }
.datepicker--time-current-hours,
.datepicker--time-current-minutes {
.datepicker--time-current-minutes,
.datepicker--time-current-seconds {
line-height: 1;
font-size: 19px;
font-size: 14px;
font-family: "Century Gothic", CenturyGothic, AppleGothic, sans-serif;
position: relative;
z-index: 1; }
.datepicker--time-current-hours:after,
.datepicker--time-current-minutes:after {
.datepicker--time-current-minutes:after,
.datepicker--time-current-seconds:after {
content: '';
background: #f0f0f0;
border-radius: 4px;
@ -459,26 +445,24 @@
z-index: -1;
opacity: 0; }
.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; }
.datepicker--time-current-ampm {
text-transform: uppercase;
-webkit-align-self: flex-end;
-ms-flex-item-align: end;
align-self: flex-end;
-ms-flex-item-align: start;
align-self: flex-start;
color: #9c9c9c;
margin-left: 6px;
font-size: 11px;
margin-bottom: 1px; }
.datepicker--time-row {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-ms-flex-align: center;
align-items: center;
font-size: 11px;
height: 17px;
background: linear-gradient(to right, #dedede, #dedede) left 50%/100% 1px no-repeat; }
@ -487,9 +471,8 @@
.datepicker--time-row input[type='range'] {
background: none;
cursor: pointer;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
-ms-flex: 1;
flex: 1;
height: 100%;
padding: 0;
margin: 0;
@ -587,30 +570,9 @@
width: 1px;
left: calc(50% - 1px);
top: calc(50% + 1px);
-webkit-transform: translateY(-100%);
transform: translateY(-100%); }
transform: translateY(-100%); }
.datepicker--time-icon:before {
width: .4em;
height: 1px;
top: 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 () {
var pluginName = 'datepicker',
var VERSION = '2.2.3',
pluginName = 'datepicker',
autoInitSelector = '.datepicker-here',
$body, $datepickersContainer,
containerBuilt = false,
@ -62,17 +63,23 @@
// timepicker
timepicker: false,
onlyTimepicker: false,
dateTimeSeparator: ' ',
timeFormat: '',
minHours: 0,
maxHours: 24,
minMinutes: 0,
maxMinutes: 59,
minSeconds: 0,
maxSeconds: 59,
hoursStep: 1,
minutesStep: 1,
secondsStep: 1,
// events
onSelect: '',
onShow: '',
onHide: '',
onChangeMonth: '',
onChangeYear: '',
onChangeDecade: '',
@ -138,6 +145,7 @@
datepicker = Datepicker;
datepicker.prototype = {
VERSION: VERSION,
viewIndexes: ['days', 'months', 'years'],
init: function () {
@ -154,7 +162,7 @@
this._setPositionClasses(this.opts.position);
this._bindEvents()
}
if (this.opts.keyboardNav) {
if (this.opts.keyboardNav && !this.opts.onlyTimepicker) {
this._bindKeyboardEvents();
}
this.$datepicker.on('mousedown', this._onMouseDownDatepicker.bind(this));
@ -170,6 +178,10 @@
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].show();
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);
}
if (this.opts.onlyTimepicker) {
this.loc.dateFormat = this.loc.timeFormat;
}
var boundary = this._getWordBoundaryRegExp;
if (this.loc.timeFormat.match(boundary('aa')) ||
this.loc.timeFormat.match(boundary('AA'))
@ -289,7 +305,8 @@
parsedSelected.month,
parsedSelected.date,
parsedSelected.hours,
parsedSelected.minutes
parsedSelected.minutes,
parsedSelected.seconds
);
formattedDates = selectedDates.map(function (date) {
@ -305,11 +322,11 @@
parsedDate.month,
parsedDate.date,
parsedDate.hours,
parsedDate.minutes
parsedDate.minutes,
parsedDate.seconds
);
})
}
this._prevOnSelectValue = formattedDates;
this.opts.onSelect(formattedDates, dates, this);
},
@ -364,6 +381,7 @@
hours = d.hours,
ampm = string.match(boundary('aa')) || string.match(boundary('AA')),
dayPeriod = 'am',
replacer = this._replacer,
validHours;
if (this.opts.timepicker && this.timepicker && ampm) {
@ -377,50 +395,63 @@
case /@/.test(result):
result = result.replace(/@/, date.getTime());
case /aa/.test(result):
result = result.replace(boundary('aa'), dayPeriod);
result = replacer(result, boundary('aa'), dayPeriod);
case /AA/.test(result):
result = result.replace(boundary('AA'), dayPeriod.toUpperCase());
result = replacer(result, boundary('AA'), dayPeriod.toUpperCase());
case /dd/.test(result):
result = result.replace(boundary('dd'), d.fullDate);
result = replacer(result, boundary('dd'), d.fullDate);
case /d/.test(result):
result = result.replace(boundary('d'), d.date);
result = replacer(result, boundary('d'), d.date);
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):
result = result.replace(boundary('D'), locale.daysShort[d.day]);
result = replacer(result, boundary('D'), locale.daysShort[d.day]);
case /mm/.test(result):
result = result.replace(boundary('mm'), d.fullMonth);
result = replacer(result, boundary('mm'), d.fullMonth);
case /m/.test(result):
result = result.replace(boundary('m'), d.month + 1);
result = replacer(result, boundary('m'), d.month + 1);
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):
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):
result = result.replace(boundary('ii'), d.fullMinutes);
result = replacer(result, boundary('ii'), d.fullMinutes);
case /i/.test(result):
result = result.replace(boundary('i'), d.minutes);
result = replacer(result, boundary('i'), d.minutes);
case /hh/.test(result):
result = result.replace(boundary('hh'), fullHours);
result = replacer(result, boundary('hh'), fullHours);
case /h/.test(result):
result = result.replace(boundary('h'), hours);
result = replacer(result, boundary('h'), hours);
case /yyyy/.test(result):
result = result.replace(boundary('yyyy'), d.year);
result = replacer(result, boundary('yyyy'), d.year);
case /yyyy1/.test(result):
result = result.replace(boundary('yyyy1'), decade[0]);
result = replacer(result, boundary('yyyy1'), decade[0]);
case /yyyy2/.test(result):
result = result.replace(boundary('yyyy2'), decade[1]);
result = replacer(result, boundary('yyyy2'), decade[1]);
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;
},
_getWordBoundaryRegExp: function (sign) {
return new RegExp('\\b(?=[a-zA-Z0-9äöüßÄÖÜ<])' + sign + '(?![>a-zA-Z0-9äöüßÄÖÜ])');
_replacer: function (str, reg, data) {
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) {
var _this = this,
opts = _this.opts,
@ -454,6 +485,7 @@
if (this.timepicker) {
date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes)
date.setSeconds(this.timepicker.seconds)
}
if (_this.view == 'days') {
@ -595,7 +627,7 @@
this._syncWithMinMaxDates();
this._defineLocale(this.opts.language);
this.nav._addButtonsIfNeed();
this.nav._render();
if (!this.opts.onlyTimepicker) this.nav._render();
this.views[this.currentView]._render();
if (this.elIsInput && !this.opts.inline) {
@ -609,6 +641,10 @@
this.$datepicker.addClass(this.opts.classes)
}
if (this.opts.onlyTimepicker) {
this.$datepicker.addClass('-only-timepicker-');
}
if (this.opts.timepicker) {
if (lastSelectedDate) this.timepicker._handleDate(lastSelectedDate);
this.timepicker._updateRanges();
@ -617,6 +653,7 @@
if (lastSelectedDate) {
lastSelectedDate.setHours(this.timepicker.hours);
lastSelectedDate.setMinutes(this.timepicker.minutes);
lastSelectedDate.setSeconds(this.timepicker.seconds);
}
}
@ -782,12 +819,20 @@
},
show: function () {
var onShow = this.opts.onShow;
this.setPosition(this.opts.position);
this.$datepicker.addClass('active');
this.visible = true;
if (onShow) {
this._bindVisionEvents(onShow)
}
},
hide: function () {
var onHide = this.opts.onHide;
this.$datepicker
.removeClass('active')
.css({
@ -800,6 +845,10 @@
this.inFocus = false;
this.visible = false;
this.$el.blur();
if (onHide) {
this._bindVisionEvents(onHide)
}
},
down: function (date) {
@ -810,6 +859,12 @@
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) {
date = date || this.focused || this.date;
@ -1023,7 +1078,7 @@
}
$cell = this.views[this.currentView].$el.find(selector);
return $cell.length ? $cell : '';
return $cell.length ? $cell : $('');
},
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) {
if (!this.visible) {
this.show();
@ -1118,11 +1197,12 @@
if (this.timepicker) {
this.focused.setHours(this.timepicker.hours);
this.focused.setMinutes(this.timepicker.minutes);
this.focused.setSeconds(this.timepicker.seconds);
}
this.selectDate(this.focused);
} else if (alreadySelected && this.opts.toggleSelected){
this.removeDate(this.focused);
return;
}
this._handleAlreadySelectedDates(alreadySelected, this.focused)
}
}
}
@ -1179,7 +1259,7 @@
this.silent = false;
},
_onTimeChange: function (e, h, m) {
_onTimeChange: function (e, h, m, s) {
var date = new Date(),
selectedDates = this.selectedDates,
selected = false;
@ -1191,6 +1271,7 @@
date.setHours(h);
date.setMinutes(m);
date.setSeconds(s);
if (!selected && !this._getCell(date).hasClass('-disabled-')) {
this.selectDate(date);
@ -1206,6 +1287,7 @@
if (this.timepicker) {
date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes);
date.setSeconds(this.timepicker.seconds)
}
this.selectDate(date);
},
@ -1329,7 +1411,9 @@
hours: date.getHours(),
fullHours: date.getHours() < 10 ? '0' + date.getHours() : date.getHours() ,
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.type = type;
this.opts = opts;
this.$el = $('');
if (this.opts.onlyTimepicker) return;
this.init();
};
@ -1492,12 +1578,6 @@
render = {},
html = d.date;
if (opts.onRenderCell) {
render = opts.onRenderCell(date, type) || {};
html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : '';
}
switch (type) {
case 'day':
if (parent.isWeekend(d.day)) classes += " -weekend-";
@ -1530,6 +1610,7 @@
html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : '';
}
if (opts.range) {
if (dp.isSame(minRange, date, type)) classes += ' -range-from-';
if (dp.isSame(maxRange, date, type)) classes += ' -range-to-';
@ -1673,6 +1754,7 @@
},
_render: function () {
if (this.opts.onlyTimepicker) return;
this._renderTypes[this.type].bind(this)();
},
@ -1691,6 +1773,7 @@
},
show: function () {
if (this.opts.onlyTimepicker) return;
this.$el.addClass('active');
this.acitve = true;
},
@ -1719,27 +1802,11 @@
if (!alreadySelected) {
dp._trigger('clickCell', selectedDate);
return;
}
if (alreadySelected && this.opts.range) {
// 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);
}
dp._handleAlreadySelectedDates.bind(dp, alreadySelected, 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) {
@ -1784,7 +1851,9 @@
},
_buildBaseHtml: function () {
this._render();
if (!this.opts.onlyTimepicker) {
this._render();
}
this._addButtonsIfNeed();
},
@ -1841,10 +1910,10 @@
switch (this.d.view) {
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')
}
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')
}
break;
@ -1857,10 +1926,11 @@
}
break;
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')
}
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')
}
break;
@ -1898,9 +1968,11 @@
;(function () {
var template = '<div class="datepicker--time">' +
'<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-minutes">#{minValue}</span>' +
' <span class="datepicker--time-current-colon">:</span>' +
' <span class="datepicker--time-current-seconds">#{secValue}</span>' +
'</div>' +
'<div class="datepicker--time-sliders">' +
' <div class="datepicker--time-row">' +
@ -1909,6 +1981,9 @@
' <div class="datepicker--time-row">' +
' <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' +
' </div>' +
' <div class="datepicker--time-row">' +
' <input type="range" name="seconds" value="#{secValue}" min="#{secMin}" max="#{secMax}" step="#{secStep}"/>' +
' </div>' +
'</div>' +
'</div>',
datepicker = $.fn.datepicker,
@ -1944,6 +2019,7 @@
this._handleDate(date);
this.hours = _date.hours < this.minHours ? this.minHours : _date.hours;
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) {
this.minHours = date.getHours();
this.minMinutes = date.getMinutes();
this.minSeconds = date.getSeconds();
// 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
@ -1968,6 +2045,7 @@
_setMaxTimeFromDate: function (date) {
this.maxHours = date.getHours();
this.maxMinutes = date.getMinutes();
this.maxSeconds = date.getSeconds();
if (this.d.lastSelectedDate) {
if (this.d.lastSelectedDate.getHours() < date.getHours()) {
@ -1979,12 +2057,15 @@
_setDefaultMinMaxTime: function () {
var maxHours = 23,
maxMinutes = 59,
maxSeconds = 59,
opts = this.opts;
this.minHours = opts.minHours < 0 || opts.minHours > maxHours ? 0 : opts.minHours;
this.minMinutes = opts.minMinutes < 0 || opts.minMinutes > maxMinutes ? 0 : opts.minMinutes;
this.maxHours = opts.maxHours < 0 || opts.maxHours > maxHours ? maxHours : opts.maxHours;
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) {
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 () {
@ -2012,11 +2099,16 @@
hourMin: this.minHours,
hourMax: lz(this.maxHours),
hourStep: this.opts.hoursStep,
hourValue: lz(this.displayHours),
hourValue: this.hours,
hourVisible: lz(this.displayHours),
minMin: this.minMinutes,
minMax: lz(this.maxMinutes),
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);
@ -2024,8 +2116,10 @@
this.$ranges = $('[type="range"]', this.$timepicker);
this.$hours = $('[name="hours"]', this.$timepicker);
this.$minutes = $('[name="minutes"]', this.$timepicker);
this.$seconds = $('[name="seconds"]', this.$timepicker);
this.$hoursText = $('.datepicker--time-current-hours', this.$timepicker);
this.$minutesText = $('.datepicker--time-current-minutes', this.$timepicker);
this.$secondsText = $('.datepicker--time-current-seconds', this.$timepicker);
if (this.d.ampm) {
this.$ampm = $('<span class="datepicker--time-current-ampm">')
@ -2038,10 +2132,12 @@
_updateCurrentTime: function () {
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.$minutesText.html(m);
this.$secondsText.html(s);
if (this.d.ampm) {
this.$ampm.html(this.dayPeriod);
@ -2057,7 +2153,12 @@
this.$minutes.attr({
min: this.minMinutes,
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._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.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='../dist/js/datepicker.js')
script(src='../dist/js/i18n/datepicker.en.js')
script(src='js/logger.js')
body
div.wrapper
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;
}
.row {
display: flex;
> * {
flex: 1;
}
}
article {
h2, h3 {
position: relative;
@ -506,4 +513,57 @@ a {
span {
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",
"version": "2.1.0",
"version": "2.2.3",
"devDependencies": {
"autoprefixer": "^6.1.0",
"browserify": "^13.0.0",
@ -25,7 +25,7 @@
"vinyl-source-stream": "^1.1.0"
},
"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)",
"main": "src/js/air-datepicker.js",

View File

@ -21,7 +21,9 @@
this.d = d;
this.type = type;
this.opts = opts;
this.$el = $('');
if (this.opts.onlyTimepicker) return;
this.init();
};
@ -67,12 +69,6 @@
render = {},
html = d.date;
if (opts.onRenderCell) {
render = opts.onRenderCell(date, type) || {};
html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : '';
}
switch (type) {
case 'day':
if (parent.isWeekend(d.day)) classes += " -weekend-";
@ -105,6 +101,7 @@
html = render.html ? render.html : html;
classes += render.classes ? ' ' + render.classes : '';
}
if (opts.range) {
if (dp.isSame(minRange, date, type)) classes += ' -range-from-';
if (dp.isSame(maxRange, date, type)) classes += ' -range-to-';
@ -248,6 +245,7 @@
},
_render: function () {
if (this.opts.onlyTimepicker) return;
this._renderTypes[this.type].bind(this)();
},
@ -266,6 +264,7 @@
},
show: function () {
if (this.opts.onlyTimepicker) return;
this.$el.addClass('active');
this.acitve = true;
},
@ -294,27 +293,11 @@
if (!alreadySelected) {
dp._trigger('clickCell', selectedDate);
return;
}
if (alreadySelected && this.opts.range) {
// 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);
}
dp._handleAlreadySelectedDates.bind(dp, alreadySelected, 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) {

View File

@ -1,5 +1,6 @@
;(function () {
var pluginName = 'datepicker',
var VERSION = '2.2.3',
pluginName = 'datepicker',
autoInitSelector = '.datepicker-here',
$body, $datepickersContainer,
containerBuilt = false,
@ -62,17 +63,23 @@
// timepicker
timepicker: false,
onlyTimepicker: false,
dateTimeSeparator: ' ',
timeFormat: '',
minHours: 0,
maxHours: 24,
minMinutes: 0,
maxMinutes: 59,
minSeconds: 0,
maxSeconds: 59,
hoursStep: 1,
minutesStep: 1,
secondsStep: 1,
// events
onSelect: '',
onShow: '',
onHide: '',
onChangeMonth: '',
onChangeYear: '',
onChangeDecade: '',
@ -138,6 +145,7 @@
datepicker = Datepicker;
datepicker.prototype = {
VERSION: VERSION,
viewIndexes: ['days', 'months', 'years'],
init: function () {
@ -154,7 +162,7 @@
this._setPositionClasses(this.opts.position);
this._bindEvents()
}
if (this.opts.keyboardNav) {
if (this.opts.keyboardNav && !this.opts.onlyTimepicker) {
this._bindKeyboardEvents();
}
this.$datepicker.on('mousedown', this._onMouseDownDatepicker.bind(this));
@ -170,6 +178,10 @@
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].show();
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);
}
if (this.opts.onlyTimepicker) {
this.loc.dateFormat = this.loc.timeFormat;
}
var boundary = this._getWordBoundaryRegExp;
if (this.loc.timeFormat.match(boundary('aa')) ||
this.loc.timeFormat.match(boundary('AA'))
@ -289,7 +305,8 @@
parsedSelected.month,
parsedSelected.date,
parsedSelected.hours,
parsedSelected.minutes
parsedSelected.minutes,
parsedSelected.seconds
);
formattedDates = selectedDates.map(function (date) {
@ -305,11 +322,11 @@
parsedDate.month,
parsedDate.date,
parsedDate.hours,
parsedDate.minutes
parsedDate.minutes,
parsedDate.seconds
);
})
}
this._prevOnSelectValue = formattedDates;
this.opts.onSelect(formattedDates, dates, this);
},
@ -364,6 +381,7 @@
hours = d.hours,
ampm = string.match(boundary('aa')) || string.match(boundary('AA')),
dayPeriod = 'am',
replacer = this._replacer,
validHours;
if (this.opts.timepicker && this.timepicker && ampm) {
@ -377,50 +395,63 @@
case /@/.test(result):
result = result.replace(/@/, date.getTime());
case /aa/.test(result):
result = result.replace(boundary('aa'), dayPeriod);
result = replacer(result, boundary('aa'), dayPeriod);
case /AA/.test(result):
result = result.replace(boundary('AA'), dayPeriod.toUpperCase());
result = replacer(result, boundary('AA'), dayPeriod.toUpperCase());
case /dd/.test(result):
result = result.replace(boundary('dd'), d.fullDate);
result = replacer(result, boundary('dd'), d.fullDate);
case /d/.test(result):
result = result.replace(boundary('d'), d.date);
result = replacer(result, boundary('d'), d.date);
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):
result = result.replace(boundary('D'), locale.daysShort[d.day]);
result = replacer(result, boundary('D'), locale.daysShort[d.day]);
case /mm/.test(result):
result = result.replace(boundary('mm'), d.fullMonth);
result = replacer(result, boundary('mm'), d.fullMonth);
case /m/.test(result):
result = result.replace(boundary('m'), d.month + 1);
result = replacer(result, boundary('m'), d.month + 1);
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):
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):
result = result.replace(boundary('ii'), d.fullMinutes);
result = replacer(result, boundary('ii'), d.fullMinutes);
case /i/.test(result):
result = result.replace(boundary('i'), d.minutes);
result = replacer(result, boundary('i'), d.minutes);
case /hh/.test(result):
result = result.replace(boundary('hh'), fullHours);
result = replacer(result, boundary('hh'), fullHours);
case /h/.test(result):
result = result.replace(boundary('h'), hours);
result = replacer(result, boundary('h'), hours);
case /yyyy/.test(result):
result = result.replace(boundary('yyyy'), d.year);
result = replacer(result, boundary('yyyy'), d.year);
case /yyyy1/.test(result):
result = result.replace(boundary('yyyy1'), decade[0]);
result = replacer(result, boundary('yyyy1'), decade[0]);
case /yyyy2/.test(result):
result = result.replace(boundary('yyyy2'), decade[1]);
result = replacer(result, boundary('yyyy2'), decade[1]);
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;
},
_getWordBoundaryRegExp: function (sign) {
return new RegExp('\\b(?=[a-zA-Z0-9äöüßÄÖÜ<])' + sign + '(?![>a-zA-Z0-9äöüßÄÖÜ])');
_replacer: function (str, reg, data) {
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) {
var _this = this,
opts = _this.opts,
@ -454,6 +485,7 @@
if (this.timepicker) {
date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes)
date.setSeconds(this.timepicker.seconds)
}
if (_this.view == 'days') {
@ -595,7 +627,7 @@
this._syncWithMinMaxDates();
this._defineLocale(this.opts.language);
this.nav._addButtonsIfNeed();
this.nav._render();
if (!this.opts.onlyTimepicker) this.nav._render();
this.views[this.currentView]._render();
if (this.elIsInput && !this.opts.inline) {
@ -609,6 +641,10 @@
this.$datepicker.addClass(this.opts.classes)
}
if (this.opts.onlyTimepicker) {
this.$datepicker.addClass('-only-timepicker-');
}
if (this.opts.timepicker) {
if (lastSelectedDate) this.timepicker._handleDate(lastSelectedDate);
this.timepicker._updateRanges();
@ -617,6 +653,7 @@
if (lastSelectedDate) {
lastSelectedDate.setHours(this.timepicker.hours);
lastSelectedDate.setMinutes(this.timepicker.minutes);
lastSelectedDate.setSeconds(this.timepicker.seconds);
}
}
@ -782,12 +819,20 @@
},
show: function () {
var onShow = this.opts.onShow;
this.setPosition(this.opts.position);
this.$datepicker.addClass('active');
this.visible = true;
if (onShow) {
this._bindVisionEvents(onShow)
}
},
hide: function () {
var onHide = this.opts.onHide;
this.$datepicker
.removeClass('active')
.css({
@ -800,6 +845,10 @@
this.inFocus = false;
this.visible = false;
this.$el.blur();
if (onHide) {
this._bindVisionEvents(onHide)
}
},
down: function (date) {
@ -810,6 +859,12 @@
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) {
date = date || this.focused || this.date;
@ -1023,7 +1078,7 @@
}
$cell = this.views[this.currentView].$el.find(selector);
return $cell.length ? $cell : '';
return $cell.length ? $cell : $('');
},
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) {
if (!this.visible) {
this.show();
@ -1118,11 +1197,12 @@
if (this.timepicker) {
this.focused.setHours(this.timepicker.hours);
this.focused.setMinutes(this.timepicker.minutes);
this.focused.setSeconds(this.timepicker.seconds);
}
this.selectDate(this.focused);
} else if (alreadySelected && this.opts.toggleSelected){
this.removeDate(this.focused);
return;
}
this._handleAlreadySelectedDates(alreadySelected, this.focused)
}
}
}
@ -1179,7 +1259,7 @@
this.silent = false;
},
_onTimeChange: function (e, h, m) {
_onTimeChange: function (e, h, m, s) {
var date = new Date(),
selectedDates = this.selectedDates,
selected = false;
@ -1191,6 +1271,7 @@
date.setHours(h);
date.setMinutes(m);
date.setSeconds(s);
if (!selected && !this._getCell(date).hasClass('-disabled-')) {
this.selectDate(date);
@ -1206,6 +1287,7 @@
if (this.timepicker) {
date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes);
date.setSeconds(this.timepicker.seconds)
}
this.selectDate(date);
},
@ -1329,7 +1411,9 @@
hours: date.getHours(),
fullHours: date.getHours() < 10 ? '0' + date.getHours() : date.getHours() ,
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 () {
this._render();
if (!this.opts.onlyTimepicker) {
this._render();
}
this._addButtonsIfNeed();
},
@ -87,10 +89,10 @@
switch (this.d.view) {
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')
}
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')
}
break;
@ -103,10 +105,11 @@
}
break;
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')
}
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')
}
break;

View File

@ -1,9 +1,11 @@
;(function () {
var template = '<div class="datepicker--time">' +
'<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-minutes">#{minValue}</span>' +
' <span class="datepicker--time-current-colon">:</span>' +
' <span class="datepicker--time-current-seconds">#{secValue}</span>' +
'</div>' +
'<div class="datepicker--time-sliders">' +
' <div class="datepicker--time-row">' +
@ -12,6 +14,9 @@
' <div class="datepicker--time-row">' +
' <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' +
' </div>' +
' <div class="datepicker--time-row">' +
' <input type="range" name="seconds" value="#{secValue}" min="#{secMin}" max="#{secMax}" step="#{secStep}"/>' +
' </div>' +
'</div>' +
'</div>',
datepicker = $.fn.datepicker,
@ -47,6 +52,7 @@
this._handleDate(date);
this.hours = _date.hours < this.minHours ? this.minHours : _date.hours;
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) {
this.minHours = date.getHours();
this.minMinutes = date.getMinutes();
this.minSeconds = date.getSeconds();
// 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
@ -71,6 +78,7 @@
_setMaxTimeFromDate: function (date) {
this.maxHours = date.getHours();
this.maxMinutes = date.getMinutes();
this.maxSeconds = date.getSeconds();
if (this.d.lastSelectedDate) {
if (this.d.lastSelectedDate.getHours() < date.getHours()) {
@ -82,12 +90,15 @@
_setDefaultMinMaxTime: function () {
var maxHours = 23,
maxMinutes = 59,
maxSeconds = 59,
opts = this.opts;
this.minHours = opts.minHours < 0 || opts.minHours > maxHours ? 0 : opts.minHours;
this.minMinutes = opts.minMinutes < 0 || opts.minMinutes > maxMinutes ? 0 : opts.minMinutes;
this.maxHours = opts.maxHours < 0 || opts.maxHours > maxHours ? maxHours : opts.maxHours;
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) {
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 () {
@ -115,11 +132,16 @@
hourMin: this.minHours,
hourMax: lz(this.maxHours),
hourStep: this.opts.hoursStep,
hourValue: lz(this.displayHours),
hourValue: this.hours,
hourVisible: lz(this.displayHours),
minMin: this.minMinutes,
minMax: lz(this.maxMinutes),
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);
@ -127,8 +149,10 @@
this.$ranges = $('[type="range"]', this.$timepicker);
this.$hours = $('[name="hours"]', this.$timepicker);
this.$minutes = $('[name="minutes"]', this.$timepicker);
this.$seconds = $('[name="seconds"]', this.$timepicker);
this.$hoursText = $('.datepicker--time-current-hours', this.$timepicker);
this.$minutesText = $('.datepicker--time-current-minutes', this.$timepicker);
this.$secondsText = $('.datepicker--time-current-seconds', this.$timepicker);
if (this.d.ampm) {
this.$ampm = $('<span class="datepicker--time-current-ampm">')
@ -141,10 +165,12 @@
_updateCurrentTime: function () {
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.$minutesText.html(m);
this.$secondsText.html(s);
if (this.d.ampm) {
this.$ampm.html(this.dayPeriod);
@ -160,7 +186,12 @@
this.$minutes.attr({
min: this.minMinutes,
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._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.update()

View File

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

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@ var assert = chai.assert,
afterEach(function () {
if (dp && destroy) {
dp.destroy();
dp = '';
}
destroy = true;
@ -78,6 +79,39 @@ var assert = chai.assert,
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 () {
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 () {
it('should define separator between date string and time', function () {
var date = new Date(2016,2,9,11,24);

View File

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

View File

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