UNPKG

@daypilot/modal

Version:

Build a modal dialog dynamically from code.

841 lines (694 loc) 25 kB
/* Copyright (c) 2010 - 2020 Annpoint, s.r.o. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ------------------------------------------------------------------------- NOTE: Requires the following acknowledgement (see also NOTICE): This product includes DayPilot Modal (https://modal.daypilot.org). */ import {Date, DateUtil} from "./date"; import {Locale} from "./locale"; var local = { Date: Date, DateUtil, Locale }; (function(DayPilot) { DayPilot.Navigator = function(id) { this.v = '${v}'; var calendar = this; this.id = id; this.api = 2; this.isNavigator = true; this.angularAutoApply = true; this.weekStarts = 'Auto'; // 0 = Sunday, 1 = Monday, ... 'Auto' = according to locale this.selectMode = 'day'; // day/week/month/none this.titleHeight = 30; this.dayHeaderHeight = 30; this.cellWidth = 30; this.cellHeight = 30; this._cssOnly = true; this.selectionStart = null; // today this.selectionEnd = null; this.selectionDay = new DayPilot.Date().getDatePart(); this.showMonths = 1; this.skipMonths = 1; this.command = "navigate"; this.year = new DayPilot.Date().getYear(); this.month = new DayPilot.Date().getMonth() + 1; this.locale = "en-us"; this.theme = "navigator_default"; this.timeRangeSelectedHandling = "Bind"; this.onTimeRangeSelect = null; this.onTimeRangeSelected = null; this.nav = {}; this._prepare = function() { this.root.dp = this; if (this._cssOnly) { this.root.className = this._prefixCssClass('_main'); } else { this.root.className = this._prefixCssClass('main'); } this.root.style.width = (this.cellWidth * 7) + 'px'; this.root.style.position = "relative"; var vsph = document.createElement("input"); vsph.type = 'hidden'; vsph.name = calendar.id + "_state"; vsph.id = vsph.name; this.root.appendChild(vsph); this.state = vsph; if (!this.startDate) { this.startDate = new DayPilot.Date(DayPilot.Date.fromYearMonthDay(this.year, this.month)); } else { // make sure it's the first day this.startDate = new DayPilot.Date(this.startDate).firstDayOfMonth(); } this.calendars = []; this.selected = []; this.months = []; }; this._api2 = function() { return calendar.api === 2; }; this._clearTable = function() { this.root.innerHTML = ''; }; this._prefixCssClass = function(part) { var prefix = this.theme || this.cssClassPrefix; if (prefix) { return prefix + part; } else { return ""; } }; this._addClass = function(object, name) { var fullName = this._cssOnly ? this._prefixCssClass("_" + name) : this._prefixCssClass(name); addClass(object, fullName); }; this._removeClass = function(object, name) { var fullName = this._cssOnly ? this._prefixCssClass("_" + name) : this._prefixCssClass(name); removeClass(object, fullName); }; this._drawTable = function(j, showLinks) { var month = {}; month.cells = []; month.days = []; month.weeks = []; var startDate = this.startDate.addMonths(j); var showBefore = showLinks.before; var showAfter = showLinks.after; var firstOfMonth = startDate.firstDayOfMonth(); var first = firstOfMonth.firstDayOfWeek(resolved.weekStarts()); var last = firstOfMonth.addMonths(1); var days = DayPilot.DateUtil.daysDiff(first, last); var rowCount = 6; month._rowCount = rowCount; var today = (new DayPilot.Date()).getDatePart(); var width = this.cellWidth * 7; var height = this.cellHeight * rowCount + this.titleHeight + this.dayHeaderHeight; month.height = height; var main = document.createElement("div"); main.style.width = (width) + 'px'; main.style.height = (height) + 'px'; main.style.position = 'relative'; if (this._cssOnly) { main.className = this._prefixCssClass('_month'); } else { main.className = this._prefixCssClass('month'); } main.style.cursor = 'default'; main.style.MozUserSelect = 'none'; main.style.KhtmlUserSelect = 'none'; main.style.WebkitUserSelect = 'none'; main.month = month; this.root.appendChild(main); var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; // title left var tl = document.createElement("div"); tl.style.position = 'absolute'; tl.style.left = '0px'; tl.style.top = '0px'; tl.style.width = this.cellWidth + 'px'; tl.style.height = this.titleHeight + 'px'; tl.style.lineHeight = this.titleHeight + 'px'; //tl.style.textAlign = 'left'; tl.setAttribute("unselectable", "on"); if (this._cssOnly) { tl.className = this._prefixCssClass('_titleleft'); } else { tl.className = this._prefixCssClass('titleleft'); } if (showLinks.left) { tl.style.cursor = 'pointer'; tl.innerHTML = "<span>&lt;</span>"; tl.onclick = this._clickLeft; } main.appendChild(tl); this.tl = tl; // title center var ti = document.createElement("div"); ti.style.position = 'absolute'; ti.style.left = this.cellWidth + 'px'; ti.style.top = '0px'; ti.style.width = (this.cellWidth * 5) + 'px'; ti.style.height = this.titleHeight + 'px'; ti.style.lineHeight = this.titleHeight + 'px'; ti.style.textAlign = 'center'; ti.setAttribute("unselectable", "on"); if (this._cssOnly) { ti.className = this._prefixCssClass('_title'); } else { ti.className = this._prefixCssClass('title'); } ti.innerHTML = resolved.locale().monthNames[startDate.getMonth()] + ' ' + startDate.getYear(); main.appendChild(ti); this.ti = ti; // title right var tr = document.createElement("div"); tr.style.position = 'absolute'; tr.style.left = (this.cellWidth * 6) + 'px'; tr.style.top = '0px'; tr.style.width = this.cellWidth + 'px'; tr.style.height = this.titleHeight + 'px'; tr.style.lineHeight = this.titleHeight + 'px'; //tr.style.textAlign = 'right'; tr.setAttribute("unselectable", "on"); if (this._cssOnly) { tr.className = this._prefixCssClass('_titleright'); } else { tr.className = this._prefixCssClass('titleright'); } if (showLinks.right) { tr.style.cursor = 'pointer'; tr.innerHTML = "<span>&gt;</span>"; tr.onclick = this._clickRight; } main.appendChild(tr); this.tr = tr; for (var x = 0; x < 7; x++) { month.cells[x] = []; // day header var dh = document.createElement("div"); dh.style.position = 'absolute'; dh.style.left = (x * this.cellWidth) + 'px'; dh.style.top = this.titleHeight + 'px'; dh.style.width = this.cellWidth + 'px'; dh.style.height = this.dayHeaderHeight + 'px'; dh.style.lineHeight = this.dayHeaderHeight + 'px'; //dh.style.textAlign = 'right'; dh.setAttribute("unselectable", "on"); if (this._cssOnly) { dh.className = this._prefixCssClass('_dayheader'); } else { dh.className = this._prefixCssClass('dayheader'); } //dh.innerHTML = "<span style='margin-right: 2px'>" + this._getDayName(x) + "</span>"; dh.innerHTML = "<span>" + this._getDayName(x) + "</span>"; main.appendChild(dh); month.days.push(dh); for (var y = 0; y < rowCount; y++) { var day = first.addDays(y * 7 + x); var isSelected = this._isSelected(day) && this._selectModeLowerCase() !== 'none'; var isCurrentMonth = day.getMonth() === startDate.getMonth(); var isPrevMonth = day.getTime() < startDate.getTime(); //var isNextMonth = day.getYear() > startDate.getYear() || (day.getYear() == startDate.getYear() && day.getMonth() > startDate.getMonth()); var isNextMonth = day.getTime() > startDate.getTime(); var dayClass; var dc = document.createElement("div"); month.cells[x][y] = dc; dc.day = day; dc.x = x; dc.y = y; dc.isCurrentMonth = isCurrentMonth; if (this._cssOnly) { dc.className = this._prefixCssClass((isCurrentMonth ? '_day' : '_dayother')); } else { dc.className = this._prefixCssClass((isCurrentMonth ? 'day' : 'dayother')); } calendar._addClass(dc, "cell"); if (day.getTime() === today.getTime() && isCurrentMonth) { this._addClass(dc, 'today'); } if (day.dayOfWeek() === 0 || day.dayOfWeek() === 6) { this._addClass(dc, 'weekend'); } dc.style.position = 'absolute'; dc.style.left = (x * this.cellWidth) + 'px'; dc.style.top = (y * this.cellHeight + totalHeaderHeight) + 'px'; dc.style.width = this.cellWidth + 'px'; dc.style.height = this.cellHeight + 'px'; dc.style.lineHeight = this.cellHeight + 'px'; // vertical alignment //dc.style.textAlign = 'right'; //dc.style.border = '1px solid white'; var inner = document.createElement("div"); inner.style.position = 'absolute'; if (this._cssOnly) { inner.className = (day.getTime() === today.getTime() && isCurrentMonth) ? this._prefixCssClass('_todaybox') : this._prefixCssClass('_daybox'); } else { inner.className = (day.getTime() === today.getTime() && isCurrentMonth) ? this._prefixCssClass('todaybox') : this._prefixCssClass('daybox'); } calendar._addClass(inner, "cell_box"); inner.style.left = '0px'; inner.style.top = '0px'; inner.style.right = '0px'; inner.style.bottom = '0px'; // inner.style.width = (this.cellWidth - 2) + 'px'; // inner.style.height = (this.cellHeight - 2) + 'px'; dc.appendChild(inner); var cell = null; if (this.cells && this.cells[day.toStringSortable()]) { cell = this.cells[day.toStringSortable()]; if (cell.css) { this._addClass(dc, cell.css); } } //var span = null; if (isCurrentMonth || (showBefore && isPrevMonth) || (showAfter && isNextMonth)) { var text = document.createElement("div"); text.innerHTML = day.getDay(); text.style.position = "absolute"; text.style.left = '0px'; text.style.top = '0px'; text.style.right = '0px'; text.style.bottom = '0px'; calendar._addClass(text, "cell_text"); dc.style.cursor = 'pointer'; dc.isClickable = true; if (cell && cell.html) { text.innerHTML = cell.html; } dc.appendChild(text); } dc.setAttribute("unselectable", "on"); dc.onclick = this._cellClick; dc.onmousedown = this._cellMouseDown; dc.onmousemove = this._cellMouseMove; if (isSelected) { calendar._cellSelect(main, x, y); this.selected.push(dc); } main.appendChild(dc); } } var line = document.createElement("div"); line.style.position = 'absolute'; line.style.left = '0px'; line.style.top = (totalHeaderHeight - 2) + 'px'; line.style.width = (this.cellWidth * 7) + 'px'; line.style.height = '1px'; line.style.fontSize = '1px'; line.style.lineHeight = '1px'; if (this._cssOnly) { line.className = this._prefixCssClass("_line"); } else { line.className = this._prefixCssClass("line"); } //line.style.borderBottom = '1px solid black'; main.appendChild(line); this.months.push(month); }; this._cellSelect = function(main, x, y) { var div = main.month.cells[x][y]; calendar._addClass(div, 'select'); }; this._selectModeLowerCase = function() { var selectMode = this.selectMode || ""; return selectMode.toLowerCase(); }; this._adjustSelection = function() { // ignores selectionEnd // uses selectMode var selectMode = calendar._selectModeLowerCase(); switch (selectMode) { case 'day': this.selectionStart = this.selectionDay; this.selectionEnd = this.selectionStart; break; case 'week': this.selectionStart = this.selectionDay.firstDayOfWeek(resolved.weekStarts()); this.selectionEnd = this.selectionStart.addDays(6); break; case 'month': this.selectionStart = this.selectionDay.firstDayOfMonth(); this.selectionEnd = this.selectionDay.lastDayOfMonth(); break; case 'none': this.selectionStart = this.selectionDay; this.selectionEnd = this.selectionStart; break; default: throw "Unknown selectMode value."; } }; this.select = function(date, options) { var focus = true; var notify = true; // fire the timeRangeSelected event if (typeof options === "object") { if (options.dontFocus) { focus = false; } if (options.dontNotify) { notify = false; } } else if (typeof options === "boolean") { focus = !options; } var originalStart = this.selectionStart; var originalEnd = this.selectionEnd; this.selectionStart = new DayPilot.Date(date).getDatePart(); this.selectionDay = this.selectionStart; var startChanged = false; if (focus) { var newStart = this.startDate; if (this.selectionStart.getTime() < this.visibleStart().getTime() || this.selectionStart.getTime() > this.visibleEnd().getTime()) { newStart = this.selectionStart.firstDayOfMonth(); } if (newStart.toStringSortable() !== this.startDate.toStringSortable()) { startChanged = true; } this.startDate = newStart; } this._adjustSelection(); // redraw this._clearTable(); this._prepare(); this._drawMonths(); if (notify && (!originalStart.equals(this.selectionStart) || !originalEnd.equals(this.selectionEnd))) { //alert('time range'); this._timeRangeSelectedDispatch(); } }; this.update = function() { this._resetCssOnly(); this._adjustSelection(); // redraw this._clearTable(); this._prepare(); this._drawMonths(); }; this._getDayName = function(i) { var x = i + resolved.weekStarts(); if (x > 6) { x -= 7; } return resolved.locale().dayNamesShort[x]; }; this._isSelected = function(date) { if (this.selectionStart === null || this.selectionEnd === null) { return false; } if (this.selectionStart.getTime() <= date.getTime() && date.getTime() <= this.selectionEnd.getTime()) { return true; } return false; }; this._cellMouseDown = function(ev) { }; this._cellMouseMove = function(ev) { }; this._cellClick = function(ev) { var month = this.parentNode.month; var x = this.x; var y = this.y; var day = month.cells[x][y].day; if (!month.cells[x][y].isClickable) { return; } calendar.clearSelection(); calendar.selectionDay = day; var day = calendar.selectionDay; switch (calendar._selectModeLowerCase()) { case 'none': //var s = month.cells[x][y]; calendar.selectionStart = day; calendar.selectionEnd = day; break; case 'day': var s = month.cells[x][y]; calendar._addClass(s, 'select'); calendar.selected.push(s); calendar.selectionStart = s.day; calendar.selectionEnd = s.day; break; case 'week': for (var j = 0; j < 7; j++) { calendar._addClass(month.cells[j][y], 'select'); calendar.selected.push(month.cells[j][y]); } calendar.selectionStart = month.cells[0][y].day; calendar.selectionEnd = month.cells[6][y].day; break; case 'month': var start = null; var end = null; for (var y = 0; y < 6; y++) { for (var x = 0; x < 7; x++) { var s = month.cells[x][y]; if (!s) { continue; } if (s.day.getYear() === day.getYear() && s.day.getMonth() === day.getMonth()) { calendar._addClass(s, 'select'); calendar.selected.push(s); if (start === null) { start = s.day; } end = s.day; } } } calendar.selectionStart = start; calendar.selectionEnd = end; break; default: throw 'unknown selectMode'; } calendar._timeRangeSelectedDispatch(); }; this._timeRangeSelectedDispatch = function() { var start = calendar.selectionStart; var end = calendar.selectionEnd.addDays(1); var days = DayPilot.DateUtil.daysDiff(start, end); var day = calendar.selectionDay; if (calendar._api2()) { var args = {}; args.start = start; args.end = end; args.day = day; args.days = days; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onTimeRangeSelect === 'function') { calendar._angular.apply(function() { calendar.onTimeRangeSelect(args); }); if (args.preventDefault.value) { return; } } if (typeof calendar.onTimeRangeSelected === 'function') { calendar._angular.apply(function() { calendar.onTimeRangeSelected(args); }); } } }; this._clickRight = function(ev) { calendar._moveMonth(calendar.skipMonths); }; this._clickLeft = function(ev) { calendar._moveMonth(-calendar.skipMonths); }; this._moveMonth = function(i) { this.startDate = this.startDate.addMonths(i); this._clearTable(); this._prepare(); this._drawMonths(); }; this.visibleStart = function() { return calendar.startDate.firstDayOfMonth().firstDayOfWeek(resolved.weekStarts()); }; this.visibleEnd = function() { return calendar.startDate.firstDayOfMonth().addMonths(this.showMonths - 1).firstDayOfWeek(resolved.weekStarts()).addDays(42); }; this._drawMonths = function() { for (var j = 0; j < this.showMonths; j++) { var showLinks = this._getShowLinks(j); this._drawTable(j, showLinks); } this.root.style.height = this._getHeight() + "px"; }; this._getHeight = function() { var total = 0; for (var i = 0; i < this.months.length; i++) { var month = this.months[i]; total += month.height; } return total; }; this._getShowLinks = function(j) { if (this.internal.showLinks) { return this.internal.showLinks; } var showLinks = {}; showLinks.left = (j === 0); showLinks.right = (j === 0); showLinks.before = j === 0; showLinks.after = j === this.showMonths - 1; return showLinks; }; this.internal = {}; this._resolved = {}; var resolved = this._resolved; resolved.locale = function() { return DayPilot.Locale.find(calendar.locale); }; resolved.weekStarts = function() { if (calendar.weekStarts === 'Auto') { var locale = resolved.locale(); if (locale) { return locale.weekStarts; } else { return 0; // Sunday } } else { return calendar.weekStarts; } }; this.clearSelection = function() { for (var j = 0; j < this.selected.length; j++) { this._removeClass(this.selected[j], 'select'); } this.selected = []; }; this._angular = {}; this._angular.scope = null; this._angular.notify = function() { if (calendar._angular.scope) { calendar._angular.scope["$apply"](); } }; this._angular.apply = function(f) { if (calendar.angularAutoApply && calendar._angular.scope) { calendar._angular.scope["$apply"](f); } else { f(); } }; this._resetCssOnly = function() { if (!calendar._cssOnly) { calendar._cssOnly = true; window.console && window.console.log && window.console.log("DayPilot: cssOnly = false mode is not supported anymore."); } }; this._loadTop = function() { if (this.id && this.id.tagName) { this.nav.top = this.id; } else if (typeof this.id === "string") { this.nav.top = document.getElementById(this.id); if (!this.nav.top) { throw "DayPilot.Navigator: The placeholder element not found: '" + id + "'."; } } else { throw "DayPilot.Navigator() constructor requires the target element or its ID as a parameter"; } this.root = this.nav.top; }; this.init = function() { //this.root = document.getElementById(id); this._loadTop(); this._resetCssOnly(); if (this.root.dp) { // already initialized return; } this._adjustSelection(); this._prepare(); this._drawMonths(); this._registerDispose(); this.initialized = true; }; this.dispose = function() { var c = calendar; if (!c.root) { return; } c.root.removeAttribute("style"); c.root.removeAttribute("class"); c.root.dp = null; c.root.innerHTML = null; c.root = null; }; this._registerDispose = function() { //var root = document.getElementById(id); this.root.dispose = this.dispose; }; this.Init = this.init; }; function addClass(object, name) { if (!name) { return; } if (!object) { return; } if (isArray(object)) { for (var i = 0; i < object.length; i++) { addClass(object[i], name); } return; } if (!object.className) { object.className = name; return; } var already = new RegExp("(^|\\s)" + name + "($|\\s)"); if (!already.test(object.className)) { object.className = object.className + ' ' + name; } } function removeClass(object, name) { if (!object) { return; } if (isArray(object)) { for (var i = 0; i < object.length; i++) { removeClass(object[i], name); } return; } if (!object.className) { return; } var already = new RegExp("(^|\\s)" + name + "($|\\s)"); object.className = object.className.replace(already, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // trim spaces } function isArray(o) { return Object.prototype.toString.call(o) === '[object Array]'; } })(local); const {Navigator} = local; export {Navigator};