begin range feature

This commit is contained in:
t1m0n 2015-12-07 15:55:33 +03:00
parent 6a3b12d34a
commit e028692caf
9 changed files with 204 additions and 27 deletions

View File

@ -36,15 +36,20 @@
-ms-flex-pack: center; -ms-flex-pack: center;
justify-content: center; justify-content: center;
height: 32px; height: 32px;
z-index: 1; } z-index: 1;
.datepicker--cell:hover, .datepicker--cell.-focus- { /*&:hover, */ }
.datepicker--cell.-focus- {
background: #f0f0f0; } background: #f0f0f0; }
.datepicker--cell.-current- { .datepicker--cell.-current- {
color: #4EB5E6; } color: #4EB5E6; }
.datepicker--cell.-current-.-focus- { .datepicker--cell.-current-.-focus- {
color: #4a4a4a; } color: #4a4a4a; }
.datepicker--cell.-current-:hover { .datepicker--cell.-in-range- {
color: #4a4a4a; } background: #a2ddf6;
color: #fff;
padding: 2px 0;
background-clip: content-box;
border-radius: 0; }
.datepicker--cell.-disabled- { .datepicker--cell.-disabled- {
cursor: default; cursor: default;
color: #aeaeae; color: #aeaeae;
@ -62,6 +67,10 @@
background: #5cc4ef; } background: #5cc4ef; }
.datepicker--cell.-selected-.-focus- { .datepicker--cell.-selected-.-focus- {
background: #45bced; } background: #45bced; }
.datepicker--cell.-range-from- {
border-radius: 4px 0 0 4px; }
.datepicker--cell.-range-to- {
border-radius: 0 4px 4px 0; }
.datepicker--days-names { .datepicker--days-names {
display: -webkit-flex; display: -webkit-flex;

File diff suppressed because one or more lines are too long

90
dist/js/datepicker.js vendored
View File

@ -44,6 +44,7 @@ var Datepicker;
multipleDates: false, // Boolean or Number multipleDates: false, // Boolean or Number
multipleDatesSeparator: ',', multipleDatesSeparator: ',',
range: true,
todayButton: false, todayButton: false,
clearButton: false, clearButton: false,
@ -117,6 +118,8 @@ var Datepicker;
this.selectedDates = []; this.selectedDates = [];
this.views = {}; this.views = {};
this.keys = []; this.keys = [];
this.minRange = '';
this.maxRange = '';
this.init() this.init()
}; };
@ -150,6 +153,9 @@ var Datepicker;
this.nav = new Datepicker.Navigation(this, this.opts); this.nav = new Datepicker.Navigation(this, this.opts);
this.view = this.currentView; this.view = this.currentView;
this.$datepicker.on('mouseenter', '.datepicker--cell', this._onMouseEnterCell.bind(this));
this.$datepicker.on('mouseleave', '.datepicker--cell', this._onMouseLeaveCell.bind(this));
this.inited = true; this.inited = true;
}, },
@ -329,6 +335,8 @@ var Datepicker;
selectDate: function (date) { selectDate: function (date) {
var d = this.parsedDate, var d = this.parsedDate,
selectedDates = this.selectedDates,
len = selectedDates.length,
newDate = ''; newDate = '';
if (!(date instanceof Date)) return; if (!(date instanceof Date)) return;
@ -336,7 +344,6 @@ var Datepicker;
if (this.view == 'days') { if (this.view == 'days') {
if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) { if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) {
newDate = new Date(date.getFullYear(), date.getMonth(), 1); newDate = new Date(date.getFullYear(), date.getMonth(), 1);
} }
} }
@ -354,10 +361,22 @@ var Datepicker;
} }
if (this.opts.multipleDates) { if (this.opts.multipleDates) {
if (this.selectedDates.length === this.opts.multipleDates) return; if (len === this.opts.multipleDates) return;
if (!this._isSelected(date)) { if (!this._isSelected(date)) {
this.selectedDates.push(date); this.selectedDates.push(date);
} }
} else if (this.opts.range) {
if (len == 2) {
this.selectedDates = [date]
} else if (len == 1) {
if (Datepicker.less(this.selectedDates[0], date, this.cellType)) {
this.selectedDates = [date]
} else {
this.selectedDates.push(date);
}
} else {
this.selectedDates = [date]
}
} else { } else {
this. selectedDates = [date]; this. selectedDates = [date];
} }
@ -516,6 +535,15 @@ var Datepicker;
} }
}, },
_getDateFromCell: function (cell) {
var curDate = this.parsedDate,
year = cell.data('year') || curDate.year,
month = cell.data('month') == undefined ? curDate.month : cell.data('month'),
date = cell.data('date') || 1;
return new Date(year, month, date);
},
_setPositionClasses: function (pos) { _setPositionClasses: function (pos) {
pos = pos.split(' '); pos = pos.split(' ');
var main = pos[0], var main = pos[0],
@ -835,9 +863,9 @@ var Datepicker;
}, },
_onBlur: function () { _onBlur: function () {
if (!this.inFocus && this.visible) { //if (!this.inFocus && this.visible) {
this.hide(); // this.hide();
} //}
}, },
_onMouseDownDatepicker: function (e) { _onMouseDownDatepicker: function (e) {
@ -907,7 +935,31 @@ var Datepicker;
this._handleHotKey(hotKey); this._handleHotKey(hotKey);
}, },
_onMouseEnterCell: function (e) {
var $cell = $(e.target).closest('.datepicker--cell'),
date = this._getDateFromCell($cell);
// Prevent from unnecessary rendering and setting new currentDate
this.silent = true;
if (this.focused) {
this.focused = ''
}
$cell.addClass('-focus-');
this.focused = date;
this.silent = false;
},
_onMouseLeaveCell: function (e) {
var $cell = $(e.target).closest('.datepicker--cell'),
date = this._getDateFromCell($cell);
$cell.removeClass('-focus-');
this.silent = true;
this.focused = '';
this.silent = false;
},
set focused(val) { set focused(val) {
if (!val && this.focused) { if (!val && this.focused) {
@ -918,6 +970,7 @@ var Datepicker;
} }
} }
this._focused = val; this._focused = val;
if (this.silent) return;
this.date = val; this.date = val;
}, },
@ -941,7 +994,6 @@ var Datepicker;
this.setPosition(); this.setPosition();
} }
} }
return val; return val;
}, },
@ -1035,6 +1087,7 @@ var Datepicker;
}; };
Datepicker.isSame = function (date1, date2, type) { Datepicker.isSame = function (date1, date2, type) {
if (!date1 || !date2) return false;
var d1 = Datepicker.getParsedDate(date1), var d1 = Datepicker.getParsedDate(date1),
d2 = Datepicker.getParsedDate(date2), d2 = Datepicker.getParsedDate(date2),
_type = type ? type : 'day', _type = type ? type : 'day',
@ -1048,6 +1101,14 @@ var Datepicker;
return conditions[_type]; return conditions[_type];
}; };
Datepicker.less = function (dateCompareTo, date, type) {
return date.getTime() < dateCompareTo.getTime();
};
Datepicker.bigger = function (dateCompareTo, date, type) {
return date.getTime() > dateCompareTo.getTime();
};
Datepicker.language = { Datepicker.language = {
ru: { ru: {
days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'], days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],
@ -1189,6 +1250,21 @@ var Datepicker;
classes += render.classes ? ' ' + render.classes : ''; classes += render.classes ? ' ' + render.classes : '';
} }
if (this.opts.range) {
if (D.isSame(this.d.selectedDates[0], date)) classes += ' -range-from-';
if (D.isSame(this.d.selectedDates[1], date)) classes += ' -range-to-';
if (this.d.selectedDates.length == 1 && this.d.focused) {
if (Datepicker.bigger(this.d.selectedDates[0], date) && D.less(this.d.focused, date)) {
classes += ' -in-range-'
}
} else if (this.d.selectedDates.length == 2) {
if (D.bigger(this.d.selectedDates[0], date) && D.less(this.d.selectedDates[1], date)) {
classes += ' -in-range-'
}
}
}
if (D.isSame(currentDate, date, type)) classes += ' -current-'; if (D.isSame(currentDate, date, type)) classes += ' -current-';
if (this.d.focused && D.isSame(date, this.d.focused, type)) classes += ' -focus-'; if (this.d.focused && D.isSame(date, this.d.focused, type)) classes += ' -focus-';
if (this.d._isSelected(date, type)) classes += ' -selected-'; if (this.d._isSelected(date, type)) classes += ' -selected-';
@ -1305,6 +1381,7 @@ var Datepicker;
}, },
_render: function () { _render: function () {
console.log('render');
this._renderTypes[this.type].bind(this)(); this._renderTypes[this.type].bind(this)();
}, },
@ -1400,7 +1477,6 @@ var Datepicker;
_render: function () { _render: function () {
var title = this._getTitle(this.d.currentDate), var title = this._getTitle(this.d.currentDate),
html = Datepicker.template(template, $.extend({title: title}, this.opts)); html = Datepicker.template(template, $.extend({title: title}, this.opts));
this.d.$nav.html(html); this.d.$nav.html(html);
if (this.d.view == 'years') { if (this.d.view == 'years') {
$('.datepicker--nav-title', this.d.$nav).addClass('-disabled-'); $('.datepicker--nav-title', this.d.$nav).addClass('-disabled-');

File diff suppressed because one or more lines are too long

View File

@ -102,6 +102,21 @@
classes += render.classes ? ' ' + render.classes : ''; classes += render.classes ? ' ' + render.classes : '';
} }
if (this.opts.range) {
if (D.isSame(this.d.selectedDates[0], date)) classes += ' -range-from-';
if (D.isSame(this.d.selectedDates[1], date)) classes += ' -range-to-';
if (this.d.selectedDates.length == 1 && this.d.focused) {
if (Datepicker.bigger(this.d.selectedDates[0], date) && D.less(this.d.focused, date)) {
classes += ' -in-range-'
}
} else if (this.d.selectedDates.length == 2) {
if (D.bigger(this.d.selectedDates[0], date) && D.less(this.d.selectedDates[1], date)) {
classes += ' -in-range-'
}
}
}
if (D.isSame(currentDate, date, type)) classes += ' -current-'; if (D.isSame(currentDate, date, type)) classes += ' -current-';
if (this.d.focused && D.isSame(date, this.d.focused, type)) classes += ' -focus-'; if (this.d.focused && D.isSame(date, this.d.focused, type)) classes += ' -focus-';
if (this.d._isSelected(date, type)) classes += ' -selected-'; if (this.d._isSelected(date, type)) classes += ' -selected-';
@ -218,6 +233,7 @@
}, },
_render: function () { _render: function () {
console.log('render');
this._renderTypes[this.type].bind(this)(); this._renderTypes[this.type].bind(this)();
}, },

