@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,336 lines (1,109 loc) • 87.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('./kendo.core.js');
require('./kendo.selectable.js');
require('./kendo.icons.js');
require('./kendo.licensing.js');
require('@progress/kendo-licensing');
require('./kendo.userevents.js');
require('./kendo.html.icon.js');
require('./kendo.html.base.js');
require('@progress/kendo-svg-icons');
const __meta__ = {
id: "calendar",
name: "Calendar",
category: "web",
description: "The Calendar widget renders a graphical calendar that supports navigation and selection.",
depends: [ "core", "selectable" ]
};
(function($, undefined$1) {
let kendo = window.kendo,
support = kendo.support,
ui = kendo.ui,
Widget = ui.Widget,
keys = kendo.keys,
parse = kendo.parseDate,
encode = kendo.htmlEncode,
adjustDST = kendo.date.adjustDST,
weekInYear = kendo.date.weekInYear,
Selectable = kendo.ui.Selectable,
RangeSelectable = kendo.ui.RangeSelectable,
extractFormat = kendo._extractFormat,
template = kendo.template,
getCulture = kendo.getCulture,
transitionOrigin = "transform-origin",
cellTemplate = template((data) => `<td class="${data.cssClass}" role="gridcell"><span tabindex="-1" class="k-link" data-href="#" data-${data.ns}value="${data.dateString}">${data.value}</span></td>`),
emptyCellTemplate = template(() => '<td role="gridcell" class="k-calendar-td k-empty"></td>'),
otherMonthCellTemplate = template(() => '<td role="gridcell" class="k-calendar-td k-empty"> </td>'),
weekNumberTemplate = template((data) => `<td class="k-calendar-td k-alt">${data.weekNumber}</td>`),
outerWidth = kendo._outerWidth,
ns = ".kendoCalendar",
CLICK = "click" + ns,
KEYDOWN_NS = "keydown" + ns,
DOT = ".",
EMPTY = " ",
TABLE = "table",
CALENDAR_VIEW = "k-calendar-view",
ID = "id",
MIN = "min",
LEFT = "left",
SLIDE = "slideIn",
MONTH = "month",
CENTURY = "century",
CHANGE = "change",
NAVIGATE = "navigate",
VALUE = "value",
HOVER = "k-hover",
DISABLED = "k-disabled",
FOCUSED = "k-focus",
OTHERMONTH = "k-other-month",
EMPTYCELL = "k-empty",
TODAY = "k-calendar-nav-today",
CELLSELECTOR = "td:has(.k-link)",
START = "start",
END = "end",
CELLSELECTORVALID = "td:has(.k-link):not(." + DISABLED + "):not(." + EMPTYCELL + ")",
WEEKCOLUMNSELECTOR = "td:not(:has(.k-link))",
SELECTED = "k-selected",
BLUR = "blur" + ns,
FOCUS = "focus",
FOCUS_WITH_NS = FOCUS + ns,
MOUSEENTER = support.touch ? "touchstart" : "mouseenter",
MOUSEENTER_WITH_NS = support.touch ? "touchstart" + ns : "mouseenter" + ns,
MOUSELEAVE = support.touch ? "touchend" + ns + " touchmove" + ns : "mouseleave" + ns,
MS_PER_MINUTE = 60000,
MS_PER_DAY = 86400000,
PREVARROW = "_prevArrow",
NEXTARROW = "_nextArrow",
ARIA_DISABLED = "aria-disabled",
ARIA_SELECTED = "aria-selected",
ARIA_LABEL = "aria-label",
extend = $.extend,
DATE = Date,
views = {
month: 0,
year: 1,
decade: 2,
century: 3
},
HEADERSELECTOR = '.k-header, .k-calendar-header',
CLASSIC_HEADER_TEMPLATE = ({ actionAttr, size, isRtl }) => `<div class="k-header k-hstack">
<span tabindex="-1" data-href="#" ${actionAttr}="prev" role="button" class="k-calendar-nav-prev k-button ${size} k-rounded-md k-button-flat k-button-flat-base k-icon-button" ${ARIA_LABEL}="Previous">${kendo.ui.icon({ icon: `caret-alt-${isRtl ? "right" : "left"}`, iconClass: "k-button-icon" })}</span></span>
<span tabindex="-1" data-href="#" ${actionAttr}="nav-up" id="` + kendo.guid() + `" role="button" class="k-calendar-nav-fast k-button ${size} k-rounded-md k-button-flat k-button-flat-base k-flex"></span>
<span tabindex="-1" data-href="#" ${actionAttr}="next" role="button" class="k-calendar-nav-next k-button ${size} k-rounded-md k-button-flat k-button-flat-base k-icon-button" ${ARIA_LABEL}="Next">${kendo.ui.icon({ icon: `caret-alt-${isRtl ? "left" : "right"}`, iconClass: "k-button-icon" })}</span>
</div>`,
MODERN_HEADER_TEMPLATE = ({ actionAttr, size, messages, isRtl }) => `<div class="k-calendar-header">
<button ${actionAttr}="nav-up" id="` + kendo.guid() + `" class="k-calendar-title k-button ${size} k-button-flat k-button-flat-primary k-rounded-md">
<span class="k-button-text"></span>
</button>
<span class="k-spacer"></span>
<span class="k-calendar-nav">
<button tabindex="-1" ${actionAttr}=${isRtl ? "next" : "prev"} class="k-calendar-nav-prev k-button ${size} k-button-flat k-button-flat-base k-rounded-md k-icon-button">
${kendo.ui.icon({ icon: `chevron-${isRtl ? "right" : "left"}`, iconClass: "k-button-icon" })}
</button>
<button tabindex="-1" ${actionAttr}="today" class="k-calendar-nav-today k-button ${size} k-button-flat k-button-flat-primary k-rounded-md" role="link">
<span class="k-button-text">${kendo.htmlEncode(messages.today)}</span>
</button>
<button tabindex="-1" ${actionAttr}=${isRtl ? "prev" : "next"} class="k-calendar-nav-next k-button ${size} k-button-flat k-button-flat-base k-rounded-md k-icon-button">
${kendo.ui.icon({ icon: `chevron-${isRtl ? "left" : "right"}`, iconClass: "k-button-icon" })}
</button>
</span>
</div>`;
var Calendar = Widget.extend({
init: function(element, options) {
var that = this, value;
options = options || {};
options.componentType = options.componentType || "classic";
Widget.fn.init.call(that, element, options);
element = that.wrapper = that.element;
options = that.options;
options.url = kendo.unescape(options.url);
that.options.disableDates = getDisabledExpr(that.options.disableDates);
that._templates();
that._selectable();
that._header();
that._viewWrapper();
if (that.options.hasFooter) {
that._footer(that.footer);
} else {
that._today = that.element.find('.k-calendar-nav-today');
that._toggle();
}
element
.addClass("k-calendar k-calendar-md " + (options.weekNumber ? " k-week-number" : ""))
.on(MOUSEENTER_WITH_NS + " " + MOUSELEAVE, CELLSELECTOR, mousetoggle)
.on(KEYDOWN_NS, "table.k-calendar-table", that._move.bind(that))
.on(CLICK + " touchend", CELLSELECTORVALID, function(e) {
var link = e.currentTarget.firstChild,
value = toDateObject(link);
if ($(link).data("href").indexOf("#") != -1) {
e.preventDefault();
}
if (that._view.name == "month" && that.options.disableDates(value)) {
return;
}
if (that._view.name != "month" || that._isSingleSelection()) {
that._click($(link));
}
})
.on("mouseup" + ns, "table.k-calendar-table, .k-calendar-footer", function() {
that._focusView(that.options.focusOnNav !== false);
})
.attr(ID);
if (that.options.weekNumber) {
element.on(CLICK, WEEKCOLUMNSELECTOR, function(e) {
var first = $(e.currentTarget).closest("tr").find(CELLSELECTORVALID).first(),
last = $(e.currentTarget).closest("tr").find(CELLSELECTORVALID).last();
if (that._isMultipleSelection()) {
that.selectable._lastActive = last;
that.selectable.selectRange(first, last);
that.selectable.trigger(CHANGE, { event: e });
}
if (that._isRangeSelection()) {
that.rangeSelectable._lastActive = last;
that.rangeSelectable.range(first, last);
that.rangeSelectable.change();
}
that._current = that._value = toDateObject(last.find("span"));
that._setCurrent(that._current);
});
}
normalize(options);
value = parse(options.value, options.format, options.culture);
that._selectDates = [];
that._index = views[options.start];
that._current = new DATE(+restrictValue(value, options.min, options.max));
that._addClassProxy = function() {
that._active = true;
if (that._cell.hasClass(DISABLED)) {
var todayString = that._view.toDateString(getToday());
that._cell = that._cellByDate(todayString);
}
that._cell.addClass(FOCUSED);
};
that._removeClassProxy = function() {
that._active = false;
if (that._cell) {
that._cell.removeClass(FOCUSED);
}
};
that.value(value);
if (that._isMultipleSelection() && options.selectDates.length > 0) {
that.selectDates(options.selectDates);
}
that._range = options.range;
if (that._isRangeSelection()) {
that.selectRange(that._range);
}
kendo.notify(that);
},
options: {
name: "Calendar",
value: null,
min: new DATE(1900, 0, 1),
max: new DATE(2099, 11, 31),
dates: [],
disableDates: null,
allowReverse: false,
centuryCellsFormat: "long",
url: "",
culture: "",
footer: "",
format: "",
month: {},
weekNumber: false,
range: { start: null, end: null, target: START },
selectable: "single",
selectDates: [],
start: MONTH,
depth: MONTH,
size: "medium",
showOtherMonthDays: true,
animation: {
horizontal: {
effects: SLIDE,
reverse: true,
duration: 500,
divisor: 2
},
vertical: {
effects: "zoomIn",
duration: 400
}
},
messages: {
weekColumnHeader: "",
today: "Today",
navigateTo: "Navigate to ",
parentViews: {
month: "year view",
year: "decade view",
decade: "century view"
}
},
componentType: "classic"
},
events: [
CHANGE,
NAVIGATE
],
componentTypes: {
"classic": {
header: {
template: CLASSIC_HEADER_TEMPLATE
},
hasFooter: true,
linksSelector: ".k-button",
contentClasses: "k-calendar-table"
},
"modern": {
header: {
template: MODERN_HEADER_TEMPLATE
},
hasFooter: false,
linksSelector: ".k-button",
contentClasses: "k-calendar-table"
}
},
setOptions: function(options) {
let that = this,
isComponentTypeChanged;
isComponentTypeChanged = options.componentType ? true : false;
normalize(options);
options.disableDates = getDisabledExpr(options.disableDates);
that._destroySelectable();
if (options.messages) {
options.messages = $.extend({}, true, that.options.messages, options.messages);
}
Widget.fn.setOptions.call(that, options);
that._templates();
that._selectable();
if (isComponentTypeChanged) {
let componentTypes = Calendar.prototype.componentTypes;
that.options.header = componentTypes[options.componentType].header;
that.options.hasFooter = componentTypes[options.componentType].hasFooter;
let header = that.element.find(HEADERSELECTOR)[0];
if (header) {
header.remove();
}
that._header();
}
that._viewWrapper();
if (that.options.hasFooter) {
that._footer(that.footer);
} else {
that.element.find(".k-calendar-footer").hide();
that._toggle();
}
that._index = views[that.options.start];
that.navigate();
if (isComponentTypeChanged) {
let value = parse(that.options.value, options.format, options.culture);
that._current = new DATE(+restrictValue(value, options.min, options.max));
that._cell = null;
that._table = null;
that.value(value);
}
if (options.weekNumber) {
that.element.addClass('k-week-number');
}
},
destroy: function() {
var that = this,
today = that._today;
that.element.off(ns);
that._title.off(ns);
that[PREVARROW].off(ns);
that[NEXTARROW].off(ns);
that._destroySelectable();
kendo.destroy(that._table);
if (today) {
kendo.destroy(today.off(ns));
}
Widget.fn.destroy.call(that);
},
current: function() {
return this._current;
},
view: function() {
return this._view;
},
focus: function(table) {
table = table || this._table;
this._bindTable(table);
table.trigger("focus");
},
min: function(value) {
return this._option(MIN, value);
},
max: function(value) {
return this._option("max", value);
},
navigateToPast: function() {
this._navigate(PREVARROW, -1);
},
navigateToFuture: function() {
this._navigate(NEXTARROW, 1);
},
navigateUp: function() {
var that = this,
index = that._index;
if (that._title.hasClass(DISABLED)) {
return;
}
that.navigate(that._current, ++index);
},
navigateDown: function(value) {
var that = this,
index = that._index,
depth = that.options.depth;
if (!value) {
return;
}
if (index === views[depth]) {
if (!isEqualDate(that._value, that._current) || !isEqualDate(that._value, value)) {
that.value(value);
that.trigger(CHANGE);
}
return;
}
that.navigate(value, --index);
},
navigate: function(value, view) {
view = isNaN(view) ? views[view] : view;
var that = this,
options = that.options,
culture = options.culture,
min = options.min,
max = options.max,
title = that._title,
from = that._table,
old = that._oldTable,
currentValue = that._current,
future = value && +value > +currentValue,
vertical = view !== undefined$1 && view !== that._index,
to, currentView, compare,
disabled,
viewWrapper = that.element.children(".k-calendar-view");
if (!value) {
value = currentValue;
}
that._current = value = new DATE(+restrictValue(value, min, max));
if (view === undefined$1) {
view = that._index;
} else {
that._index = view;
}
that._view = currentView = calendar.views[view];
compare = currentView.compare;
disabled = view === views[CENTURY];
title.toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled);
disabled = compare(value, min) < 1;
that[PREVARROW].toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled);
disabled = compare(value, max) > -1;
that[NEXTARROW].toggleClass(DISABLED, disabled).attr(ARIA_DISABLED, disabled);
if (from && old && old.data("animating")) {
old.kendoStop(true, true);
from.kendoStop(true, true);
}
that._oldTable = from;
if (!from || that._changeView) {
title.html('<span class="k-button-text">' + currentView.title(value, min, max, culture) + '</span>');
if (that.options.messages.parentViews && that._view.name !== CENTURY) {
title.attr("title", encode(that.options.messages.navigateTo + that.options.messages.parentViews[that._view.name]));
} else {
title.removeAttr("title");
}
that._table = to = $(currentView.content(extend({
min: min,
max: max,
date: value,
url: options.url,
dates: options.dates,
format: options.format,
showOtherMonthDays: options.showOtherMonthDays,
centuryCellsFormat: options.centuryCellsFormat,
culture: culture,
disableDates: options.disableDates,
isWeekColumnVisible: options.weekNumber,
messages: options.messages,
contentClasses: that.options.contentClasses
}, that[currentView.name])));
that._aria();
var replace = from && from.data("start") === to.data("start");
that._animate({
from: from,
to: to,
vertical: vertical,
future: future,
replace: replace
});
viewWrapper.removeClass("k-calendar-monthview k-calendar-yearview k-calendar-decadeview k-calendar-centuryview");
viewWrapper.addClass("k-calendar-" + currentView.name + "view");
that.trigger(NAVIGATE);
that._focus(value);
}
if (view === views[options.depth] && that._selectDates.length > 0) {
that._visualizeSelectedDatesInView();
}
if (that._isSingleSelection()) {
if (view === views[options.depth] && that._value && !that.options.disableDates(that._value)) {
that._selectCell(that._value);
}
}
that._setCurrent(value);
if (!from && that._cell) {
that._cell.removeClass(FOCUSED);
}
that._changeView = true;
},
selectDates: function(dates) {
var that = this,
validSelectedDates,
datesUnique;
if (dates === undefined$1) {
return that._selectDates;
}
datesUnique = dates
.map(function(date) { return date.getTime(); })
.filter(function(date, position, array) {
return array.indexOf(date) === position;
})
.map(function(time) { return new Date(time); });
validSelectedDates = $.grep(datesUnique, function(value) {
if (value) {
return +that._validateValue(new Date(value.setHours(0, 0, 0, 0))) === +value;
}
});
that._selectDates = validSelectedDates.length > 0 ? validSelectedDates : (datesUnique.length === 0 ? datesUnique : that._selectDates);
that._visualizeSelectedDatesInView();
},
value: function(value) {
var that = this,
old = that._view,
view = that._view;
if (value === undefined$1) {
return that._value;
}
value = that._validateValue(value);
if (value && that._isMultipleSelection()) {
var date = new Date(+value);
date.setHours(0, 0, 0, 0);
that._selectDates = [date];
that.selectable._lastActive = null;
}
if (old && value === null && that._cell) {
that._cell.removeClass(SELECTED);
} else {
that._changeView = !value || view && view.compare(value, that._current) !== 0;
that.navigate(value);
}
},
isRtl: function() {
return kendo.support.isRtl(this.wrapper);
},
_aria: function() {
var table = this._table;
table.attr("aria-labelledby", this._title.attr("id"));
if (this._view.name === "month" && this._isMultipleSelection()) {
table.attr("aria-multiselectable", "true");
}
},
_validateValue: function(value) {
var that = this,
options = that.options,
min = options.min,
max = options.max;
if (value === null) {
that._current = createDate(that._current.getFullYear(), that._current.getMonth(), that._current.getDate());
}
value = parse(value, options.format, options.culture);
if (value !== null) {
value = new DATE(+value);
if (!isInRange(value, min, max)) {
value = null;
}
}
if (value === null || !that.options.disableDates(new Date(+value))) {
that._value = value;
} else if (that._value === undefined$1) {
that._value = null;
}
return that._value;
},
_visualizeSelectedDatesInView: function() {
var that = this;
var selectedDates = {};
$.each(that._selectDates, function(index, value) {
selectedDates[kendo.calendar.views[0].toDateString(value)] = value;
});
that.selectable.clear();
var cells = that._table
.find(CELLSELECTOR)
.filter(function(index, element) {
return selectedDates[$(element.firstChild).attr(kendo.attr(VALUE))];
});
if (cells.length > 0) {
that.selectable._selectElement(cells, true);
}
},
_isSingleSelection: function() {
let selectable = this.options.selectable,
selectableOptions = Selectable.parseOptions(selectable);
return selectableOptions.single;
},
_isMultipleSelection: function() {
let selectable = this.options.selectable,
selectableOptions = Selectable.parseOptions(selectable);
return selectableOptions.multiple;
},
_isRangeSelection: function() {
let selectable = this.options.selectable,
selectableOptions = Selectable.parseOptions(selectable);
return selectableOptions.range;
},
_selectable: function() {
let that = this,
selectable = that.options.selectable,
selectableOptions = Selectable.parseOptions(selectable);
if (!that._isMultipleSelection() && !that._isRangeSelection()) {
return;
}
if (that.rangeSelectable) {
that.rangeSelectable.destroy();
that.rangeSelectable = null;
}
if (selectableOptions.range) {
that.rangeSelectable = new RangeSelectable(that.wrapper, {
widget: that,
filter: ".k-calendar-monthview table " + CELLSELECTORVALID,
cellSelector: CELLSELECTOR,
cellSelectorValid: CELLSELECTORVALID,
change: that._onSelect.bind(that),
reverse: that.options.allowReverse,
resetOnStart: true,
ns: ns
});
that.element.addClass("k-calendar-range");
} else {
that.selectable = new Selectable(that.wrapper, {
aria: true,
//excludes the anchor element
inputSelectors: "input,textarea,.k-multiselect-wrap,select,button,.k-button>span,.k-button>img,span.k-icon.k-i-caret-alt-down,span.k-icon.k-i-caret-alt-up,span.k-svg-icon.k-svg-i-caret-alt-down,span.k-svg-icon.k-svg-i-caret-alt-up",
multiple: selectableOptions.multiple,
filter: "table.k-calendar-table:eq(0) " + CELLSELECTORVALID,
change: that._onSelect.bind(that),
relatedTarget: that._onRelatedTarget.bind(that)
});
}
},
_restoreSelection: function() {
const that = this;
let range;
that._preventChange = true;
if (that._isRangeSelection()) {
range = that.selectRange();
if (!range || !range.start) {
that._preventChange = false;
return;
}
that.selectRange(range);
}
that._preventChange = false;
},
selectRange: function(range) {
const that = this, view = that._view;
let startInRange, endInRange, visibleRange;
if (range === undefined$1) {
return that._range;
}
that._range = range;
if (!range.start) {
return;
}
visibleRange = that._visibleRange();
startInRange = that._dateInViews(range.start);
endInRange = range.end && that._dateInViews(range.end);
if (!startInRange && endInRange) {
that.rangeSelectable.selectTo(that._cellByDate(view.toDateString(range.end)));
}
if (startInRange && endInRange) {
that.rangeSelectable.range(that._cellByDate(view.toDateString(range.start)), that._cellByDate(view.toDateString(range.end)), false, that.options.allowReverse);
}
if (range.end && startInRange && !endInRange) {
that.rangeSelectable.selectFrom(that._cellByDate(view.toDateString(range.start)));
}
if (!range.end && startInRange) {
that.rangeSelectable.start(that._cellByDate(view.toDateString(range.start)));
}
if (+visibleRange.start > +range.start && +visibleRange.end < +range.end) {
that.rangeSelectable.mid(that.element.find(CELLSELECTORVALID));
}
},
_onRelatedTarget: function(target) {
var that = this;
if (that.selectable.options.multiple && target.is(CELLSELECTORVALID)) {
that._current = toDateObject(target.find("span"));
that._setCurrent(that._current);
}
},
_onSelect: function(e) {
let that = this,
eventArgs = e,
range,
useEnd = e.sender._useEnd,
useStart = e.sender._useStart,
initialRange,
start,
end,
value,
target,
selectableOptions = Selectable.parseOptions(that.options.selectable);
if (that._isRangeSelection()) {
range = e.sender.range();
initialRange = that.selectRange() || {};
target = initialRange.target;
if (range.start && range.start.length) {
start = toDateObject(range.start.find("span"));
}
if (range.end && range.end.length) {
end = toDateObject(range.end.find("span"));
}
if (target === END) {
target = START;
} else {
target = END;
}
that._range = { start: useStart ? initialRange.start : start, end: useEnd ? initialRange.end : end, target: target };
if (!that._preventChange) {
that.trigger(CHANGE);
}
value = end || start;
if (end && !that._dateInViews(end)) {
value = start;
}
that.selectRange(that._range);
that.value(value);
return;
}
if (!selectableOptions.multiple) {
if ($(eventArgs.event.currentTarget).is("td") && !$(eventArgs.event.currentTarget).hasClass("k-selected")) {
$(eventArgs.event.currentTarget).addClass("k-selected");
}
else {
that._click($(eventArgs.event.currentTarget).find("span"));
}
return;
}
if (eventArgs.event.ctrlKey || eventArgs.event.metaKey) {
if ($(eventArgs.event.currentTarget).is(CELLSELECTORVALID)) {
that._toggleSelection($(eventArgs.event.currentTarget));
}
else {
that._cellsBySelector(CELLSELECTORVALID).each(function(index, element) {
var value = toDateObject($(element).find("span"));
that._deselect(value);
});
that._addSelectedCellsToArray();
}
}
else if (eventArgs.event.shiftKey) {
that._rangeSelection(that._cell);
}
else if ($(eventArgs.event.currentTarget).is(CELLSELECTOR)) {
that.value(toDateObject($(eventArgs.event.currentTarget).find("span")));
}
else {
that._selectDates = [];
that._addSelectedCellsToArray();
}
that.trigger(CHANGE);
},
_destroySelectable: function() {
var that = this;
if (that.selectable) {
that.selectable.destroy();
that.selectable = null;
}
if (that.rangeSelectable) {
that.rangeSelectable.destroy();
that.rangeSelectable = null;
}
},
//when ctrl key is clicked
_toggleSelection: function(currentCell) {
var that = this,
date = toDateObject(currentCell.find("span"));
if (currentCell.hasClass("k-selected")) {
that._selectDates.push(date);
}
else {
that._deselect(date);
}
},
//shift selection
_rangeSelection: function(toDateCell, startDate) {
var that = this,
fromDate = startDate || toDateObject(that.selectable.value().first().find("span")),
toDate = toDateObject(toDateCell.find("span")),
daysDifference;
if (that.selectable._lastActive || that._value) {
fromDate = that.selectable._lastActive ? toDateObject(that.selectable._lastActive.find("span")) : new Date(+that._value);
} else {
that.selectable._lastActive = startDate ? that._cellByDate(that._view.toDateString(startDate), CELLSELECTORVALID) : that.selectable.value().first();
}
that._selectDates = [];
daysDifference = daysBetweenTwoDates(fromDate, toDate);
addDaysToArray(that._selectDates, daysDifference, fromDate, that.options.disableDates);
that._visualizeSelectedDatesInView();
},
_visibleRange: function() {
let table = this.element.find(DOT + CALENDAR_VIEW + EMPTY + TABLE),
firstDateInView = toDateObject(table.first().find(CELLSELECTOR).first().find("span")),
lastDateInView = toDateObject(table.last().find(CELLSELECTOR).last().find("span"));
return { start: firstDateInView, end: lastDateInView };
},
_cellsBySelector: function(selector) {
var that = this;
return that._table.find(selector);
},
_addSelectedCellsToArray: function() {
var that = this;
that.selectable.value().each(function(index, item) {
var date = toDateObject($(item.firstChild));
if (!that.options.disableDates(date)) {
that._selectDates.push(date);
}
});
},
_deselect: function(date) {
var that = this;
var currentDateIndex = that._selectDates.map(Number).indexOf(+date);
if (currentDateIndex != -1) {
that._selectDates.splice(currentDateIndex, 1);
}
},
_dateInView: function(date) {
var that = this,
firstDateInView = toDateObject(that._cellsBySelector(CELLSELECTORVALID).first().find("span")),
lastDateInView = toDateObject(that._cellsBySelector(CELLSELECTORVALID).last().find("span"));
return +date <= +lastDateInView && +date >= +firstDateInView;
},
_isNavigatable: function(currentValue, cellIndex) {
var that = this;
var isDisabled = that.options.disableDates;
var cell;
var index;
if (that._view.name == "month") {
return !isDisabled(currentValue);
} else {
index = that.wrapper.find("." + FOCUSED).index();
cell = that.wrapper.find(".k-calendar-table td").eq(index + cellIndex);
return cell.is(CELLSELECTORVALID) || !isDisabled(currentValue);
}
},
_dateInViews: function(date) {
let that = this,
tables = that.element.find(".k-calendar-view table"),
firstDateInView = toDateObject(tables.first().find(CELLSELECTOR).first().find("span")),
lastDateInView = toDateObject(tables.last().find(CELLSELECTOR).last().find("span"));
date = new Date(date.toDateString());
return +date <= +lastDateInView && +date >= +firstDateInView;
},
_move: function(e) {
var that = this,
options = that.options,
key = e.keyCode,
view = that._view,
index = that._index,
min = that.options.min,
max = that.options.max,
currentValue = new DATE(+that._current),
isRtl = that.isRtl(),
isDisabled = that.options.disableDates,
value, prevent, method, temp, cell, focusedCell, lastActive;
if (e.target === that._table[0]) {
that._active = true;
}
if (key == keys.RIGHT && !isRtl || key == keys.LEFT && isRtl) {
value = 1;
prevent = true;
} else if (key == keys.LEFT && !isRtl || key == keys.RIGHT && isRtl) {
value = -1;
prevent = true;
} else if (key == keys.UP) {
value = index === 0 ? -7 : -4;
prevent = true;
} else if (key == keys.DOWN) {
value = index === 0 ? 7 : 4;
prevent = true;
} else if (key == keys.SPACEBAR) {
value = 0;
prevent = true;
} else if (key == keys.HOME || key == keys.END) {
method = key == keys.HOME ? "first" : "last";
temp = view[method](currentValue);
currentValue = new DATE(temp.getFullYear(), temp.getMonth(), temp.getDate(), currentValue.getHours(), currentValue.getMinutes(), currentValue.getSeconds(), currentValue.getMilliseconds());
currentValue.setFullYear(temp.getFullYear());
prevent = true;
} else if (key === 84) {
that._todayClick(e);
prevent = true;
}
if (e.ctrlKey || e.metaKey) {
if (key == keys.RIGHT && !isRtl || key == keys.LEFT && isRtl) {
that.navigateToFuture();
prevent = true;
} else if (key == keys.LEFT && !isRtl || key == keys.RIGHT && isRtl) {
that.navigateToPast();
prevent = true;
} else if (key == keys.UP) {
that.navigateUp();
prevent = true;
} else if (key == keys.DOWN) {
that._click($(that._cell[0].firstChild));
prevent = true;
}
else if ((key == keys.ENTER || key == keys.SPACEBAR) && that._isMultipleSelection()) {
that._keyboardToggleSelection(e);
var focusedDate = toDateObject($(that._cell[0]).find("span"));
that._setCurrent(focusedDate);
}
} else if (e.shiftKey) {
if (value !== undefined$1 || method) {
if (!method) {
view.setDate(currentValue, value);
}
if (!isInRange(currentValue, min, max)) {
currentValue = restrictValue(currentValue, options.min, options.max);
}
if (isDisabled(currentValue)) {
currentValue = that._nextNavigatable(currentValue, value);
}
min = createDate(min.getFullYear(), min.getMonth(), min.getDate());
if (that._isMultipleSelection()) {
that._keyboardRangeSelection(e, currentValue);
} else if (that._isRangeSelection()) {
if (!that._dateInViews(currentValue)) {
if (value > 0) {
that.navigateToFuture();
} else {
that.navigateToPast();
}
}
} else {
that._focus(currentValue);
}
}
if (that.rangeSelectable) {
cell = that._cellByDate(view.toDateString(currentValue));
lastActive = toDateObject((that.rangeSelectable._lastActive || focusedCell).find("span"));
if (!that._dateInViews(lastActive)) {
if (+lastActive > +currentValue) {
that.rangeSelectable._end = that.rangeSelectable._lastActive;
that.rangeSelectable.selectFrom(cell);
} else {
that.rangeSelectable.selectTo(cell);
}
} else {
if (that.rangeSelectable._end && that.rangeSelectable._end.is("." + FOCUSED)) {
that.rangeSelectable._lastActive = that.rangeSelectable._start;
} else {
that.rangeSelectable._lastActive = that._cellByDate(view.toDateString(lastActive));
}
that.rangeSelectable.range(that.rangeSelectable._lastActive, cell);
}
that.rangeSelectable.change();
that._setCurrent(currentValue);
}
} else {
if (key == keys.ENTER || key == keys.SPACEBAR) {
if (view.name == "month" && that._isMultipleSelection()) {
that.value(toDateObject($(that._cell.find("span"))));
that.selectable._lastActive = $(that._cell[0]);
that.trigger(CHANGE);
} else if (that.rangeSelectable) {
that.rangeSelectable.change();
} else {
that._click($(that._cell[0].firstChild));
}
prevent = true;
} else if (key == keys.PAGEUP) {
prevent = true;
that.navigateToPast();
} else if (key == keys.PAGEDOWN) {
prevent = true;
that.navigateToFuture();
}
if (value || method) {
if (!method) {
view.setDate(currentValue, value);
}
min = createDate(min.getFullYear(), min.getMonth(), min.getDate());
if (!isInRange(currentValue, min, max)) {
currentValue = restrictValue(currentValue, options.min, options.max);
}
if (!that._isNavigatable(currentValue, value)) {
currentValue = that._nextNavigatable(currentValue, value);
}
if (that._isMultipleSelection()) {
if (!that._dateInView(currentValue)) {
that.navigate(currentValue);
}
else {
that._current = currentValue;
that._setCurrent(currentValue);
}
}
else {
that._focus(currentValue);
}
}
}
if (prevent) {
e.preventDefault();
}
return that._current;
},
_keyboardRangeSelection: function(event, currentValue) {
var that = this,
fromDate,
daysDifference;
if (!that._dateInView(currentValue)) {
that._selectDates = [];
fromDate = that.selectable._lastActive ? toDateObject(that.selectable._lastActive.find("span")) : currentValue;
daysDifference = daysBetweenTwoDates(fromDate, new Date(+currentValue));
addDaysToArray(that._selectDates, daysDifference, fromDate, that.options.disableDates);
that.navigate(currentValue);
that._current = currentValue;
that.selectable._lastActive = that.selectable._lastActive || that._cellByDate(that._view.toDateString(currentValue), CELLSELECTORVALID);
that.trigger(CHANGE);
return;
}
that.selectable.options.filter = that.wrapper.find("table").length > 1 && +currentValue > +that._current ? "table.k-calendar-table:eq(1) " + CELLSELECTORVALID : "table.k-calendar-table:eq(0) " + CELLSELECTORVALID;
that._setCurrent(currentValue);
that._current = currentValue;
that._rangeSelection(that._cellByDate(that._view.toDateString(currentValue), CELLSELECTORVALID), currentValue);
that.trigger(CHANGE);
that.selectable.options.filter = "table.k-calendar-table:eq(0) " + CELLSELECTORVALID;
},
_keyboardToggleSelection: function(event) {
var that = this;
event.currentTarget = that._cell[0];
that.selectable._lastActive = $(that._cell[0]);
if ($(that._cell[0]).hasClass(SELECTED)) {
that.selectable._unselect($(that._cell[0]));
}
else {
that.selectable.value($(that._cell[0]));
}
that.selectable.trigger(CHANGE, { event: event });
},
_nextNavigatable: function(currentValue, value) {
var that = this,
disabled = true,
view = that._view,
min = that.options.min,
max = that.options.max,
isDisabled = that.options.disableDates,
navigatableDate = new Date(currentValue.getTime());
view.setDate(navigatableDate, -value);
while (disabled) {
view.setDate(currentValue, value);
if (!isInRange(currentValue, min, max)) {
currentValue = navigatableDate;
break;
}
disabled = isDisabled(currentValue);
}
return currentValue;
},
_animate: function(options) {
var that = this;
var from = options.from;
var to = options.to;
var active = that._active;
var viewWrapper = that.element.children(".k-calendar-view");
if (!from) {
viewWrapper.append(to);
that._bindTable(to);
} else if (from.parent().data("animating")) {
from.off(ns);
from.parent().kendoStop(true, true).remove();
from.remove();
viewWrapper.append(to);
that._focusView(active);
} else if (!from.is(":visible") || that.options.animation === false || options.replace) {
to.insertAfter(from);
from.off(ns).remove();
that._focusView(active);
} else {
that[options.vertical ? "_vertical" : "_horizontal"](from, to, options.future);
}
},
_horizontal: function(from, to, future) {
var that = this,
active = that._active,
horizontal = that.options.animation.horizontal,
effects = horizontal.effects,
viewWidth = outerWidth(from),
margin = (outerWidth(from, true) - viewWidth);
if (effects && effects.indexOf(SLIDE) != -1) {
from.add(to).css({ width: viewWidth });
from.wrap("<div/>");
that._focusView(active, from);
from.parent()
.css({
position: "relative",
width: (viewWidth * 2) + (2 * margin),
display: "flex",
[future ? "margin-right" : "margin-left"]: (-viewWidth - margin)
});
to[future ? "insertAfter" : "insertBefore"](from);
extend(horizontal, {
effects: SLIDE + ":" + (future ? "right" : LEFT),
complete: function() {
from.off(ns).remove();
that._oldTable = null;
to.unwrap();
that._focusView(active);
}
});
from.parent().kendoStop(true, true).kendoAnimate(horizontal);
}
},
_vertical: function(from, to) {
var that = this,
vertical = that.options.animation.vertical,
effects = vertical.effects,
active = that._active, //active state before from's blur
cell, position;
if (effects && effects.indexOf("zoom") != -1) {
to.insertBefore(from);
from.css({
position: "absolute",
width: to.width()
});
{
cell = that._cellByDate(that._view.toDateString(that._current));
position = cell.position();
position = (position.left + parseInt(cell.width() / 2, 10)) + "px" + " " + (position.top + parseInt(cell.height() / 2, 10) + "px");
to.css(transitionOrigin, position);
}
from.kendoStop(true, true).kendoAnimate({
effects: "fadeOut",
duration: 600,
complete: function() {
from.off(ns).remove();
that._oldTable = null;
that._focusView(active);
}
});
to.kendoStop(true, true).kendoAnimate(vertical);
}
},
_cellByDate: function(value, selector) {
return this._table.find(selector ? selector : "td:not(." + OTHERMONTH + ")")
.filter(function() {
return $(this.firstChild).attr(kendo.attr(VALUE)) === value;
})