View File

@ -44,6 +44,7 @@ var Datepicker;
multipleDates: false, // Boolean or Number multipleDates: false, // Boolean or Number
multipleDatesSeparator: ',', multipleDatesSeparator: ',',
range: true,
todayButton: false, todayButton: false,
clearButton: false, clearButton: false,
@ -117,6 +118,8 @@ var Datepicker;
this.selectedDates = []; this.selectedDates = [];
this.views = {}; this.views = {};
this.keys = []; this.keys = [];
this.minRange = '';
this.maxRange = '';
this.init() this.init()
}; };
@ -150,6 +153,9 @@ var Datepicker;
this.nav = new Datepicker.Navigation(this, this.opts); this.nav = new Datepicker.Navigation(this, this.opts);
this.view = this.currentView; this.view = this.currentView;
this.$datepicker.on('mouseenter', '.datepicker--cell', this._onMouseEnterCell.bind(this));
this.$datepicker.on('mouseleave', '.datepicker--cell', this._onMouseLeaveCell.bind(this));
this.inited = true; this.inited = true;
}, },
@ -329,6 +335,8 @@ var Datepicker;
selectDate: function (date) { selectDate: function (date) {
var d = this.parsedDate, var d = this.parsedDate,
selectedDates = this.selectedDates,
len = selectedDates.length,
newDate = ''; newDate = '';
if (!(date instanceof Date)) return; if (!(date instanceof Date)) return;
@ -336,7 +344,6 @@ var Datepicker;
if (this.view == 'days') { if (this.view == 'days') {
if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) { if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) {
newDate = new Date(date.getFullYear(), date.getMonth(), 1); newDate = new Date(date.getFullYear(), date.getMonth(), 1);
} }
} }
@ -354,10 +361,22 @@ var Datepicker;
} }
if (this.opts.multipleDates) { if (this.opts.multipleDates) {
if (this.selectedDates.length === this.opts.multipleDates) return; if (len === this.opts.multipleDates) return;
if (!this._isSelected(date)) { if (!this._isSelected(date)) {
this.selectedDates.push(date); this.selectedDates.push(date);
} }
} else if (this.opts.range) {
if (len == 2) {
this.selectedDates = [date]
} else if (len == 1) {
if (Datepicker.less(this.selectedDates[0], date, this.cellType)) {
this.selectedDates = [date]
} else {
this.selectedDates.push(date);
}
} else {
this.selectedDates = [date]
}
} else { } else {
this. selectedDates = [date]; this. selectedDates = [date];
} }
@ -516,6 +535,15 @@ var Datepicker;
} }
}, },
_getDateFromCell: function (cell) {
var curDate = this.parsedDate,
year = cell.data('year') || curDate.year,
month = cell.data('month') == undefined ? curDate.month : cell.data('month'),
date = cell.data('date') || 1;
return new Date(year, month, date);
},
_setPositionClasses: function (pos) { _setPositionClasses: function (pos) {
pos = pos.split(' '); pos = pos.split(' ');
var main = pos[0], var main = pos[0],
@ -835,9 +863,9 @@ var Datepicker;
}, },
_onBlur: function () { _onBlur: function () {
if (!this.inFocus && this.visible) { //if (!this.inFocus && this.visible) {
this.hide(); // this.hide();
} //}
}, },
_onMouseDownDatepicker: function (e) { _onMouseDownDatepicker: function (e) {
@ -907,7 +935,31 @@ var Datepicker;
this._handleHotKey(hotKey); this._handleHotKey(hotKey);
}, },
_onMouseEnterCell: function (e) {
var $cell = $(e.target).closest('.datepicker--cell'),
date = this._getDateFromCell($cell);
// Prevent from unnecessary rendering and setting new currentDate
this.silent = true;
if (this.focused) {
this.focused = ''
}
$cell.addClass('-focus-');
this.focused = date;
this.silent = false;
},
_onMouseLeaveCell: function (e) {
var $cell = $(e.target).closest('.datepicker--cell'),
date = this._getDateFromCell($cell);
$cell.removeClass('-focus-');
this.silent = true;
this.focused = '';
this.silent = false;
},
set focused(val) { set focused(val) {
if (!val && this.focused) { if (!val && this.focused) {
@ -918,6 +970,7 @@ var Datepicker;
} }
} }
this._focused = val; this._focused = val;
if (this.silent) return;
this.date = val; this.date = val;
}, },
@ -941,7 +994,6 @@ var Datepicker;
this.setPosition(); this.setPosition();
} }
} }
return val; return val;
}, },
@ -1035,6 +1087,7 @@ var Datepicker;
}; };
Datepicker.isSame = function (date1, date2, type) { Datepicker.isSame = function (date1, date2, type) {
if (!date1 || !date2) return false;
var d1 = Datepicker.getParsedDate(date1), var d1 = Datepicker.getParsedDate(date1),
d2 = Datepicker.getParsedDate(date2), d2 = Datepicker.getParsedDate(date2),
_type = type ? type : 'day', _type = type ? type : 'day',
@ -1048,6 +1101,14 @@ var Datepicker;
return conditions[_type]; return conditions[_type];
}; };
Datepicker.less = function (dateCompareTo, date, type) {
return date.getTime() < dateCompareTo.getTime();
};
Datepicker.bigger = function (dateCompareTo, date, type) {
return date.getTime() > dateCompareTo.getTime();
};
Datepicker.language = { Datepicker.language = {
ru: { ru: {
days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'], days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],

View File

@ -44,7 +44,6 @@
_render: function () { _render: function () {
var title = this._getTitle(this.d.currentDate), var title = this._getTitle(this.d.currentDate),
html = Datepicker.template(template, $.extend({title: title}, this.opts)); html = Datepicker.template(template, $.extend({title: title}, this.opts));
this.d.$nav.html(html); this.d.$nav.html(html);
if (this.d.view == 'years') { if (this.d.view == 'years') {
$('.datepicker--nav-title', this.d.$nav).addClass('-disabled-'); $('.datepicker--nav-title', this.d.$nav).addClass('-disabled-');

View File

@ -23,6 +23,7 @@ $textColor: (
$bg: ( $bg: (
selected: #5cc4ef, selected: #5cc4ef,
selectedHover: darken(#5cc4ef, 5), selectedHover: darken(#5cc4ef, 5),
inRange: lighten(#5cc4ef, 15),
hover: #f0f0f0 hover: #f0f0f0
); );

View File

@ -19,7 +19,7 @@
height: $dayCellSize; height: $dayCellSize;
z-index: 1; z-index: 1;
&:hover, &.-focus- { /*&:hover, */&.-focus- {
background: map_get($bg, hover); background: map_get($bg, hover);
} }
@ -30,10 +30,18 @@
color: map_get($textColor, common); color: map_get($textColor, common);
} }
&:hover { //&:hover {
color: map_get($textColor, common); // color: map_get($textColor, common);
//background: rgba(map_get($textColor, currentDate), .05); // //background: rgba(map_get($textColor, currentDate), .05);
//}
} }
&.-in-range- {
background: map_get($bg, inRange);
color: #fff;
padding: 2px 0;
background-clip: content-box;
border-radius: 0;
} }
&.-disabled- { &.-disabled- {
@ -66,6 +74,13 @@
background: map_get($bg, selectedHover); background: map_get($bg, selectedHover);
} }
} }
&.-range-from- {
border-radius: $datepickerBorderRadius 0 0 $datepickerBorderRadius;
}
&.-range-to- {
border-radius: 0 $datepickerBorderRadius $datepickerBorderRadius 0;
}
} }
// Day names // Day names