/* Copyright 2005 - 2015 Annpoint, s.r.o. Use of this software is subject to license terms. http://www.daypilot.org/ */ if (typeof DayPilot === 'undefined') { var DayPilot = {}; } if (typeof DayPilot.Global === 'undefined') { DayPilot.Global = {}; } // compatibility with 5.9.2029 and previous if (typeof DayPilotScheduler === 'undefined') { var DayPilotScheduler = DayPilot.SchedulerVisible = {}; } (function() { if (typeof DayPilot.Scheduler !== 'undefined') { return; } // temp hack var android = (function() { var nua = navigator.userAgent; return ((nua.indexOf('Mozilla/5.0') > -1 && nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1) && !(nua.indexOf('Chrome') > -1)); })(); var DayPilotScheduler = {}; var doNothing = function() { }; DayPilot.Scheduler = function(id, options) { this.v = '1658'; var calendar = this; this.id = id; // referenced this.isScheduler = true; this.hideUntilInit = true; this.api = 2; // default values this.allowDefaultContextMenu = false; this.allowEventOverlap = true; this.allowMultiMove = false; this.allowMultiRange = false; this.allowMultiResize = false; this.allowMultiSelect = true; this.multiSelectRectangle = "Disabled"; // "Free", "Row", "Disabled" //this.allowDuplicateResources = false; this.autoRefreshCommand = 'refresh'; this.autoRefreshEnabled = false; this.autoRefreshInterval = 60; this.autoRefreshMaxCount = 20; this.autoScroll = "Drag"; this.blockOnCallBack = false; this.borderColor = "#000000"; this.businessBeginsHour = 9; this.businessEndsHour = 18; this.cellBackColor = "#FFFFD5"; this.cellBackColorNonBusiness = "#FFF4BC"; this.cellBorderColor = "#EAD098"; this.cellDuration = 60; this.cellGroupBy = 'Day'; this.cellSelectColor = "#316AC5"; this.cellWidth = 40; this.cellWidthSpec = "Fixed"; //this.clientSide = true; this.groupConcurrentEvents = false; this.groupConcurrentEventsLimit = 1; this._cellPropertiesLazyLoading = true; // server-based only this.cellSweeping = true; this.cellSweepingCacheSize = 1000; this.crosshairColor = 'Gray'; this.crosshairOpacity = 20; this.crosshairType = 'Header'; //this.debuggingEnabled = false; this.doubleClickTimeout = 300; this.dragOutAllowed = false; this.durationBarColor = 'blue'; this.durationBarHeight = 3; this.durationBarVisible = true; this.durationBarMode = "Duration"; this.durationBarDetached = false; this.days = 1; this.drawBlankCells = true; this.dynamicEventRendering = 'Progressive'; this.dynamicEventRenderingMargin = 50; this.dynamicEventRenderingMarginX = null; this.dynamicEventRenderingMarginY = null; this.dynamicEventRenderingCacheSweeping = false; this.dynamicEventRenderingCacheSize = 200; this.dynamicLoading = false; this.eventBorderColor = "#000000"; this.eventBorderVisible = true; this.eventBackColor = "#FFFFFF"; this.eventEndSpec = "DateTime"; this.eventFontFamily = "Tahoma, Arial"; this.eventFontSize = '8pt'; this.eventFontColor = '#000000'; this.eventHeight = 25; this.eventMoveMargin = 5; this.eventMoveToPosition = false; this.eventResizeMargin = 5; this.eventStackingLineHeight = 100; this.eventTapAndHoldHandling = "Move"; this.eventTextWrappingEnabled = false; this._ganttAppendToResources = false; this.headerFontColor = "#000000"; this.headerFontFamily = "Tahoma, Arial"; this.headerFontSize = '8pt'; this.headerHeight = 20; this.heightSpec = 'Auto'; this.hideBorderFor100PctHeight = false; this.hourFontFamily = "Tahoma, Arial"; this.hourFontSize = '10pt'; this.hourNameBackColor = "#ECE9D8"; this.hourNameBorderColor = "#ACA899"; this.layout = 'Auto'; this.linkCreateHandling = "Disabled"; this.linkBottomMargin = 10; this.locale = "en-us"; this.loadingLabelText = "Loading..."; this.loadingLabelVisible = true; this.loadingLabelBackColor = "orange"; this.loadingLabelFontColor = "#ffffff"; this.loadingLabelFontFamily = "Tahoma"; this.loadingLabelFontSize = "10pt"; this.messageHideAfter = 5000; this.messageHideOnMouseOut = true; this.multiMoveVerticalMode = "Disabled"; // options: "Disabled", "Master", "All" this.moveBy = 'Full'; this.notifyCommit = 'Immediate'; // or 'Queue' this.numberFormat = "0.00"; this.progressiveRowRendering = true; this.progressiveRowRenderingPreload = 25; this.tapAndHoldTimeout = 500; this.timeHeaders = [ {"groupBy": "Default"}, {"groupBy": "Cell"} ]; this.treePreventParentUsage = false; this.treeAutoExpand = true; this.rowHeaderHideIconEnabled = false; this.rowHeaderWidth = 80; this.rowHeaderScrolling = false; this.rowHeaderSplitterWidth = 3; this.rowHeaderWidthAutoFit = true; this.rowHeaderCols = null; this.rowMarginBottom = 0; this.rowMarginTop = 0; this.rowMinHeight = 0; this.scale = "CellDuration"; this.scrollDelayDynamic = 500; this.scrollDelayEvents = 200; this.scrollDelayCells = 20; this.scrollDelayFloats = 0; this.scrollX = 0; this.scrollY = 0; this.shadow = "Fill"; this.showBaseTimeHeader = true; // obsolete this.showNonBusiness = true; this.showToolTip = true; this.snapToGrid = true; this.startDate = new DayPilot.Date().getDatePart(); this.syncResourceTree = false; this.timeBreakColor = '#000000'; this.timeHeaderTextWrappingEnabled = false; this.treeEnabled = false; this.treeIndent = 20; this.treeImageMarginLeft = 5; this.treeImageMarginTop = 5; this.timeFormat = "Auto"; this.useEventBoxes = 'Always'; this.viewType = 'Resources'; this.visible = true; this.weekStarts = 'Auto'; // 0 = Sunday, 1 = Monday, ... 'Auto' = use .locale this.width = null; this.floatingEvents = true; this.floatingTimeHeaders = true; this.eventCorners = 'Regular'; ; this.separators = []; //this.afterRender = function() { }; this.cornerHtml = ''; this._crosshairLastY = -1; this._crosshairLastX = -1; this.eventClickHandling = 'Enabled'; this.eventDeleteHandling = "Disabled"; this.eventHoverHandling = 'Bubble'; this.eventDoubleClickHandling = 'Disabled'; this.eventEditHandling = 'Update'; this.eventMoveHandling = 'Update'; this.eventResizeHandling = 'Update'; this.eventRightClickHandling = 'ContextMenu'; this.eventSelectHandling = 'Update'; this.rowClickHandling = 'Enabled'; this.rowDoubleClickHandling = "Disabled"; this.rowCreateHandling = "Disabled"; this.rowEditHandling = 'Update'; this.rowHeaderColumnResizedHandling = "Update"; this.rowSelectHandling = 'Update'; this.rowMoveHandling = "Disabled"; this.timeRangeDoubleClickHandling = 'Disabled'; this.timeRangeSelectedHandling = 'Enabled'; this.eventMovingStartEndEnabled = false; this.eventMovingStartEndFormat = "MMMM d, yyyy"; this.timeRangeSelectingStartEndEnabled = false; this.timeRangeSelectingStartEndFormat = "MMMM d, yyyy"; this.eventResizingStartEndEnabled = false; this.eventResizingStartEndFormat = "MMMM d, yyyy"; this.cssOnly = true; this.cssClassPrefix = "bookview"; // if null, ASP.NET callback will be used this.backendUrl = null; if (calendar.api === 1) { this.onEventMove = function() { }; this.onEventResize = function() { }; this.onResourceExpand = function() { }; this.onResourceCollapse = function() { }; } this.onBeforeTimeHeaderRender = null; this.onEventMove = null; this.onEventMoved = null; this.onEventMoving = null; this.onEventResize = null; this.onEventResized = null; this.onEventResizing = null; this.onEventMouseOver = null; // TODO rename to onEventMouseEnter? this.onEventMouseOut = null; // TODO rename to onEventMouseLeave? this.onTimeRangeSelect = null; this.onTimeRangeSelected = null; this.onTimeRangeSelecting = null; this.onRowHeaderResized = null; this.onBeforeCellRender = null; this.onCellMouseOver = null; // TODO rename to onCellMouseEnter? this.onCellMouseOut = null; // TODO rename to onCellMouseLeave? this.onRectangleEventSelecting = null; this.onRectangleEventSelect = null; this.onRectangleEventSelected = null; //this._debugMessages = []; this.autoRefreshCount = 0; this._innerHeightTree = 0; // internal, name kept non-minified for debugging purposes this.rowlist = []; this.itline = []; this.timeline = null; //this.status = {}; this.events = {}; this.cells = {}; // store the element references this.elements = {}; this.elements.events = []; this.elements.bars = []; this.elements.text = []; this.elements.cells = []; this.elements.linesVertical = []; // required for height updating //this.elements.linesHorizontal = []; this.elements.separators = []; this.elements.range = []; this.elements.breaks = []; this.elements.links = []; this.elements.linkpoints = []; this.elements.rectangle = []; this._cache = {}; this._cache.cells = []; this._cache.linesVertical = {}; this._cache.linesHorizontal = {}; this._cache.timeHeaderGroups = []; this._cache.timeHeader = {}; this._cache.pixels = []; this._cache.breaks = []; this._cache.events = []; // processed using client-side beforeEventRender this.clientState = {}; this.q = new DayPilot.Queue(); this.members = {}; this.members.obsolete = [ "Init", "cleanSelection", "cssClassPrefix", "getHScrollPosition", "setHScrollPosition", "getVScrollPosition", "setVScrollPosition", "showBaseTimeHeader" ]; this.members.ignoreFilter = function(name) { if (name.indexOf("div") === 0) { return true; } return false; }; this.members.ignore = [ "internal", "nav", "debug", "temp", "elements", "members", "cellProperties", "itline", "rowlist", "timeHeader" ]; this.members.noCssOnly = [ "borderColor", "cellBackColor", "cellBackColorNonBusiness", "cellBorderColor", "cellSelectColor", "durationBarColor", "eventBackColor", "eventBorderColor", "eventBorderVisible", "eventCorners", "eventFontColor", "eventFontFamily", "eventFontSize", "headerFontColor", "headerFontFamily", "headerFontSize", "hourFontFamily", "hourFontSize", "hourNameBackColor", "hourNameBorderColor", "loadingLabelBackColor", "loadingLabelFontColor", "loadingLabelFontFamily", "loadingLabelFontSize", "shadow", "timeBreakColor" ]; this.nav = {}; this._updateView = function(result, context) { var result = DayPilot.Util.parseJSON(result); calendar.onScrollCalled = false; if (typeof calendar.onCallBackResult === "function") { // internal API var args = {}; args.result = result; args.preventDefault = function() { args.preventDefault.value = true; }; calendar.onCallBackResult(args); if (args.preventDefault.value) { //calendar._updateFloats(); calendar._deleteDragSource(); calendar._loadingStop(); calendar._startAutoRefresh(); if (result.Message) { if (calendar.message) { // condition can be removed as soon as message() is implemented properly calendar.message(result.Message); } } calendar._fireAfterRenderDetached(result.CallBackData, true); calendar._doCallBackEnd(); calendar._clearCachedValues(); return; } } if (result.BubbleGuid) { var guid = result.BubbleGuid; var bubble = this.bubbles[guid]; delete this.bubbles[guid]; calendar._loadingStop(); if (typeof result.Result.BubbleHTML !== 'undefined' && bubble) { bubble.updateView(result.Result.BubbleHTML, bubble); } calendar._doCallBackEnd(); return; } if (result.CallBackRedirect) { document.location.href = result.CallBackRedirect; return; } if (typeof DayPilot.Bubble !== "undefined") { DayPilot.Bubble.hideActive(); } if (typeof result.ClientState !== 'undefined') { if (result.ClientState === null) { calendar.clientState = {}; } else { calendar.clientState = result.ClientState; } } if (result.UpdateType === "None") { calendar._loadingStop(); calendar._doCallBackEnd(); //calendar.afterRender(result.CallBackData, true); if (result.Message) { calendar.message(result.Message); } calendar._fireAfterRenderDetached(result.CallBackData, true); return; } // update config if (result.VsUpdate) { var vsph = document.createElement("input"); vsph.type = 'hidden'; vsph.name = calendar.id + "_vsupdate"; vsph.id = vsph.name; vsph.value = result.VsUpdate; calendar._vsph.innerHTML = ''; calendar._vsph.appendChild(vsph); } if (typeof result.TagFields !== 'undefined') { calendar.tagFields = result.TagFields; } if (typeof result.SortDirections !== 'undefined') { calendar.sortDirections = result.SortDirections; } calendar._cache.drawArea = null; if (result.UpdateType === "Full") { // generated calendar.resources = result.Resources; calendar.colors = result.Colors; calendar.palette = result.Palette; calendar.dirtyColors = result.DirtyColors; calendar.cellProperties = result.CellProperties; calendar.cellConfig = result.CellConfig; calendar.separators = result.Separators; calendar.timeline = result.Timeline; calendar.timeHeader = result.TimeHeader; calendar.timeHeaders = result.TimeHeaders; if (typeof result.Links !== "undefined") { calendar.links.list = result.Links; } if (typeof result.RowHeaderColumns !== 'undefined') calendar.rowHeaderColumns = result.RowHeaderColumns; // properties calendar.startDate = result.StartDate ? new DayPilot.Date(result.StartDate) : calendar.startDate; calendar.days = result.Days ? result.Days : calendar.days; calendar.cellDuration = result.CellDuration ? result.CellDuration : calendar.cellDuration; calendar.cellGroupBy = result.CellGroupBy ? result.CellGroupBy : calendar.cellGroupBy; calendar.cellWidth = result.CellWidth ? result.CellWidth : calendar.cellWidth; // scrollX // scrollY calendar.viewType = result.ViewType ? result.ViewType : calendar.viewType; calendar.hourNameBackColor = result.HourNameBackColor ? result.HourNameBackColor : calendar.hourNameBackColor; if (typeof result.ShowNonBusiness !== 'undefined') calendar.showNonBusiness = result.ShowNonBusiness; calendar.businessBeginsHour = result.BusinessBeginsHour ? result.BusinessBeginsHour : calendar.businessBeginsHour; calendar.businessEndsHour = result.BusinessEndsHour ? result.BusinessEndsHour : calendar.businessEndsHour; if (typeof result.DynamicLoading !== 'undefined') calendar.dynamicLoading = result.DynamicLoading; if (typeof result.TreeEnabled !== 'undefined') calendar.treeEnabled = result.TreeEnabled; calendar.backColor = result.BackColor ? result.BackColor : calendar.backColor; calendar.nonBusinessBackColor = result.NonBusinessBackColor ? result.NonBusinessBackColor : calendar.nonBusinessBackColor; calendar.locale = result.Locale ? result.Locale : calendar.locale; if (typeof result.TimeZone !== 'undefined') calendar.timeZone = result.TimeZone; calendar.timeFormat = result.TimeFormat ? result.TimeFormat : calendar.timeFormat; calendar.rowHeaderCols = result.RowHeaderCols ? result.RowHeaderCols : calendar.rowHeaderCols; if (typeof result.DurationBarMode !== "undefined") calendar.durationBarMode = result.DurationBarMode; //if (typeof result.ShowBaseTimeHeader !== "undefined") calendar.showBaseTimeHeader = result.ShowBaseTimeHeader; calendar.cornerBackColor = result.CornerBackColor ? result.CornerBackColor : calendar.cornerBackColor; if (typeof result.CornerHTML !== 'undefined') { calendar.cornerHtml = result.CornerHTML; } calendar.hashes = result.Hashes; calendar._calculateCellWidth(); calendar._prepareItline(); calendar._loadResources(); calendar._expandCellProperties(); } if (result.Action !== "Scroll") { calendar._loadEvents(result.Events); } if (result.UpdateType === 'Full') { calendar._drawResHeader(); calendar._drawTimeHeader(); } calendar._prepareRowTops(); calendar._show(); //calendar._updateHeight(); // test calendar._resize(); calendar._cache.drawArea = null; if (result.Action !== "Scroll") { calendar._updateRowHeaderHeights(); calendar._updateHeaderHeight(); if (calendar.heightSpec === 'Auto' || calendar.heightSpec === 'Max') { calendar._updateHeight(); } calendar._deleteCells(); calendar._deleteEvents(); calendar._deleteSeparators(); calendar.multiselect.clear(true); calendar.multiselect._loadList(result.SelectedEvents); calendar._drawCells(); calendar._drawSeparators(); calendar._drawEvents(); } else { calendar.multiselect.clear(true); calendar.multiselect._loadList(result.SelectedEvents); //calendar._updateRowsNoLoad(updatedRows, true); // draw events not called here because it's now called in loadEventsDynamic //calendar._drawCells(); calendar._loadEventsDynamic(result.Events); } if (!DayPilot.list(calendar.multiselect.list).isEmpty()) { calendar.multiselect.redraw(); } if (calendar.timeRangeSelectedHandling !== "HoldForever") { calendar._deleteRange(); } if (result.UpdateType === "Full") { calendar.setScroll(result.ScrollX, result.ScrollY); calendar._saveState(); } calendar._updateFloats(); calendar._deleteDragSource(); if (result.SelectedRows) { calendar._loadSelectedRows(result.SelectedRows); } calendar._loadingStop(); if (result.UpdateType === 'Full' && navigator.appVersion.indexOf("MSIE 7.") !== -1) { // ugly bug, ugly fix - the time header disappears after expanding a dynamically loaded tree node window.setTimeout(function() { calendar._drawResHeader(); calendar._updateHeight(); }, 0); } calendar._startAutoRefresh(); if (result.Message) { if (calendar.message) { // condition can be removed as soon as message() is implemented properly calendar.message(result.Message); } } calendar._fireAfterRenderDetached(result.CallBackData, true); calendar._doCallBackEnd(); calendar._clearCachedValues(); if (result.UpdateType === 'Full' && result.Action !== "Scroll" && !calendar.onScrollCalled) { setTimeout(function() { calendar._onScroll(); }, 0); } }; this._deleteDragSource = function() { if (calendar.todo) { if (calendar.todo.del) { var del = calendar.todo.del; del.parentNode.removeChild(del); calendar.todo.del = null; } } }; this._fireAfterRenderDetached = function(data, isCallBack) { var afterRenderDelayed = function(data, isc) { return function() { if (calendar._api2()) { if (typeof calendar.onAfterRender === 'function') { var args = {}; args.isCallBack = isc; args.data = data; calendar.onAfterRender(args); } } else { if (calendar.afterRender) { calendar.afterRender(data, isc); } } }; }; window.setTimeout(afterRenderDelayed(data, isCallBack), 0); }; this.scrollTo = function(date, animated, position) { if (!date) { return; } var pixels; if (date.isDayPilotDate) { pixels = this.getPixels(date).left; } else if (typeof date === "string") { pixels = this.getPixels(new DayPilot.Date(date)).left; } else if (typeof date === "number") { pixels = date; } else { throw "Invalid scrollTo() parameter. Accepted parameters: string (ISO date), number (pixels), DayPilot.Date object"; } var max = this._maind.clientWidth; var width = this.nav.scroll.clientWidth; position = position || "left"; switch(position.toLowerCase()) { case "left": break; case "middle": pixels -= width/2; break; case "right": pixels -= width; break; } if (pixels < 0) { pixels = 0; } if (pixels > max - width) { pixels = max - width; } if (!animated) { this.setScrollX(pixels); } else { this._scrollToAnimated(pixels); } }; this._scrollToAnimated = function(pixels) { var plan = {}; plan.steps = []; plan.index = 0; plan.delay = 10; plan.next = function() { var step = plan.steps[plan.index]; plan.index += 1; return step; }; plan.finished = function() { calendar._onScroll(); }; var pos = calendar.getScrollX(); var steps = 100; var diff = pixels - pos; for (var i = 0; i < steps; i++) { var x = i/steps; var pct = ((x-.5)*2)/(Math.pow(((x-0.5)*2),2)+1)+.5; plan.steps.push(pos + diff*pct); } plan.steps.push(pixels); scrollStep(plan); function scrollStep(plan) { var step = plan.next(); if (typeof step === "undefined") { plan.finished && plan.finished(); return; } calendar.setScrollX(step); window.clearTimeout(calendar.refreshTimeout); setTimeout(function() { scrollStep(plan); }, plan.delay); }; }; this.scrollToResource = function(id) { DayPilot.complete(function() { var row = calendar._findRowByResourceId(id); if (!row) { return; } setTimeout(function() { var scrollY = row.top; calendar.nav.scroll.scrollTop = scrollY; }, 100); }); }; this._findHeadersInViewPort = function() { if (!this.cssOnly) { return; } if (!this.floatingTimeHeaders) { return; } if (!this.timeHeader) { return; } var area = this._getDrawArea(); if (!area) { return; } this._deleteHeaderSections(); var start = area.pixels.left; var end = area.pixels.right; var cells = []; for (var y = 0; y < this.timeHeader.length; y++) { for (var x = 0; x < this.timeHeader[y].length; x++) { var h = this.timeHeader[y][x]; var left = h.left; var right = h.left + h.width; var cell = null; if (left < start && start < right) { cell = {}; cell.x = x; cell.y = y; cell.marginLeft = start - left; cell.marginRight = 0; cell.div = this._cache.timeHeader[x + "_" + y]; cells.push(cell); } if (left < end && end < right) { if (!cell) { cell = {}; cell.x = x; cell.y = y; cell.marginLeft = 0; cell.div = this._cache.timeHeader[x + "_" + y]; cells.push(cell); } cell.marginRight = right - end; break; // end of this line } } } for (var i = 0; i < cells.length; i++) { var cell = cells[i]; this._createHeaderSection(cell.div, cell.marginLeft, cell.marginRight); } }; this._updateFloats = function() { this._findHeadersInViewPort(); this._findEventsInViewPort(); }; this._viewport = {}; var viewport = this._viewport; viewport.eventsInRectangle = function(x, y, width, height) { var startX = x; var endX = x + width; var startY = y; var endY = y + height; return DayPilot.list(calendar.elements.events).filter(function(e) { var data = e.event; var left = data.part.left; var right = data.part.left + data.part.width; var row = calendar.rowlist[data.part.dayIndex]; var top = row.top + data.part.top; var bottom = top + data.part.height; if (DayPilot.Util.overlaps(left, right, startX, endX) && DayPilot.Util.overlaps(top, bottom, startY, endY)) { return true; } }); }; viewport.events = function(type) { var list = []; var type = type || "All"; var area = calendar._getDrawArea(); if (!area) { return DayPilot.list(list); } var start = area.pixels.left; var end = area.pixels.right; for(var i = 0; i < calendar.elements.events.length; i++) { var e = calendar.elements.events[i]; var data = e.event; var left = data.part.left; var right = data.part.left + data.part.width; switch (type) { case "Left": if (left < start && start < right) { list.push(e); } break; case "All": if (DayPilot.Util.overlaps(left, right, start, end)) { list.push(e); } break; } } return DayPilot.list(list).addProps({ "area": area}); }; this._findEventsInViewPort = function() { if (!this.cssOnly) { return; } if (!this.floatingEvents) { return; } var events = viewport.events("Left"); this._deleteEventSections(); events.each(function(item) { var left = events.area.pixels.left; var data = item.event; var start = data.part.left; var marginLeft = left - start; calendar._createEventSection(item, marginLeft, 0); }); }; this.elements.sections = []; this.elements.hsections = []; this._createHeaderSection = function(div, marginLeft, marginRight) { var section = document.createElement("div"); section.setAttribute("unselectable", "on"); section.className = this._prefixCssClass("_timeheader_float"); section.style.position = "absolute"; section.style.left = marginLeft + "px"; section.style.right = marginRight + "px"; section.style.bottom = "0px"; //section.style.backgroundColor = "red"; //section.style.color = "white"; section.style.overflow = "hidden"; var inner = document.createElement("div"); inner.className = this._prefixCssClass("_timeheader_float_inner"); inner.setAttribute("unselectable", "on"); inner.innerHTML = div.cell.th.innerHTML; section.appendChild(inner); div.section = section; //div.appendChild(section); div.insertBefore(section, div.firstChild.nextSibling); // after inner div.firstChild.innerHTML = ''; // hide the content of inner temporarily this.elements.hsections.push(div); }; this._deleteHeaderSections = function() { for (var i = 0; i < this.elements.hsections.length; i++) { var e = this.elements.hsections[i]; // restore HTML in inner var data = e.cell; if (data && e.firstChild) { // might be deleted already e.firstChild.innerHTML = data.th.innerHTML; } DayPilot.de(e.section); e.section = null; } this.elements.hsections = []; }; this._createEventSection = function(div, marginLeft, marginRight) { var section = document.createElement("div"); section.setAttribute("unselectable", "on"); section.className = this._prefixCssClass("_event_float"); section.style.position = "absolute"; section.style.left = marginLeft + "px"; section.style.right = marginRight + "px"; section.style.top = "0px"; section.style.bottom = "0px"; section.style.overflow = "hidden"; var inner = document.createElement("div"); inner.className = this._prefixCssClass("_event_float_inner"); if (div.event.data.additionalClassName) { inner.className += " " + div.event.data.additionalClassName; } if (div.event.data.collisionCount) { inner.setAttribute("collision-count", div.event.data.collisionCount); } inner.setAttribute("unselectable", "on"); inner.innerHTML = div.event.client.html(); section.appendChild(inner); //section.innerHTML = div.event.text(); div.section = section; //div.firstChild.appendChild(section); div.insertBefore(section, div.firstChild.nextSibling); // after inner div.firstChild.innerHTML = ''; // hide the content of inner temporarily div.firstChild.removeAttribute("collision-count"); this.elements.sections.push(div); }; this._deleteEventSections = function() { for (var i = 0; i < this.elements.sections.length; i++) { var e = this.elements.sections[i]; // restore HTML in inner var data = e.event; if (data) { // might be deleted already e.firstChild.innerHTML = data.client.html(); if (e.firstChild.innerHTML) { if (data.data.collisionCount) { e.firstChild.setAttribute("collision-count", data.data.collisionCount); } } else { e.firstChild.removeAttribute("collision-count"); } } DayPilot.de(e.section); e.section = null; } this.elements.sections = []; }; this.setScrollX = function(scrollX) { this.setScroll(scrollX, calendar.scrollY); }; this.setScrollY = function(scrollY) { this.setScroll(calendar.scrollX, scrollY); }; this.setScroll = function(scrollX, scrollY) { var scroll = calendar.nav.scroll; var maxHeight = calendar._innerHeightTree; var maxWidth = calendar._cellCount() * calendar.cellWidth; if (scroll.clientWidth + scrollX > maxWidth) { scrollX = maxWidth - scroll.clientWidth; } //var scrollY = result.ScrollY; if (scroll.clientHeight + scrollY > maxHeight) { scrollY = maxHeight - scroll.clientHeight; } calendar.divTimeScroll.scrollLeft = scrollX; calendar.divResScroll.scrollTop = scrollY; scroll.scrollLeft = scrollX; scroll.scrollTop = scrollY; }; this.message = function(html, delay, foreColor, backColor) { if (html === null) { return; } var delay = delay || this.messageHideAfter || 2000; var foreColor = foreColor || "#ffffff"; var backColor = backColor || "#000000"; var opacity = 0.8; var top = this._getTotalHeaderHeight() + 1; var left = this._getOuterRowHeaderWidth() + resolved.splitterWidth(); var right = DayPilot.sw(calendar.nav.scroll) + 1; var bottom = DayPilot.sh(calendar.nav.scroll) + 1; var div; if (!this.nav.message) { div = document.createElement("div"); div.style.position = "absolute"; //div.style.width = "100%"; div.style.left = left + "px"; div.style.right = right + "px"; //div.style.height = "0px"; //div.style.paddingLeft = left + "px"; //div.style.paddingRight = right + "px"; //div.style.opacity = 1; //div.style.filter = "alpha(opacity=100)"; // enable fading in IE8 div.style.display = 'none'; div.onmousemove = function() { if (!calendar.messageHideOnMouseOut) { return; } if (div.messageTimeout && !div.status) { clearTimeout(div.messageTimeout); } }; div.onmouseout = function() { if (!calendar.messageHideOnMouseOut) { return; } if (calendar.nav.message.style.display !== 'none') { div.messageTimeout = setTimeout(calendar._hideMessage, 500); } }; var inner = document.createElement("div"); inner.onclick = function() { calendar.nav.message.style.display = 'none'; }; if (!this.cssOnly) { inner.style.padding = "5px"; inner.style.opacity = opacity; inner.style.filter = "alpha(opacity=" + (opacity * 100) + ")"; } else { inner.className = this._prefixCssClass("_message"); } div.appendChild(inner); var close = document.createElement("div"); close.style.position = "absolute"; if (!this.cssOnly) { close.style.top = "5px"; close.style.right = (DayPilot.sw(calendar.nav.scroll) + 5) + "px"; close.style.color = foreColor; close.style.lineHeight = "100%"; close.style.cursor = "pointer"; close.style.fontWeight = "bold"; close.innerHTML = "X"; } else { close.className = this._prefixCssClass("_message_close"); } close.onclick = function() { calendar.nav.message.style.display = 'none'; }; div.appendChild(close); this.nav.top.appendChild(div); this.nav.message = div; } else { div = calendar.nav.message; } var showNow = function() { var inner = calendar.nav.message.firstChild; if (!calendar.cssOnly) { inner.style.backgroundColor = backColor; inner.style.color = foreColor; } inner.innerHTML = html; // update the right margin (scrollbar width) var right = DayPilot.sw(calendar.nav.scroll) + 1; calendar.nav.message.style.right = right + "px"; // always update the position var position = calendar.messageBarPosition || "Top"; if (position === "Bottom") { calendar.nav.message.style.bottom = bottom + "px"; calendar.nav.message.style.top = ""; } else if (position === "Top") { calendar.nav.message.style.bottom = ""; calendar.nav.message.style.top = top + "px"; } var end = function() { div.messageTimeout = setTimeout(calendar._hideMessage, delay); }; DayPilot.fade(calendar.nav.message, 0.2, end); }; clearTimeout(div.messageTimeout); // another message was visible if (this.nav.message.style.display !== 'none') { DayPilot.fade(calendar.nav.message, -0.2, showNow); } else { showNow(); } }; this._hideMessage = function() { if (!calendar.nav.message) { return; } var end = function() { calendar.nav.message.style.display = 'none'; }; DayPilot.fade(calendar.nav.message, -0.2, end); }; this.message.show = function(html) { calendar.message(html); }; this.message.hide = function() { calendar._hideMessage(); }; this._originalBorder = null; // updates the height after a resize this._updateHeight = function() { if (this.nav.scroll) { // only if the control is not disposed already var dividerHeight = 1; if (this._originalBorder !== null) { this.nav.top.style.border = this._originalBorder; this._originalBorder = null; } if (this.heightSpec === 'Parent100Pct') { // similar to setHeight() this.nav.top.style.height = "100%"; if (this.hideBorderFor100PctHeight) { this._originalBorder = this.nav.top.style.border; this.nav.top.style.border = "0 none"; } this.height = parseInt(this.nav.top.clientHeight, 10) - (this._getTotalHeaderHeight()) - dividerHeight; } // getting ready for the scrollbar // keep it here, firefox requires it to get the scrollbar height this.nav.scroll.style.height = '30px'; var height = this._getScrollableHeight(); //height = Math.max(1, height); // make sure it's not negative var total = height + this._getTotalHeaderHeight() + dividerHeight; if (height >= 0) { this.nav.scroll.style.height = (height) + 'px'; this._scrollRes.style.height = (height) + 'px'; } if (this.nav.divider) { if (!total || isNaN(total) || total < 0) { total = 0; } this.nav.divider.style.height = (total) + "px"; } // required for table-based mode if (this.heightSpec !== "Parent100Pct") { this.nav.top.style.height = (total) + "px"; } //calendar.nav.resScrollSpace.style.height = (calendar.divResScroll.clientHeight + 20) + "px"; if (calendar.nav.resScrollSpace) { calendar.nav.resScrollSpace.style.height = (height + 20) + "px"; } for (var i = 0; i < this.elements.separators.length; i++) { this.elements.separators[i].style.height = this._innerHeightTree + 'px'; } for (var i = 0; i < this.elements.linesVertical.length; i++) { this.elements.linesVertical[i].style.height = this._innerHeightTree + 'px'; } } }; this._prepareItline = function() { this.startDate = new DayPilot.Date(this.startDate).getDatePart(); this._endDate = (this.viewType !== 'Days') ? this.startDate.addDays(this.days) : this.startDate.addDays(1); this._cache.pixels = []; this.itline = []; var autoCellWidth = this.cellWidthSpec === "Auto"; //var customWidth = false; var updateCellWidthForAuto = function() { if (!autoCellWidth) { return; } var count = 0; if (calendar.timeHeader) { if (calendar.timeline) { count = calendar.timeline.length; } else { var row = calendar.timeHeader[calendar.timeHeader.length - 1]; count = row.length; } } else { if (calendar.scale === "Manual") { count = calendar.timeline.length; } else { calendar._generateTimeline(); // hack count = calendar.itline.length; calendar.itline = []; } } var width = calendar._getScrollableWidth(); if (count > 0 && width > 0) { //calendar.cellWidth = Math.floor(width / count); calendar.cellWidth = width / count; //if (calendar.cellWidth * count > width) } //calendar.debug.message("updated cellWidth: " + calendar.cellWidth); }; updateCellWidthForAuto(); // set on the server, copy from there if (this._serverBased() && this.timeline) { // timeline supplied from the server if (this.timeline) { // TODO dissolve //calendar.debug.message("timeline received from server"); this.itline = []; var lastEnd = null; var left = 0; for (var i = 0; i < this.timeline.length; i++) { /* if (src.width) { customWidth = true; }*/ var src = this.timeline[i]; var cell = {}; cell.start = new DayPilot.Date(src.start); cell.end = src.end ? new DayPilot.Date(src.end) : cell.start.addMinutes(this.cellDuration); if (!src.width) { var right = Math.floor(left + this.cellWidth); var width = right - Math.floor(left); cell.left = Math.floor(left); cell.width = width; left += this.cellWidth; } else { cell.left = src.left || left; // left is optional TODO remove original syntax cell.width = src.width || this.cellWidth; // width is optional TODO remove original syntax left += cell.width; } /* if (autoCellWidth) { cell.left = Math.floor(left); cell.width = Math.floor(this.cellWidth); // width is optional } else { cell.left = src.left || left; // left is optional cell.width = src.width || this.cellWidth; // width is optional } */ cell.breakBefore = lastEnd && lastEnd.ticks !== cell.start.ticks; lastEnd = cell.end; this.itline.push(cell); } } if (autoCellWidth) { this._updateHeaderGroupDimensions(); } } else { this.timeHeader = []; if (this.scale === "Manual") { this.itline = []; var left = 0; var lastEnd = null; for (var i = 0; i < this.timeline.length; i++) { var src = this.timeline[i]; /* if (src.width) { customWidth = true; } */ var cell = {}; cell.start = new DayPilot.Date(src.start); cell.end = src.end ? new DayPilot.Date(src.end) : cell.start.addMinutes(this.cellDuration); var w = src.width || this.cellWidth; var right = Math.floor(left + w); var width = right - Math.floor(left); cell.left = Math.floor(left); cell.width = width; left += w; // TODO custom width //cell.left = Math.floor(left); //cell.width = Math.floor(src.width || this.cellWidth); //cell.breakBefore = src.breakBefore; cell.breakBefore = lastEnd && lastEnd.ticks !== cell.start.ticks; lastEnd = cell.end; this.itline.push(cell); //left += cell.width; } } else { this._generateTimeline(); } //updateItlineForAutoCellWidth(); this._prepareHeaderGroups(); } }; this._generateTimeline = function() { var start = this.startDate; var end = this._addScaleSize(start); // var breakBefore = false; // groups var timeHeaders = this.timeHeaders; var left = 0; //var hrow = []; while (end.ticks <= this._endDate.ticks && end.ticks > start.ticks) { if (this._includeCell(start, end)) { var right = Math.floor(left + this.cellWidth); var width = right - Math.floor(left); var timeCell = {}; timeCell.start = start; timeCell.end = end; timeCell.left = Math.floor(left); timeCell.width = width; timeCell.breakBefore = breakBefore; this.itline.push(timeCell); left += this.cellWidth; breakBefore = false; } else { breakBefore = true; } start = end; end = this._addScaleSize(start); } }; this._updateHeaderGroupDimensions = function() { //calendar.debug.message("updateHeaderGroupDimensions"); if (!this.timeHeader) { return; } for (var y = 0; y < this.timeHeader.length; y++) { var row = this.timeHeader[y]; for (var x = 0; x < row.length; x++) { var h = row[x]; h.left = this.getPixels(new DayPilot.Date(h.start)).left; var right = this.getPixels(new DayPilot.Date(h.end)).left; var width = right - h.left; h.width = width; //calendar.debug.message("cell: " + h.start + "-" + h.end + " : left: " + h.left + " width:" + h.width); } } }; this._prepareHeaderGroups = function() { var timeHeaders = this.timeHeaders; if (!timeHeaders) { timeHeaders = [ {"groupBy": this.cellGroupBy}, {"groupBy": "Cell"} ]; } //var timeHeaders = this.timeHeaders; for (var i = 0; i < timeHeaders.length; i++) { var groupBy = timeHeaders[i].groupBy; var format = timeHeaders[i].format; if (groupBy === "Default") { groupBy = this.cellGroupBy; } //var start = this.startDate; var line = []; //var cell = {}; var start = this._visibleStart(); while (start.ticks < this._endDate.ticks) { var h = {}; h.start = start; h.end = this._addGroupSize(h.start, groupBy); if (h.start.ticks === h.end.ticks) { break; } h.left = this.getPixels(h.start).left; var right = this.getPixels(h.end).left; var width = right - h.left; h.width = width; h.colspan = Math.ceil(width / (1.0 * this.cellWidth)); if (format) { h.innerHTML = h.start.toString(format, resolved.locale()); } else { h.innerHTML = this._getGroupName(h, groupBy); } if (width > 0) { if (typeof this.onBeforeTimeHeaderRender === 'function') { var cell = {}; cell.start = h.start; cell.end = h.end; cell.html = h.innerHTML; cell.toolTip = h.innerHTML; //cell.color = null; cell.backColor = null; if (!this.cssOnly) { cell.backColor = this.hourNameBackColor; } cell.level = this.timeHeader.length; var args = {}; args.header = cell; this.onBeforeTimeHeaderRender(args); h.innerHTML = cell.html; h.backColor = cell.backColor; h.toolTip = cell.toolTip; } line.push(h); } start = h.end; } this.timeHeader.push(line); } }; this._includeCell = function(start, end) { if (typeof this.onIncludeTimeCell === 'function') { var cell = {}; cell.start = start; cell.end = end; cell.visible = true; var args = {}; args.cell = cell; this.onIncludeTimeCell(args); return cell.visible; } if (this.showNonBusiness) { return true; } return this.isBusiness({"start":start, "end":end}); /* if (start.d.getUTCDay() === 0) { // Sunday return false; } if (start.d.getUTCDay() === 6) { // Saturday return false; } var cellDuration = (end.getTime() - start.getTime()) / (1000 * 60); // minutes if (cellDuration < 60 * 24) { // cell is smaller than one day var startHour = start.d.getUTCHours(); startHour += start.d.getUTCMinutes() / 60.0; startHour += start.d.getUTCSeconds() / 3600.0; startHour += start.d.getUTCMilliseconds() / 3600000.0; if (startHour < this.businessBeginsHour) { return false; } if (this.businessEndsHour >= 24) { return true; } if (startHour >= this.businessEndsHour) { return false; } } return true; */ }; this.getPixels = function(date) { var ticks = date.ticks; var cache = this._cache.pixels[ticks]; if (cache) { return cache; } var previous = null; var previousEndTicks = 221876841600000; // December 31, 9000 if (this.itline.length === 0 || ticks < this.itline[0].start.ticks) { var result = {}; result.cut = false; result.left = 0; result.boxLeft = result.left; result.boxRight = result.left; result.i = null; // not in range return result; } //var thisone = date.toString() === "2014-05-01T00:00:00"; for (var i = 0; i < this.itline.length; i++) { var found = false; var cell = this.itline[i]; var cellStartTicks = cell.start.ticks; var cellEndTicks = cell.end.ticks; if (cellStartTicks < ticks && ticks < cellEndTicks) { // inside var offset = ticks - cellStartTicks; var result = {}; result.cut = false; result.left = cell.left + this._ticksToPixels(cell, offset); result.boxLeft = cell.left; result.boxRight = cell.left + cell.width; result.i = i; break; } else if (cellStartTicks === ticks) { // start var result = {}; result.cut = false; result.left = cell.left; result.boxLeft = result.left; result.boxRight = result.left + cell.width; result.i = i; break; } else if (cellEndTicks === ticks) { // end var result = {}; result.cut = false; result.left = cell.left + cell.width; result.boxLeft = result.left; result.boxRight = result.left; result.i = i + 1; break; } else if (ticks < cellStartTicks && ticks > previousEndTicks) { // hidden var result = {}; result.cut = true; result.left = cell.left; result.boxLeft = result.left; result.boxRight = result.left; result.i = i; break; } previousEndTicks = cellEndTicks; } if (!result) { var last = this.itline[this.itline.length - 1]; var result = {}; result.cut = true; result.left = last.left + last.width; result.boxLeft = result.left; result.boxRight = result.left; result.i = null; // not in range //this.log.c5 = this.log.c5 ? this.log.c5+1 : 1; } this._cache.pixels[ticks] = result; return result; }; // left - pixel offset from start // precise - true: calculates exact date from pixels, false: the it's the cell start // isEnd - returns the end of the previous cell // // isEnd and precise can't be combined this.getDate = function(left, precise, isEnd) { //var x = Math.floor(left / this.cellWidth); var position = this._getItlineCellFromPixels(left, isEnd); if (!position) { return null; } var x = position.x; var itc = this.itline[x]; if (!itc) { return null; } //var start = (isEnd && x > 0) ? this.itline[x - 1].end : this.itline[x].start; var start = (isEnd && !precise) ? itc.end : itc.start; if (!precise) { return start; } else { return start.addTime(this._pixelsToTicks(position.cell, position.offset)); } }; this._getItlineCellFromPixels = function(pixels, isEnd) { if (this.itline.length === 0) { return null; } var pos = 0; var previous = 0; for (var i = 0; i < this.itline.length; i++) { var cell = this.itline[i]; var width = cell.width || this.cellWidth; pos += width; if ((pixels < pos) || (isEnd && pixels === pos)) { var result = {}; result.x = i; result.offset = pixels - previous; result.cell = cell; return result; } previous = pos; } var cell = this.itline[this.itline.length - 1]; var result = {}; result.x = this.itline.length - 1; result.offset = cell.width || this.cellWidth; result.cell = cell; return result; }; this._getItlineCellFromTime = function(time) { var pos = new DayPilot.Date(time); //var previous = 0; for (var i = 0; i < this.itline.length; i++) { var cell = this.itline[i]; if (cell.start.ticks <= pos.ticks && pos.ticks < cell.end.ticks) { var result = {}; result.hidden = false; result.current = cell; return result; } if (pos.ticks < cell.start.ticks) // it's a hidden cell { var result = {}; result.hidden = true; result.previous = i > 0 ? this.itline[i - 1] : null; result.current = null; result.next = this.itline[i]; return result; } //pos = pos.addMinutes(1); } var result = {}; result.past = true; result.previous = this.itline[this.itline.length - 1]; return result; }; this._ticksToPixels = function(cell, ticks) { // DEBUG check that it's not used improperly (timeline) var width = cell.width || this.cellWidth; var duration = cell.end.ticks - cell.start.ticks; return Math.floor((width * ticks) / (duration)); }; this._pixelsToTicks = function(cell, pixels) { var duration = cell.end.ticks - cell.start.ticks; var width = cell.width || this.cellWidth; return Math.floor(pixels / width * duration ); }; this._onEventClick = function(ev) { if (touch.start) { return; } moving = {}; // clear calendar._eventClickDispatch(this, ev); }; this.eventClickPostBack = function(e, data) { this._postBack2('EventClick', e, data); }; this.eventClickCallBack = function(e, data) { this._callBack2('EventClick', e, data); }; this._eventClickDispatch = function(div, ev) { var e = div.event; var ev = ev || window.event; if (typeof (DayPilotBubble) !== 'undefined') { DayPilotBubble.hideActive(); } //if (calendar.eventDoubleClickHandling === 'Disabled') { if (!e.client.doubleClickEnabled()) { calendar._eventClickSingle(div, ev); return; } if (!calendar.timeouts.click) { calendar.timeouts.click = []; } var eventClickDelayed = function(div, ev) { return function() { calendar._eventClickSingle(div, ev); }; }; calendar.timeouts.click.push(window.setTimeout(eventClickDelayed(div, ev), calendar.doubleClickTimeout)); }; this._eventClickSingle = function(div, ev) { if (typeof ev === "boolean") { throw "Invalid _eventClickSingle parameters"; } var e = div.event; var ctrlKey = ev.ctrlKey; var metaKey = ev.metaKey; //var data = div.data; if (!e.client.clickEnabled()) { return; } if (calendar._api2()) { var args = {}; args.e = e; args.div = div; args.originalEvent = ev; args.ctrl = ctrlKey; args.meta = metaKey; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onEventClick === 'function') { calendar.onEventClick(args); if (args.preventDefault.value) { return; } } switch (calendar.eventClickHandling) { case 'PostBack': calendar.eventClickPostBack(e); break; case 'CallBack': calendar.eventClickCallBack(e); break; case 'Edit': calendar._divEdit(div); break; case 'Select': calendar._eventSelect(div, e, ctrlKey, metaKey); break; case 'ContextMenu': var menu = e.client.contextMenu(); if (menu) { menu.show(e); } else { if (calendar.contextMenu) { calendar.contextMenu.show(e); } } break; case 'Bubble': if (calendar.bubble) { calendar.bubble.showEvent(e); } break; case "RectangleSelect": if (calendar.multiSelectRectangle !== "Disabled") { rectangle.start(); return false; } break; } if (typeof calendar.onEventClicked === 'function') { calendar.onEventClicked(args); } } else { switch (calendar.eventClickHandling) { case 'PostBack': calendar.eventClickPostBack(e); break; case 'CallBack': calendar.eventClickCallBack(e); break; case 'JavaScript': calendar.onEventClick(e); break; case 'Edit': calendar._divEdit(div); break; case 'Select': calendar._eventSelect(div, e, ctrlKey, metaKey); break; case 'ContextMenu': var menu = e.client.contextMenu(); if (menu) { menu.show(e); } else { if (calendar.contextMenu) { calendar.contextMenu.show(e); } } break; case 'Bubble': if (calendar.bubble) { calendar.bubble.showEvent(e); } break; case "RectangleSelect": if (calendar.multiSelectRectangle !== "Disabled") { rectangle.start(); return false; } break; } } }; this._eventDeleteDispatch = function(e) { if (calendar._api2()) { var args = {}; args.e = e; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onEventDelete === 'function') { calendar.onEventDelete(args); if (args.preventDefault.value) { return; } } switch (calendar.eventDeleteHandling) { case 'PostBack': calendar.eventDeletePostBack(e); break; case 'CallBack': calendar.eventDeleteCallBack(e); break; case 'Update': calendar.events.remove(e); break; } if (typeof calendar.onEventDeleted === 'function') { calendar.onEventDeleted(args); } } else { switch (calendar.eventDeleteHandling) { case 'PostBack': calendar.eventDeletePostBack(e); break; case 'CallBack': calendar.eventDeleteCallBack(e); break; case 'JavaScript': calendar.onEventDelete(e); break; } } }; this.eventDeletePostBack = function(e, data) { this._postBack2('EventDelete', e, data); }; this.eventDeleteCallBack = function(e, data) { this._callBack2('EventDelete', e, data); }; // obsolete this.setHScrollPosition = function(pixels) { this.nav.scroll.scrollLeft = pixels; }; this.getScrollX = function() { return this.nav.scroll.scrollLeft; }; // obsolete this.getHScrollPosition = this.getScrollX; this.getScrollY = function() { return this.nav.scroll.scrollTop; }; this._eventSelect = function(div, e, ctrlKey, metaKey) { calendar._eventSelectDispatch(div, e, ctrlKey, metaKey); }; this.eventSelectPostBack = function(e, change, data) { var params = {}; params.e = e; params.change = change; this._postBack2('EventSelect', params, data); }; this.eventSelectCallBack = function(e, change, data) { var params = {}; params.e = e; params.change = change; this._callBack2('EventSelect', params, data); }; this._eventSelectDispatch = function(div, e, ctrlKey, metaKey) { //var e = this.selectedEvent(); var m = calendar.multiselect; var allowDeselect = false; var isSelected = m.isSelected(e); var ctrlOrMeta = ctrlKey || metaKey; if (!ctrlOrMeta && isSelected && !allowDeselect && m.list.length === 1) { return; } if (calendar._api2()) { m.previous = m.events(); var args = {}; args.e = e; args.selected = isSelected; args.ctrl = ctrlKey; args.meta = metaKey; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onEventSelect === 'function') { calendar.onEventSelect(args); if (args.preventDefault.value) { return; } } switch (calendar.eventSelectHandling) { case 'PostBack': calendar.eventSelectPostBack(e, change); break; case 'CallBack': if (typeof WebForm_InitCallback !== 'undefined') { window.__theFormPostData = ""; window.__theFormPostCollection = []; WebForm_InitCallback(); } calendar.eventSelectCallBack(e, change); break; case 'Update': m._toggleDiv(div, ctrlKey, metaKey); break; } if (typeof calendar.onEventSelected === 'function') { args.change = m.isSelected(e) ? "selected" : "deselected"; args.selected = m.isSelected(e); calendar.onEventSelected(args); } } else { m.previous = m.events(); m._toggleDiv(div, ctrlKey, metaKey); var change = m.isSelected(e) ? "selected" : "deselected"; switch (calendar.eventSelectHandling) { case 'PostBack': calendar.eventSelectPostBack(e, change); break; case 'CallBack': if (typeof WebForm_InitCallback !== 'undefined') { window.__theFormPostData = ""; window.__theFormPostCollection = []; WebForm_InitCallback(); } calendar.eventSelectCallBack(e, change); break; case 'JavaScript': calendar.onEventSelect(e, change); break; } } }; this.eventRightClickPostBack = function(e, data) { this._postBack2('EventRightClick', e, data); }; this.eventRightClickCallBack = function(e, data) { this._callBack2('EventRightClick', e, data); }; this._eventRightClickDispatch = function(ev) { var e = this.event; ev = ev || window.event; ev.cancelBubble = true; if (!this.event.client.rightClickEnabled()) { return false; } if (calendar._api2()) { var args = {}; args.e = e; args.div = this; args.originalEvent = ev; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onEventRightClick === 'function') { calendar.onEventRightClick(args); if (args.preventDefault.value) { return; } } switch (calendar.eventRightClickHandling) { case 'PostBack': calendar.eventRightClickPostBack(e); break; case 'CallBack': calendar.eventRightClickCallBack(e); break; case 'ContextMenu': var menu = e.client.contextMenu(); if (menu) { menu.show(e); } else { if (calendar.contextMenu) { calendar.contextMenu.show(this.event); } } break; case 'Bubble': if (calendar.bubble) { calendar.bubble.showEvent(e); } break; } if (typeof calendar.onEventRightClicked === 'function') { calendar.onEventRightClicked(args); } } else { switch (calendar.eventRightClickHandling) { case 'PostBack': calendar.eventRightClickPostBack(e); break; case 'CallBack': calendar.eventRightClickCallBack(e); break; case 'JavaScript': calendar.onEventRightClick(e); break; case 'ContextMenu': var menu = e.client.contextMenu(); if (menu) { menu.show(e); } else { if (calendar.contextMenu) { calendar.contextMenu.show(this.event); } } break; case 'Bubble': if (calendar.bubble) { calendar.bubble.showEvent(e); } break; } } return false; }; this.eventDoubleClickPostBack = function(e, data) { this._postBack2('EventDoubleClick', e, data); }; this.eventDoubleClickCallBack = function(e, data) { this._callBack2('EventDoubleClick', e, data); }; this._eventDoubleClickDispatch = function(ev) { if (typeof (DayPilotBubble) !== 'undefined') { DayPilotBubble.hideActive(); } if (calendar.timeouts.click) { for (var toid in calendar.timeouts.click) { window.clearTimeout(calendar.timeouts.click[toid]); } calendar.timeouts.click = null; } var ev = ev || window.event; var e = this.event; ev.stopPropagation && ev.stopPropagation(); ev.cancelBubble = true; if (calendar._api2()) { var args = {}; args.e = e; args.originalEvent = ev; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onEventDoubleClick === 'function') { calendar.onEventDoubleClick(args); if (args.preventDefault.value) { return; } } switch (calendar.eventDoubleClickHandling) { case 'PostBack': calendar.eventDoubleClickPostBack(e); break; case 'CallBack': calendar.eventDoubleClickCallBack(e); break; case 'Edit': calendar._divEdit(this); break; case 'Select': calendar._eventSelect(div, e, ev.ctrlKey, ev.metaKey); break; case 'Bubble': if (calendar.bubble) { calendar.bubble.showEvent(e); } break; case 'ContextMenu': var menu = e.client.contextMenu(); if (menu) { menu.show(e); } else { if (calendar.contextMenu) { calendar.contextMenu.show(e); } } break; } if (typeof calendar.onEventDoubleClicked === 'function') { calendar.onEventDoubleClicked(args); } } else { switch (calendar.eventDoubleClickHandling) { case 'PostBack': calendar.eventDoubleClickPostBack(e); break; case 'CallBack': calendar.eventDoubleClickCallBack(e); break; case 'JavaScript': calendar.onEventDoubleClick(e); break; case 'Edit': calendar._divEdit(this); break; case 'Select': calendar._eventSelect(div, e, ev.ctrlKey, ev.metaKey); break; case 'Bubble': if (calendar.bubble) { calendar.bubble.showEvent(e); } break; case 'ContextMenu': var menu = e.client.contextMenu(); if (menu) { menu.show(e); } else { if (calendar.contextMenu) { calendar.contextMenu.show(e); } } break; } } }; this.eventResizePostBack = function(e, newStart, newEnd, data) { this._invokeEventResize("PostBack", e, newStart, newEnd, data); }; this.eventResizeCallBack = function(e, newStart, newEnd, data) { this._invokeEventResize("CallBack", e, newStart, newEnd, data); }; this._invokeEventResize = function(type, e, newStart, newEnd, data) { var params = {}; params.e = e; params.newStart = newStart; params.newEnd = newEnd; this._invokeEvent(type, "EventResize", params, data); }; this._eventResizeDispatch = function(e, newStart, newEnd) { if (this.eventResizeHandling === 'Disabled') { return; } newEnd = calendar._adjustEndOut(newEnd); if (calendar._api2()) { // API v2 var args = {}; args.e = e; args.newStart = newStart; args.newEnd = newEnd; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onEventResize === 'function') { calendar.onEventResize(args); if (args.preventDefault.value) { return; } newStart = args.newStart; newEnd = args.newEnd; } switch (calendar.eventResizeHandling) { case 'PostBack': calendar.eventResizePostBack(e, newStart, newEnd); break; case 'CallBack': calendar.eventResizeCallBack(e, newStart, newEnd); break; case 'Notify': calendar.eventResizeNotify(e, newStart, newEnd); break; case 'Update': //newEnd = calendar._adjustEndIn(newEnd); e.start(newStart); e.end(newEnd); calendar.events.update(e); break; } if (typeof calendar.onEventResized === 'function') { calendar.onEventResized(args); } } else { switch (calendar.eventResizeHandling) { case 'PostBack': //newEnd = calendar._adjustEndOut(newEnd); calendar.eventResizePostBack(e, newStart, newEnd); break; case 'CallBack': //newEnd = calendar._adjustEndOut(newEnd); calendar.eventResizeCallBack(e, newStart, newEnd); break; case 'JavaScript': //newEnd = calendar._adjustEndOut(newEnd); calendar.onEventResize(e, newStart, newEnd); break; case 'Notify': //newEnd = calendar._adjustEndOut(newEnd); calendar.eventResizeNotify(e, newStart, newEnd); break; case 'Update': e.start(newStart); e.end(newEnd); calendar.events.update(e); break; } } }; this.eventMovePostBack = function(e, newStart, newEnd, newResource, data, line) { this._invokeEventMove("PostBack", e, newStart, newEnd, newResource, data, line); }; this.eventMoveCallBack = function(e, newStart, newEnd, newResource, data, line) { this._invokeEventMove("CallBack", e, newStart, newEnd, newResource, data, line); }; this._invokeEventMove = function(type, e, newStart, newEnd, newResource, data, line) { var usesArgs = e && !!e.preventDefault; var params = {}; if (usesArgs) { var args = e; params.e = args.e; params.newStart = args.newStart; params.newEnd = args.newEnd; params.newResource = args.newResource; params.position = args.position; params.multimove = []; args.multimove.each(function(item) { var mmp = {}; mmp.e = item.event; mmp.newStart = item.start; mmp.newEnd = item.end; mmp.newResource = item.event.resource(); if (mmp.e === args.e || mmp.e.data.id == args.e.data.id) { mmp.newResource = args.newResource; } else if (mm.rowoffset) { var ri = item.event.part.dayIndex + mm.rowoffset; mmp.newResource = calendar.rowlist[ri].id; } params.multimove.push(mmp); }); } else { params.e = e; params.newStart = newStart; params.newEnd = newEnd; params.newResource = newResource; params.position = line; } this._invokeEvent(type, "EventMove", params, data); }; this._invokeTimeRangeSelected = function(type, args, data) { var params = {}; params.start = args.start; params.end = args.end; params.resource = args.resource; params.multirange = []; args.multirange.each(function(item) { var mrp = {}; mrp.start = item.start; mrp.end = item.end; mrp.resource = item.resource; params.multirange.push(mrp); }); this._invokeEvent(type, "TimeRangeSelected", params, data); }; this._invokeEvent = function(type, action, params, data) { if (type === 'PostBack') { calendar._postBack2(action, params, data); } else if (type === 'CallBack') { calendar._callBack2(action, params, data, "CallBack"); } else if (type === 'Immediate') { calendar._callBack2(action, params, data, "Notify"); } else if (type === 'Queue') { calendar.queue.add(new DayPilot.Action(this, action, params, data)); } else if (type === 'Notify') { if (resolved.notifyType() === 'Notify') { calendar._callBack2(action, params, data, "Notify"); } else { calendar.queue.add(new DayPilot.Action(calendar, action, params, data)); } } else { throw "Invalid event invocation type"; } }; this.eventMoveNotify = function(e, newStart, newEnd, newResource, data, line) { var usesArgs = e && !!e.preventDefault; if (usesArgs) { var args = e; args.old = new DayPilot.Event(args.e.copy(), calendar); args.multimove.each(function(item) { item.old = new DayPilot.Event(item.event.copy(), calendar); }); calendar._doEventMoveUpdate(args); args.e = args.old; delete args.old; args.multimove.each(function(item) { item.event = item.old; delete item.old; }); } else { e = new DayPilot.Event(e.copy(), calendar); var rows = calendar.events._removeFromRows(e.data); e.start(newStart); e.end(newEnd); e.resource(newResource); e.commit(); rows = rows.concat(calendar.events._addToRows(e.data)); calendar._loadRows(rows); calendar._updateRowHeights(); calendar._updateRowsNoLoad(rows); } this._invokeEventMove("Notify", e, newStart, newEnd, newResource, data, line); }; this.eventResizeNotify = function(e, newStart, newEnd, data) { var old = new DayPilot.Event(e.copy(), this); var rows = calendar.events._removeFromRows(e.data); e.start(newStart); e.end(newEnd); e.commit(); rows = rows.concat(calendar.events._addToRows(e.data)); calendar._loadRows(rows); calendar._updateRowHeights(); calendar._updateRowsNoLoad(rows); this._invokeEventResize("Notify", old, newStart, newEnd, data); }; // internal methods for handling event selection this.multiselect = {}; this.multiselect.list = []; this.multiselect.divs = []; this.multiselect.previous = []; this.multiselect._loadList = function(list) { calendar.multiselect.list = DayPilot.list(list).map(function(item) { return new DayPilot.Event(item, calendar); }); }; this.multiselect._serialize = function() { var m = calendar.multiselect; return DayPilot.JSON.stringify(m.events()); }; this.multiselect.events = function() { var m = calendar.multiselect; var events = DayPilot.list(); events.ignoreToJSON = true; for (var i = 0; i < m.list.length; i++) { events.push(m.list[i]); } return events; }; this.multiselect._updateHidden = function() { // not implemented }; this.multiselect._toggleDiv = function(div, ctrl, meta) { var m = calendar.multiselect; if (m.isSelected(div.event)) { if (calendar.allowMultiSelect) { if (ctrl || meta) { m.remove(div.event, true); } else { var count = m.list.length; m.clear(); if (count > 1) { m.add(div.event, true); } } } else { // clear all m.clear(); } } else { if (calendar.allowMultiSelect) { if (ctrl || meta) { m.add(div.event, true); } else { m.clear(); m.add(div.event, true); } } else { m.clear(); m.add(div.event, true); } } //m.redraw(); m._update(div); m._updateHidden(); }; // compare event with the init select list this.multiselect._shouldBeSelected = function(ev) { var m = calendar.multiselect; return m._isInList(ev, m.initList); }; this.multiselect._alert = function() { var m = calendar.multiselect; var list = []; for (var i = 0; i < m.list.length; i++) { var event = m.list[i]; list.push(event.value()); } alert(list.join("\n")); }; this.multiselect.add = function(ev, dontRedraw) { var m = calendar.multiselect; if (m.indexOf(ev) === -1) { m.list.push(ev); } if (dontRedraw) { return; } m.redraw(); }; this.multiselect.remove = function(ev, dontRedraw) { var m = calendar.multiselect; var i = m.indexOf(ev); if (i !== -1) { m.list.splice(i, 1); } if (dontRedraw) { return; } m.redraw(); }; this.multiselect.clear = function(dontRedraw) { var m = calendar.multiselect; m.list = []; if (dontRedraw) { return; } m.redraw(); }; this.multiselect.redraw = function() { var m = calendar.multiselect; m.divs = []; for (var i = 0; i < calendar.elements.events.length; i++) { var div = calendar.elements.events[i]; if (!div.event) { continue; } if (!div.event.isEvent) { continue; } if (m.isSelected(div.event)) { m._divSelect(div); } else { m._divDeselect(div); } } }; /* this.multiselect._redrawForRow = function(i) { }; */ // not used this.multiselect._updateEvent = function(ev) { var m = calendar.multiselect; var div = null; for (var i = 0; i < calendar.elements.events.length; i++) { if (m.isSelected(calendar.elements.events[i].event)) { div = calendar.elements.events[i]; break; } } m._update(div); }; // used for faster redraw this.multiselect._update = function(div) { if (!div) { return; } var m = calendar.multiselect; if (m.isSelected(div.event)) { m._divSelect(div); } else { m._divDeselect(div); } }; this.multiselect._divSelect = function(div) { var m = calendar.multiselect; var cn = calendar.cssOnly ? calendar._prefixCssClass("_selected") : calendar._prefixCssClass("selected"); var div = m._findContentDiv(div); DayPilot.Util.addClass(div, cn); m.divs.push(div); }; this.multiselect._findContentDiv = function(div) { return div; }; this.multiselect._divDeselectAll = function() { var m = calendar.multiselect; for (var i = 0; i < m.divs.length; i++) { var div = m.divs[i]; m._divDeselect(div, true); } m.divs = []; }; this.multiselect._divDeselect = function(div, dontRemoveFromCache) { var m = calendar.multiselect; var cn = calendar.cssOnly ? calendar._prefixCssClass("_selected") : calendar._prefixCssClass("selected"); DayPilot.Util.removeClass(div, cn); if (dontRemoveFromCache) { return; } var i = DayPilot.indexOf(m.divs, div); if (i !== -1) { m.divs.splice(i, 1); } }; this.multiselect.isSelected = function(ev) { if (!ev) { return false; } if (!ev.isEvent) { return false; } return calendar.multiselect._isInList(ev, calendar.multiselect.list); }; this.multiselect.indexOf = function(ev) { //return DayPilot.indexOf(calendar.multiselect.list, ev); var data = ev.data; for (var i = 0; i < calendar.multiselect.list.length; i++) { var item = calendar.multiselect.list[i]; if (item.data === data) { return i; } } return -1; }; this.multiselect._isInList = function(e, list) { if (!list) { return false; } for (var i = 0; i < list.length; i++) { var ei = list[i]; if (e === ei) { return true; } if (typeof ei.id === 'function') { if (ei.id() !== null && e.id() !== null && ei.id() === e.id()) { return true; } if (ei.id() === null && e.id() === null && ei.recurrentMasterId() === e.recurrentMasterId() && e.start().toStringSortable() === ei.start().toStringSortable()) { return true; } } else { if (ei.id !== null && e.id() !== null && ei.id === e.id()) { return true; } if (ei.id === null && e.id() === null && ei.recurrentMasterId === e.recurrentMasterId() && e.start().toStringSortable() === ei.start) { return true; } } } return false; }; this.multiselect.startRectangle = function() { rectangle.start(); }; this._update = function(args) { var args = args || {}; var full = !args.eventsOnly; if (!calendar.cssOnly) { calendar.cssOnly = true; DayPilot.Util.log("DayPilot: cssOnly = false mode is not supported since DayPilot Pro 8.0.") } if (full) { if (!this._serverBased()) { calendar.timeHeader = null; calendar.cellProperties = {}; } calendar._calculateCellWidth(); calendar._prepareItline(); if (!args || !args.dontLoadResources) { calendar._loadResources(); } } this._loadEvents(); if (full) { calendar._updateCorner(); calendar._drawResHeader(); calendar._drawTimeHeader(); } calendar._prepareRowTops(); calendar._updateRowHeaderHeights(); calendar._updateRowHeaderWidth(); calendar._updateHeaderHeight(); linktools.hideLinkpoints(); this._deleteEvents(); this._deleteSeparators(); this._deleteCells(); this._clearCachedValues(); this._expandCellProperties(); this._drawCells(); this._drawSeparators(); calendar._updateHeight(); if (args.immediateEvents || args.eventsOnly) { calendar._drawEvents(); } else { setTimeout(function() { calendar._drawEvents(); }, 100); } if (!DayPilot.list(calendar.multiselect.list).isEmpty()) { this.multiselect.redraw(); } /* if (DayPilot.isArray(calendar.multiselect.list) && calendar.multiselect.list.length > 0) { this.multiselect.redraw(); } */ if (this.visible) { this.show(); } else { this.hide(); } this._updateFloats(); this._onScroll(); }; // full update this.update = function() { this._update({"immediateEvents":true}); }; this._updateRowsNoLoad = function(rows, appendOnlyIfPossible, finishedCallBack) { //var start, end; rows = DayPilot.ua(rows); for (var i = 0; i < rows.length; i++) { var ri = rows[i]; calendar._drawRowForced(ri); } //calendar.debug.message("updateRowsNoLoad/rowsDirty: " + this._rowsDirty); if (this._rowsDirty) { this._prepareRowTops(); this._updateRowHeaderHeights(); this._deleteCells(); this._deleteSeparators(); for (var i = 0; i < rows.length; i++) { var ri = rows[i]; this._deleteEventsInRow(ri); } for (var i = 0; i < rows.length; i++) { var ri = rows[i]; this._drawEventsInRow(ri); } this._drawCells(); this._drawSeparators(); this._updateEventTops(); } else { var batch = true; if (batch) { var doRow = function(i) { if (i >= rows.length) { return; } var ri = rows[i]; if (!appendOnlyIfPossible) { calendar._deleteEventsInRow(ri); } calendar._drawEventsInRow(ri); if (i + 1 < rows.length) { setTimeout(function() { doRow(i+1); }, 10); } else { calendar._findEventsInViewPort(); linktools.load(); calendar.multiselect.redraw(); if (finishedCallBack) { finishedCallBack(); } } }; doRow(0); } else { for (var i = 0; i < rows.length; i++) { var ri = rows[i]; if (!appendOnlyIfPossible) { this._deleteEventsInRow(ri); } this._drawEventsInRow(ri); } } DayPilot.list(rows).each(function(y) { //calendar.debug.message("deleting row: " + y); calendar._deleteCellsInRow(y); }); calendar._drawCells(); } calendar._findEventsInViewPort(); linktools.load(); calendar.multiselect.redraw(); if (finishedCallBack) { finishedCallBack(); } this._clearCachedValues(); }; this._adjustEndOut = function(date) { if (calendar.eventEndSpec === "DateTime") { return date; } if (date.getDatePart().ticks === date.ticks) { return date.addDays(-1); } return date.getDatePart(); }; this._adjustEndIn = function(date) { if (calendar.eventEndSpec === "DateTime") { return date; } return date.getDatePart().addDays(1); }; this._adjustEndNormalize = function(date) { if (calendar.eventEndSpec === "DateTime") { return date; } return date.getDatePart(); }; this._eventMoveDispatch = function(e, newStart, newEnd, newResource, external, ev, line) { if (calendar.eventMoveHandling === 'Disabled') { return; } newEnd = calendar._adjustEndOut(newEnd); var args = {}; args.e = e; args.newStart = newStart; args.newEnd = newEnd; args.newResource = newResource; args.external = external; args.ctrl = false; args.meta = false; args.shift = false; if (ev) { args.shift = ev.shiftKey; args.ctrl = ev.ctrlKey; args.meta = ev.metaKey; } args.multimove = DayPilot.list(mm.list); var info = {}; info.event = e; info.start = newStart; info.end = newEnd; //info.overlapping = false; // always false, this event is not fired if overlapping is forbidden args.multimove.splice(0, 0, info); args.position = line; args.preventDefault = function() { this.preventDefault.value = true; }; if (calendar._api2()) { // API v2 if (typeof calendar.onEventMove === 'function') { calendar.onEventMove(args); if (args.preventDefault.value) { return; } newStart = args.newStart; newEnd = args.newEnd; } switch (calendar.eventMoveHandling) { case 'PostBack': calendar.eventMovePostBack(args); break; case 'CallBack': calendar.eventMoveCallBack(args); // e, newStart, newEnd, newResource, null, line break; case 'Notify': calendar.eventMoveNotify(args); break; case 'Update': //newEnd = calendar._adjustEndIn(newEnd); calendar._doEventMoveUpdate(args); break; } if (typeof calendar.onEventMoved === 'function') { calendar.onEventMoved(args); } } else { switch (calendar.eventMoveHandling) { case 'PostBack': calendar.eventMovePostBack(args); break; case 'CallBack': calendar.eventMoveCallBack(args); break; case 'JavaScript': calendar.onEventMove(e, newStart, newEnd, newResource, external, ev ? ev.ctrlKey : false, ev ? ev.shiftKey : false, line); break; case 'Notify': calendar.eventMoveNotify(args); break; case 'Update': calendar._doEventMoveUpdate(args); /* e.start(newStart); e.end(newEnd); e.resource(newResource); calendar.events.update(e);*/ break; } } }; this._doEventMoveUpdate = function(args) { var e = args.e; var newStart = args.newStart; var newEnd = args.newEnd; var newResource = args.newResource; var external = args.external; e.start(newStart); e.end(newEnd); e.resource(newResource); if (external) { e.commit(); calendar.events.add(e); } else { calendar.events.update(e); } if (!args.multimove.isEmpty()) { args.multimove.each(function(item) { if (item.event === e) { // skip the main event return; } item.event.start(item.start); item.event.end(item.end); if (mm.rowoffset) { var ri = item.event.part.dayIndex + mm.rowoffset; var newResource = calendar.rowlist[ri].id; item.event.resource(newResource); } item.event.commit(); calendar.events.update(item.event); }); } calendar._deleteDragSource(); }; this._bubbleCallBack = function(args, bubble) { var guid = calendar._recordBubbleCall(bubble); var params = {}; params.args = args; params.guid = guid; calendar._callBack2("Bubble", params); }; this._recordBubbleCall = function(bubble) { var guid = DayPilot.guid(); if (!this.bubbles) { this.bubbles = []; } this.bubbles[guid] = bubble; return guid; }; this.eventMenuClickPostBack = function(e, command, data) { var params = {}; params.e = e; params.command = command; this._postBack2('EventMenuClick', params, data); }; this.eventMenuClickCallBack = function(e, command, data) { var params = {}; params.e = e; params.command = command; this._callBack2('EventMenuClick', params, data); }; this._eventMenuClick = function(command, e, handling) { switch (handling) { case 'PostBack': calendar.eventMenuClickPostBack(e, command); break; case 'CallBack': calendar.eventMenuClickCallBack(e, command); break; } }; this.timeRangeSelectedPostBack = function(start, end, resource, data) { var range = {}; range.start = start; range.end = end; range.resource = resource; this._postBack2('TimeRangeSelected', range, data); }; this.timeRangeSelectedCallBack = function(start, end, resource, data) { var range = {}; range.start = start; range.end = end; range.resource = resource; this._callBack2('TimeRangeSelected', range, data); }; this._timeRangeSelectedDispatchFromRange = function(range) { if (!range) { return; } if (range.disabled) { calendar.clearSelection(); return; } var sel = calendar._getSelection(range); if (!sel) { return; } calendar._timeRangeSelectedDispatch(sel.start, sel.end, sel.resource); }; this._timeRangeSelectedDispatch = function(start, end, resource) { if (calendar.timeRangeSelectedHandling === 'Disabled') { return; } var rawend = end; end = calendar._adjustEndOut(rawend); var args = {}; args.start = start; args.end = end; args.resource = resource; args.preventDefault = function () { this.preventDefault.value = true; }; args.multirange = DayPilot.list(mr.list).map(function (item) { return calendar._getSelection(item); }); if (args.multirange.isEmpty()) { args.multirange.push({"start": args.start, "end": args.end, "resource": args.resource}); } if (calendar._api2()) { if (typeof calendar.onTimeRangeSelect === 'function') { calendar.onTimeRangeSelect(args); if (args.preventDefault.value) { return; } start = args.start; end = args.end; } calendar._updateRange(DayPilotScheduler.rangeHold, start, end, args.multirange); calendar._drawRange(DayPilotScheduler.rangeHold, true); // now perform the default built-in action switch (calendar.timeRangeSelectedHandling) { case 'PostBack': calendar._invokeTimeRangeSelected("PostBack", args); break; case 'CallBack': calendar._invokeTimeRangeSelected("CallBack", args); break; } if (typeof calendar.onTimeRangeSelected === 'function') { calendar.onTimeRangeSelected(args); } } else { switch (calendar.timeRangeSelectedHandling) { case 'PostBack': calendar._invokeTimeRangeSelected("PostBack", args); break; case 'CallBack': calendar._invokeTimeRangeSelected("CallBack", args); break; case 'JavaScript': calendar.onTimeRangeSelected(start, end, resource, args.multirange); break; case 'Hold': break; } } }; this._updateRange = function(range, start, end, multirange) { //var range = DayPilotScheduler.rangeHold; if (!range || (multirange && multirange.length > 1)) { return; } var rawend = calendar._adjustEndIn(end); var itc, cell; var rowOffset = 0; if (calendar.viewType === "Days") { var row = calendar._findRowInDaysView(start); rowOffset = row.start.getTime() - calendar.startDate.getTime(); } // fix start if (start.getTime() < calendar.itline[0].start.getTime()) { range.start.x = 0; } else { itc = calendar._getItlineCellFromTime(start.addTime(-rowOffset)); cell = itc.current || itc.previous; range.start.x = DayPilot.indexOf(calendar.itline, cell); } // fix end itc = calendar._getItlineCellFromTime(rawend.addMilliseconds(-1).addTime(-rowOffset)); if (itc.past) { range.end.x = calendar.itline.length - 1; } else { cell = itc.current || itc.next; range.end.x = DayPilot.indexOf(calendar.itline, cell); } }; this._findRowInDaysView = function(start) { // inefficient var day = start.getDatePart().getTime(); for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; var rs = row.start.getTime(); if (rs === day) { return row; } } }; this.timeRangeDoubleClickPostBack = function(start, end, resource, data) { var range = {}; range.start = start; range.end = end; range.resource = resource; this._postBack2('TimeRangeDoubleClick', range, data); }; this.timeRangeDoubleClickCallBack = function(start, end, resource, data) { var range = {}; range.start = start; range.end = end; range.resource = resource; this._callBack2('TimeRangeDoubleClick', range, data); }; this._timeRangeDoubleClickDispatch = function(start, end, resource) { end = calendar._adjustEndOut(end); if (calendar._api2()) { var args = {}; args.start = start; args.end = end; args.resource = resource; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onTimeRangeDoubleClick === 'function') { calendar.onTimeRangeDoubleClick(args); if (args.preventDefault.value) { return; } } switch (calendar.timeRangeDoubleClickHandling) { case 'PostBack': calendar.timeRangeDoubleClickPostBack(start, end, resource); break; case 'CallBack': calendar.timeRangeDoubleClickCallBack(start, end, resource); break; } if (typeof calendar.onTimeRangeDoubleClicked === 'function') { calendar.onTimeRangeDoubleClicked(args); } } else { //end = calendar._adjustEndOut(end); switch (calendar.timeRangeDoubleClickHandling) { case 'PostBack': calendar.timeRangeDoubleClickPostBack(start, end, resource); break; case 'CallBack': calendar.timeRangeDoubleClickCallBack(start, end, resource); break; case 'JavaScript': calendar.onTimeRangeDoubleClick(start, end, resource); break; } } }; this.timeRangeMenuClickPostBack = function(e, command, data) { var params = {}; params.selection = e; params.command = command; this._postBack2("TimeRangeMenuClick", params, data); }; this.timeRangeMenuClickCallBack = function(e, command, data) { var params = {}; params.selection = e; params.command = command; this._callBack2("TimeRangeMenuClick", params, data); }; this._timeRangeMenuClick = function(command, e, handling) { switch (handling) { case 'PostBack': calendar.timeRangeMenuClickPostBack(e, command); break; case 'CallBack': calendar.timeRangeMenuClickCallBack(e, command); break; } }; this.linkMenuClickPostBack = function(e, command, data) { var params = {}; params.link = e; params.command = command; this._postBack2("LinkMenuClick", params, data); }; this.linkMenuClickCallBack = function(e, command, data) { var params = {}; params.link = e; params.command = command; this._callBack2("LinkMenuClick", params, data); }; this._linkMenuClick = function(command, e, handling) { switch (handling) { case 'PostBack': calendar.linkMenuClickPostBack(e, command); break; case 'CallBack': calendar.linkMenuClickCallBack(e, command); break; } }; this.rowMenuClickPostBack = function(e, command, data) { var params = {}; params.resource = e; params.command = command; this._postBack2("RowMenuClick", params, data); }; // backwards compatibility this.resourceHeaderMenuClickPostBack = this.rowMenuClickPostBack; this.rowMenuClickCallBack = function(e, command, data) { var params = {}; params.resource = e; params.command = command; this._callBack2("RowMenuClick", params, data); }; this.resourceHeaderMenuClickCallBack = this.rowMenuClickCallBack; this._rowMenuClick = function(command, e, handling) { switch (handling) { case 'PostBack': calendar.rowMenuClickPostBack(e, command); break; case 'CallBack': calendar.rowMenuClickCallBack(e, command); break; } }; this._rowUpdateText = function (row, newText) { var r = rowtools._findTableRow(row); var c = r.cells[0]; var text = c.textDiv; text.innerHTML = newText; row.Text = newText; row.html = newText; }; this._rowCreateDispatch = function(row, newText) { if (!newText) { return; } var args = {}; args.text = newText; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onRowCreate === "function") { calendar.onRowCreate(args); if (args.preventDefault.value) { return; } } switch (calendar.rowCreateHandling) { case "CallBack": calendar.rowCreateCallBack(args.text); break; case "PostBack": calendar.rowCreatePostBack(args.text); break; } if (typeof calendar.onRowCreated === "function") { calendar.onRowCreated(args); } }; this._rowEditDispatch = function(row, newText) { if (row.isNewRow) { calendar._rowCreateDispatch(row, newText); return; } var index = DayPilot.indexOf(calendar.rowlist, row); var e = calendar._createRowObject(row, index); if (calendar._api2()) { var args = {}; args.resource = e; args.newText = newText; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onRowEdit === 'function') { calendar.onRowEdit(args); if (args.preventDefault.value) { return; } } switch (calendar.rowEditHandling) { case 'PostBack': calendar.rowEditPostBack(e, newText); break; case 'CallBack': calendar.rowEditCallBack(e, newText); break; case 'Update': calendar._rowUpdateText(row, newText); break; } if (typeof calendar.onRowEdited === 'function') { calendar.onRowEdited(args); } } else { switch (calendar.rowEditHandling) { case 'PostBack': calendar.rowEditPostBack(e, newText); break; case 'CallBack': calendar.rowEditCallBack(e, newText); break; case 'JavaScript': calendar.onrowEdit(e, newText); break; } } }; this.rowCreatePostBack = function(newText, data) { var params = {}; params.text = newText; this._postBack2("RowCreate", params, data); }; this.rowCreateCallBack = function(newText, data) { var params = {}; params.text = newText; this._callBack2("RowCreate", params, data); }; this.rowEditPostBack = function(e, newText, data) { var params = {}; params.resource = e; params.newText = newText; this._postBack2("RowEdit", params, data); }; this.rowEditCallBack = function(e, newText, data) { var params = {}; params.resource = e; params.newText = newText; this._callBack2("RowEdit", params, data); }; this.rowMovePostBack = function(source, target, position, data) { var params = {}; params.source = source; params.target = target; params.position = position; this._postBack2("RowMove", params, data); }; this.rowMoveCallBack = function(source, target, position, data) { var params = {}; params.source = source; params.target = target; params.position = position; this._callBack2("RowMove", params, data); }; this.rowMoveNotify = function(source, target, position, data) { var params = {}; params.source = source; params.target = target; params.position = position; this._callBack2("RowMove", params, data, "Notify"); }; this.rowClickPostBack = function(e, data) { var params = {}; params.resource = e; this._postBack2("RowClick", params, data); }; // backwards compatibility this.resourceHeaderClickPostBack = this.rowClickPostBack; this.rowClickCallBack = function(e, data) { var params = {}; params.resource = e; this._callBack2("RowClick", params, data); }; // backwards compatibility this.resourceHeaderClickCallBack = this.rowClickCallBack; this._rowClickDispatch = function(e, ctrl, shift, meta) { if (calendar.rowDoubleClickHandling === "Disabled") { calendar._rowClickSingle(e, ctrl, shift, meta); return; } if (!calendar.timeouts.resClick) { calendar.timeouts.resClick = []; } var resClickDelayed = function(e, ctrl, shift, meta) { return function() { calendar._rowClickSingle(e, ctrl, shift, meta); }; }; calendar.timeouts.resClick.push(window.setTimeout(resClickDelayed(e, ctrl, shift, meta), calendar.doubleClickTimeout)); }; this._rowClickSingle = function(e, ctrl, shift, meta) { // backwards compatibility var rowClickHandling = calendar.resourceHeaderClickHandling || calendar.rowClickHandling; if (calendar._api2()) { var args = {}; args.resource = e; args.row = e; args.ctrl = ctrl; args.shift = shift; args.meta = meta; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onRowClick === 'function') { calendar.onRowClick(args); if (args.preventDefault.value) { return; } } // backwards compatiblity if (typeof calendar.onResourceHeaderClick === 'function') { calendar.onResourceHeaderClick(args); if (args.preventDefault.value) { return; } } switch (rowClickHandling) { case 'PostBack': calendar.rowClickPostBack(e); break; case 'CallBack': calendar.rowClickCallBack(e); break; case 'Select': calendar._rowSelectDispatch(e.$.row, ctrl, shift, meta); break; case 'Edit': calendar._rowtools.edit(e.$.row); break; } if (typeof calendar.onRowClicked === 'function') { calendar.onRowClicked(args); } if (typeof calendar.onResourceHeaderClicked === 'function') { calendar.onResourceHeaderClicked(args); } } else { switch (rowClickHandling) { case 'PostBack': calendar.rowClickPostBack(e); break; case 'CallBack': calendar.rowClickCallBack(e); break; case 'JavaScript': calendar.onRowClick(e); break; case 'Select': calendar._rowSelectDispatch(e.$.row, ctrl, shift); break; case 'Edit': calendar._rowtools.edit(e.$.row); break; } } }; // this.timeHeaderClickPostBack = function(e, data) { var params = {}; params.header = e; this._postBack2("TimeHeaderClick", params, data); }; this.timeHeaderClickCallBack = function(e, data) { var params = {}; params.header = e; this._callBack2("TimeHeaderClick", params, data); }; this._timeHeaderClickDispatch = function(e) { if (calendar._api2()) { var args = {}; args.header = e; /* * start * end * level * */ args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onTimeHeaderClick === 'function') { calendar.onTimeHeaderClick(args); if (args.preventDefault.value) { return; } } switch (this.timeHeaderClickHandling) { case 'PostBack': calendar.timeHeaderClickPostBack(e); break; case 'CallBack': calendar.timeHeaderClickCallBack(e); break; } if (typeof calendar.onTimeHeaderClicked === 'function') { calendar.onTimeHeaderClicked(args); } } else { switch (this.timeHeaderClickHandling) { case 'PostBack': calendar.timeHeaderClickPostBack(e); break; case 'CallBack': calendar.timeHeaderClickCallBack(e); break; case 'JavaScript': calendar.onTimeHeaderClick(e); break; } } }; // this.resourceCollapsePostBack = function(e, data) { var params = {}; params.resource = e; this._postBack2("ResourceCollapse", params, data); }; this.resourceCollapseCallBack = function(e, data) { var params = {}; params.resource = e; this._callBack2("ResourceCollapse", params, data); }; this._resourceCollapseDispatch = function(e) { if (calendar._api2()) { var args = {}; args.resource = e; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onResourceCollapse === 'function') { calendar.onResourceCollapse(args); if (args.preventDefault.value) { return; } } switch (this.resourceCollapseHandling) { case 'PostBack': calendar.resourceCollapsePostBack(e); break; case 'CallBack': calendar.resourceCollapseCallBack(e); break; } } else { switch (this.resourceCollapseHandling) { case 'PostBack': calendar.resourceCollapsePostBack(e); break; case 'CallBack': calendar.resourceCollapseCallBack(e); break; case 'JavaScript': calendar.onResourceCollapse(e); break; } } }; // expand this.resourceExpandPostBack = function(e, data) { var params = {}; params.resource = e; this._postBack2("ResourceExpand", params, data); }; this.resourceExpandCallBack = function(e, data) { var params = {}; params.resource = e; this._callBack2("ResourceExpand", params, data); }; this._resourceExpandDispatch = function(e) { if (calendar._api2()) { var args = {}; args.resource = e; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onResourceExpand === 'function') { calendar.onResourceExpand(args); if (args.preventDefault.value) { return; } } switch (this.resourceExpandHandling) { case 'PostBack': calendar.resourceExpandPostBack(e); break; case 'CallBack': calendar.resourceExpandCallBack(e); break; } } else { switch (this.resourceExpandHandling) { case 'PostBack': calendar.resourceExpandPostBack(e); break; case 'CallBack': calendar.resourceExpandCallBack(e); break; case 'JavaScript': calendar.onResourceExpand(e); break; } } }; this.eventEditPostBack = function(e, newText, data) { var params = {}; params.e = e; params.newText = newText; this._postBack2("EventEdit", params, data); }; this.eventEditCallBack = function(e, newText, data) { var params = {}; params.e = e; params.newText = newText; this._callBack2("EventEdit", params, data); }; this._eventEditDispatch = function(e, newText) { if (calendar._api2()) { var args = {}; args.e = e; args.newText = newText; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onEventEdit === 'function') { calendar.onEventEdit(args); if (args.preventDefault.value) { return; } } switch (calendar.eventEditHandling) { case 'PostBack': calendar.eventEditPostBack(e, newText); break; case 'CallBack': calendar.eventEditCallBack(e, newText); break; case 'Update': e.text(newText); calendar.events.update(e); break; } if (typeof calendar.onEventEdited === 'function') { calendar.onEventEdited(args); if (args.preventDefault.value) { return; } } } else { switch (calendar.eventEditHandling) { case 'PostBack': calendar.eventEditPostBack(e, newText); break; case 'CallBack': calendar.eventEditCallBack(e, newText); break; case 'JavaScript': calendar.onEventEdit(e, newText); break; } } }; this.commandCallBack = function(command, data) { this._invokeCommand("CallBack", command, data); }; this.commandPostBack = function(command, data) { this._invokeCommand("PostBack", command, data); }; this._invokeCommand = function(type, command, data) { var params = {}; params.command = command; this._invokeEvent(type, "Command", params, data); }; this._postBack2 = function(action, parameters, data) { var envelope = {}; envelope.action = action; envelope.type = "PostBack"; envelope.parameters = parameters; envelope.data = data; envelope.header = this._getCallBackHeader(); var commandstring = "JSON" + DayPilot.JSON.stringify(envelope); __doPostBack(calendar.uniqueID, commandstring); }; this._callBack2 = function(action, parameters, data, type) { if (!calendar._serverBased()) { calendar.debug.message("Callback invoked without the server-side backend specified. Callback canceled.", "warning"); return; } if (typeof type === 'undefined') { type = "CallBack"; } this._pauseAutoRefresh(); calendar._loadingStart(); var envelope = {}; envelope.action = action; envelope.type = type; envelope.parameters = parameters; envelope.data = data; envelope.header = this._getCallBackHeader(); var json = DayPilot.JSON.stringify(envelope); var commandstring; if (typeof Iuppiter !== 'undefined' && Iuppiter.compress) { commandstring = "LZJB" + Iuppiter.Base64.encode(Iuppiter.compress(json)); } else { commandstring = "JSON" + json; } this._doCallBackStart(envelope); var context = null; if (this.backendUrl) { DayPilot.request(this.backendUrl, this._callBackResponse, commandstring, this._ajaxError); } else if (typeof WebForm_DoCallback === 'function') { WebForm_DoCallback(this.uniqueID, commandstring, this._updateView, context, this.callbackError, true); } }; this._doCallBackStart = function(envelope) { var args = {}; if (typeof calendar.onCallBackStart === 'function') { calendar.onCallBackStart(args); } }; this._doCallBackEnd = function() { var args = {}; if (typeof calendar.onCallBackEnd === 'function') { setTimeout(function() { calendar.onCallBackEnd(args); }, 0); } }; this._serverBased = function() { if (this.backendUrl) { // ASP.NET MVC, Java return true; } if (this._isAspnetWebForms()) { return true; } return false; }; this._isAspnetWebForms = function() { if (typeof WebForm_DoCallback === 'function' && this.uniqueID) { return true; } return false; }; this._ajaxError = function(req) { if (typeof calendar.onAjaxError === 'function') { var args = {}; args.request = req; calendar.onAjaxError(args); } else if (typeof calendar.ajaxError === 'function') { // backwards compatibility calendar.ajaxError(req); } }; this._callBackResponse = function(response) { calendar._updateView(response.responseText); }; this._getCallBackHeader = function() { var h = {}; h.v = this.v; h.control = "dps"; h.id = this.id; // callback-changeable state h.startDate = calendar.startDate; h.days = calendar.days; h.cellDuration = calendar.cellDuration; h.cellGroupBy = calendar.cellGroupBy; h.cellWidth = calendar.cellWidth; h.cellWidthSpec = calendar.cellWidthSpec; // extra properties h.viewType = calendar.viewType; // serialize h.hourNameBackColor = calendar.hourNameBackColor; h.showNonBusiness = calendar.showNonBusiness; h.businessBeginsHour = calendar.businessBeginsHour; h.businessEndsHour = calendar.businessEndsHour; h.weekStarts = calendar.weekStarts; h.treeEnabled = calendar.treeEnabled; h.backColor = calendar.cellBackColor; h.nonBusinessBackColor = calendar.cellBackColorNonBusiness; h.locale = calendar.locale; h.timeZone = calendar.timeZone; h.tagFields = calendar.tagFields; h.timeHeaders = calendar.timeHeaders; h.cssOnly = calendar.cssOnly; h.cssClassPrefix = calendar.cssClassPrefix; h.durationBarMode = calendar.durationBarMode; h.showBaseTimeHeader = true; // to be removed h.rowHeaderColumns = calendar.rowHeaderColumns; h.rowMarginBottom = calendar.rowMarginBottom; h.rowMarginTop = calendar.rowMarginTop; h.rowMinHeight = calendar.rowMinHeight; h.scale = calendar.scale; // custom state h.clientState = calendar.clientState; // user-changeable state if (this.nav.scroll) { h.scrollX = this.nav.scroll.scrollLeft; h.scrollY = this.nav.scroll.scrollTop; } h.selected = calendar.multiselect.events(); h.selectedRows = rowtools._getSelectedList(); // special h.hashes = calendar.hashes; var area = calendar._getArea(h.scrollX, h.scrollY); var range = calendar._getAreaRange(area); var res = calendar._getAreaResources(area); //h.scrollX = calendar.scrollX; //h.scrollY = calendar.scrollY; h.rangeStart = range.start; h.rangeEnd = range.end; h.resources = res; h.dynamicLoading = calendar.dynamicLoading; h.separators = this.separators; if (this.syncResourceTree && this.viewType != "Days") { h.tree = this._getTreeState(); } if (this.syncLinks) { h.links = this._getLinksState(); } if (this.scale === "Manual") { h.timeline = this._getTimelineState(); } if (typeof calendar.onCallBackHeader === "function") { var args = {}; args.header = h; calendar.onCallBackHeader(args); } return h; }; this._getTimelineState = function() { var list = []; DayPilot.list(calendar.timeline).each(function(item) { var json = {}; json.start = item.start; json.end = item.end; json.width = item.width; list.push(json); }); return list; }; this._getLinksState = function() { var list = []; var getTags = function(link) { var result = {}; if (link.tags) { for (var name in link.tags) { result[name] = "" + link.tags[name]; } } return result; }; if (!DayPilot.isArray(calendar.links.list)) { return list; } for (var i = 0; i < calendar.links.list.length; i++) { var link = calendar.links.list[i]; var json = {}; json.id = link.id; json.from = link.from; json.to = link.to; json.type = link.type; json.tags = getTags(link); list.push(json); } return list; }; this.getViewPort = function() { var scrollX = this.nav.scroll.scrollLeft; var scrollY = this.nav.scroll.scrollTop; var area = this._getArea(scrollX, scrollY); var range = this._getAreaRange(area); var resources = this._getAreaResources(area); var result = {}; result.start = range.start; result.end = range.end; result.resources = resources; return result; }; this._getArea = function(scrollX, scrollY) { var area = {}; area.start = {}; area.end = {}; area.start.x = Math.floor(scrollX / calendar.cellWidth); area.end.x = Math.floor((scrollX + calendar.nav.scroll.clientWidth) / calendar.cellWidth); area.start.y = calendar._getRow(scrollY).i; area.end.y = calendar._getRow(scrollY + calendar.nav.scroll.clientHeight).i; var maxX = this.itline.length; if (area.end.x >= maxX) { area.end.x = maxX - 1; } return area; }; this._getAreaRange = function(area) { var result = {}; if (this.itline.length <= 0) { result.start = this.startDate; result.end = this.startDate; return result; } if (!this.itline[area.start.x]) { throw 'Internal error: area.start.x is null.'; } result.start = this.itline[area.start.x].start; result.end = this.itline[area.end.x].end; return result; }; this._getAreaResources = function(area) { // this might not be necessary, ported from DPSD if (!area) { var area = this._getArea(this.nav.scroll.scrollLeft, this.nav.scroll.scrollTop); } var res = []; res.ignoreToJSON = true; // preventing Gaia and prototype to mess up with Array serialization for (var i = area.start.y; i <= area.end.y; i++) { var r = calendar.rowlist[i]; if (r && !r.hidden) { res.push(r.id); } } return res; }; this._getTreeState = function() { var tree = []; tree.ignoreToJSON = true; // preventing Gaia and prototype to mess up with Array serialization for (var i = 0; i < this.rowlist.length; i++) { var row = this.rowlist[i]; if (row.level > 0) { continue; } if (row.isNewRow) { continue; } var node = this._getNodeState(i); tree.push(node); } return tree; }; this._getNodeChildren = function(indices) { var children = []; children.ignoreToJSON = true; // preventing Gaia to mess up with Array serialization for (var i = 0; i < indices.length; i++) { var index = indices[i]; var row = calendar.rowlist[index]; if (row.isNewRow) { continue; } children.push(calendar._getNodeState(index)); } return children; }; this._getNodeState = function(i) { var row = this.rowlist[i]; if (typeof calendar.onGetNodeState === "function") { var args = {}; args.row = row; args.preventDefault = function() { args.preventDefault.value = true; }; args.result = {}; calendar.onGetNodeState(args); if (args.preventDefault.value) { return args.result; } } var node = {}; node.Value = row.id; node.BackColor = row.backColor; node.Name = row.name; node.InnerHTML = row.html; node.ToolTip = row.toolTip; node.Expanded = row.expanded; node.Children = this._getNodeChildren(row.children); node.Loaded = row.loaded; node.IsParent = row.isParent; node.Columns = this._getNodeColumns(row); if (row.start.getTime() !== calendar.startDate.getTime()) { node.Start = row.start; } if (row.minHeight !== calendar.rowMinHeight) { node.MinHeight = row.minHeight; } if (row.marginBottom !== calendar.rowMarginBottom) { node.MarginBottom = row.marginBottom; } if (row.marginTop !== calendar.rowMarginTop) { node.MarginTop = row.marginTop; } if (row.eventHeight !== calendar.eventHeight) { node.EventHeight = row.eventHeight; } return node; }; this._getNodeColumns = function(row) { if (!row.columns || row.columns.length === 0) { return null; } var columns = []; columns.ignoreToJSON = true; // preventing Gaia to mess up with Array serialization for (var i = 0; i < row.columns.length; i++) { var c = {}; c.InnerHTML = row.columns[i].html; columns.push(c); } return columns; }; /* this.$ = function(subid) { return document.getElementById(id + "_" + subid); }; */ this._prefixCssClass = function(part) { var prefix = this.theme || this.cssClassPrefix; if (prefix) { return prefix + part; } else { return ""; } }; this._registerDispose = function() { //var root = document.getElementById(id); this.nav.top.dispose = this.dispose; }; this.dispose = function() { var c = calendar; if (!c.nav.top) { return; } c._pauseAutoRefresh(); c._deleteEvents(); c.divBreaks = null; c.divCells = null; c.divCorner = null; c.divCrosshair = null; c.divEvents = null; if (c.divHeader) { c.divHeader.rows = null; } c.divHeader = null; c.divLines = null; c.divNorth = null; c.divRange = null; c.divResScroll = null; c.divSeparators = null; c.divSeparatorsAbove = null; c.divStretch = null; c.divTimeScroll = null; c._scrollRes = null; c._vsph = null; c._maind.calendar = null; c._maind = null; c.nav.loading = null; c.nav.top.onmousemove = null; c.nav.top.dispose = null; c.nav.top.ontouchstart = null; c.nav.top.ontouchmove = null; c.nav.top.ontouchend = null; c.nav.top.removeAttribute('style'); c.nav.top.removeAttribute('class'); c.nav.top.innerHTML = ""; c.nav.top.dp = null; c.nav.top = null; c.nav.scroll.onscroll = null; c.nav.scroll.root = null; c.nav.scroll = null; DayPilot.ue(window, 'resize', c._resize); DayPilotScheduler.unregister(c); }; this._createShadowRange = function(object, type) { var maind = calendar._maind; var coords = calendar._getShadowCoords(object); var event = object.event; var height = event.part.height || calendar._resolved.eventHeight(); var top = (event.part && event.part.top) ? (event.part.top + calendar.rowlist[event.part.dayIndex].top) : coords.top; var shadow = document.createElement('div'); shadow.setAttribute('unselectable', 'on'); shadow.style.position = 'absolute'; shadow.style.width = (coords.width) + 'px'; shadow.style.height = height + 'px'; shadow.style.left = coords.left + 'px'; shadow.style.top = top + 'px'; shadow.style.zIndex = 101; shadow.style.overflow = 'hidden'; var inner = document.createElement("div"); shadow.appendChild(inner); if (this.cssOnly) { shadow.className = this._prefixCssClass("_shadow"); inner.className = this._prefixCssClass("_shadow_inner"); } if (!this.cssOnly) { if (type === 'Fill') { // transparent shadow inner.style.backgroundColor = "#aaaaaa"; inner.style.opacity = 0.5; inner.style.filter = "alpha(opacity=50)"; inner.style.height = "100%"; if (object && object.event && object.style) { //shadow.style.overflow = 'hidden'; inner.style.fontSize = object.style.fontSize; inner.style.fontFamily = object.style.fontFamily; inner.style.color = object.style.color; inner.innerHTML = object.event.client.innerHTML(); } } else { shadow.style.paddingTop = "2px"; inner.style.border = '2px dotted #666666'; } } maind.appendChild(shadow); shadow.calendar = calendar; return shadow; }; this._createShadow = function(object, type) { var maind = calendar._maind; var coords = calendar._getShadowCoords(object); var event = object.event; var ev = event; if (calendar._isRowDisabled(coords.rowIndex)) { return; } var height = event.part.height || calendar._resolved.eventHeight(); var top = (event.part && event.part.top) ? (event.part.top + calendar.rowlist[event.part.dayIndex].top) : coords.top; var left = coords.left; var verticalAllowed = (ev.cache && typeof ev.cache.moveVDisabled !== 'undefined') ? !ev.cache.moveVDisabled : !ev.data.moveVDisabled; var horizontalAllowed = (ev.cache && typeof ev.cache.moveHDisabled !== 'undefined') ? !ev.cache.moveHDisabled :!ev.data.moveHDisabled; if (!verticalAllowed && DayPilotScheduler.moving) { top = calendar.rowlist[ev.part.dayIndex].top; } if (!horizontalAllowed && DayPilotScheduler.moving) { left = event.part.left; } var shadow = document.createElement('div'); shadow.setAttribute('unselectable', 'on'); shadow.style.position = 'absolute'; shadow.style.width = (coords.width) + 'px'; shadow.style.height = height + 'px'; shadow.style.left = left + 'px'; shadow.style.top = top + 'px'; shadow.style.zIndex = 101; shadow.style.overflow = 'hidden'; var inner = document.createElement("div"); shadow.appendChild(inner); if (this.cssOnly) { shadow.className = this._prefixCssClass("_shadow"); inner.className = this._prefixCssClass("_shadow_inner"); } if (!this.cssOnly) { if (type === 'Fill') { // transparent shadow inner.style.backgroundColor = "#aaaaaa"; inner.style.opacity = 0.5; inner.style.filter = "alpha(opacity=50)"; inner.style.height = "100%"; if (object && object.event && object.style) { //shadow.style.overflow = 'hidden'; inner.style.fontSize = object.style.fontSize; inner.style.fontFamily = object.style.fontFamily; inner.style.color = object.style.color; inner.innerHTML = object.event.client.innerHTML(); } } else { shadow.style.paddingTop = "2px"; inner.style.border = '2px dotted #666666'; } } maind.appendChild(shadow); shadow.calendar = calendar; return shadow; }; // y is in pixels, not row index this._getRow = function(y) { var result = {}; var element; var top = 0; var rowEnd = 0; var iMax = this.rowlist.length; // maximum row index for (var i = 0; i < iMax; i++) { var row = this.rowlist[i]; if (row.hidden) { continue; } rowEnd += row.height; if (y < rowEnd || i === iMax - 1) { top = rowEnd - row.height; element = row; break; } } result.top = top; result.bottom = rowEnd; result.i = i; result.element = element; return result; }; this.links = {}; var linktools = {}; this._linktools = linktools; linktools.clear = function() { calendar.divLinksAbove.innerHTML = ''; calendar.divLinksBelow.innerHTML = ''; calendar.elements.links = []; }; linktools.showLinkpoints = function() { var events = viewport.events(); events.each(function(div) { linktools.showLinkpoint(div); }); }; linktools.showLinkpoint = function(div) { var width = 10; var mid = width/2; var left = div.event.part.left; var top = calendar.rowlist[div.event.part.dayIndex].top + div.event.part.top; var height = div.event.part.height; var right = div.event.part.right; var start = DayPilot.Util.div(calendar.divLinkpoints, left - mid, top - mid + height/2, width, width); start.style.backgroundColor = "white"; start.style.border = "1px solid gray"; start.style.borderRadius = "5px"; start.style.boxSizing = "border-box"; start.coords = {x: left, y: top + height/2}; start.type = "Start"; start.event = div.event; linktools.activateLinkpoint(start); calendar.elements.linkpoints.push(start); var end = DayPilot.Util.div(calendar.divLinkpoints, right - mid, top - mid + height/2, width, width); end.style.backgroundColor = "white"; end.style.border = "1px solid gray"; end.style.borderRadius = "5px"; end.style.boxSizing = "border-box"; end.coords = {x: right, y: top + height/2}; end.type = "Finish"; end.event = div.event; linktools.activateLinkpoint(end); calendar.elements.linkpoints.push(end); }; linktools.activateLinkpoint = function(div) { //linktools.clearHideTimeout(); div.onmousedown = function(ev) { var ev = ev || window.event; linking.source = div; linking.calendar = calendar; linktools.showLinkpoints(); ev.preventDefault && ev.preventDefault(); // prevent text selection cursor in chrome ev.stopPropagation && ev.stopPropagation(); return false; }; div.onmousemove = function(ev) { //if (linking.source) { div.style.backgroundColor = "black"; //} linktools.clearHideTimeout(); }; div.onmouseout = function(ev) { if (!linking.source || linking.source.event !== div.event) { div.style.backgroundColor = "white"; } }; div.onmouseup = function(ev) { if (linking.source) { var type = linking.source.type + "To" + div.type; var from = linking.source.event.id(); var to = div.event.id(); var args = {}; args.from = from; args.to = to; args.type = type; args.id = null; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onLinkCreate === "function") { calendar.onLinkCreate(args); if (args.preventDefault.value) { return; } } var update = function() { calendar.links.list.push({"from": from, "to": to, "type": type, "id": args.id}); linktools.load(); }; switch (calendar.linkCreateHandling) { case "Update": update(); break; case "CallBack": calendar._linkCreateCallBack(args); break; case "PostBack": calendar._linkCreatePostBack(args); break; case "Notify": update(); calendar._linkCreateNotify(args); break; } if (typeof calendar.onLinkCreated === "function") { calendar.onLinkCreated(args); } } }; } linktools.hideLinkpoints = function() { calendar.divLinkpoints.innerHTML = ''; calendar.elements.linkpoints = []; }; linktools.hideTimeout = null; linktools.hideLinkpointsWithDelay = function() { linktools.hideTimeout = setTimeout(function() { linktools.hideLinkpoints(); }, 100); }; linktools.clearHideTimeout = function() { if (linktools.hideTimeout) { clearTimeout(linktools.hideTimeout); linktools.hideTimeout = null; } }; linktools.load = function() { linktools.clear(); if (!DayPilot.isArray(calendar.links.list)) { return; } for (var i = 0; i < calendar.links.list.length; i++) { var link = calendar.links.list[i]; linktools.drawLinkId(link.from, link.to, link); } }; linktools.drawLinkId = function(from, to, props) { var start = calendar.events.find(from); var end = calendar.events.find(to); linktools.drawLink(start, end, props); }; linktools.drawLink = function(from, to, props) { var divFrom = calendar._findEventDiv(from); var divTo = calendar._findEventDiv(to); if (!divFrom) { return; } if (!divTo) { return; } var type = props.type || "FinishToStart"; var start, end; var fromRowTop = calendar.rowlist[divFrom.event.part.dayIndex].top; var toRowTop = calendar.rowlist[divTo.event.part.dayIndex].top; switch (type) { case "FinishToStart": start = {x: divFrom.event.part.right, y: fromRowTop + divFrom.event.part.top}; end = {x: divTo.event.part.left, y: toRowTop + divTo.event.part.top}; break; case "StartToFinish": start = {x: divFrom.event.part.left, y: fromRowTop + divFrom.event.part.top}; end = {x: divTo.event.part.right, y: toRowTop + divTo.event.part.top}; break; case "StartToStart": start = {x: divFrom.event.part.left, y: fromRowTop + divFrom.event.part.top}; end = {x: divTo.event.part.left, y: toRowTop + divTo.event.part.top}; break; case "FinishToFinish": start = {x: divFrom.event.part.right, y: fromRowTop + divFrom.event.part.top}; end = {x: divTo.event.part.right, y: toRowTop + divTo.event.part.top}; break; } linktools.drawLinkXy(start, end, props); }; linktools.clearShadow = function() { calendar.divLinkShadow.innerHTML = ''; calendar.elements.linkshadow = []; }; linktools.drawShadow = function(from, to) { linktools.clearShadow(); if (DayPilot.browser.ielt9) { linktools.drawShadowOldStyle(from, to); } else { var parent = calendar.divLinkShadow; var line = DayPilot.line(from.x, from.y, to.x, to.y, true); parent.appendChild(line); calendar.elements.linkshadow.push(line); } }; linktools.drawShadowOldStyle = function(from, to) { var nx = Math.min(from.x, to.x); var width = 2; var parent = calendar.divLinkShadow; var color = "black"; var h1 = DayPilot.Util.div(parent, nx, from.y, from.x - nx, width); h1.style.backgroundColor = color; calendar.elements.linkshadow.push(h1); var v1 = DayPilot.Util.div(parent, nx, from.y, width, to.y - from.y); v1.style.backgroundColor = color; calendar.elements.linkshadow.push(v1); var h3 = DayPilot.Util.div(parent, nx, to.y, to.x - nx, width); h3.style.backgroundColor = color; calendar.elements.linkshadow.push(h3); var a = DayPilot.Util.div(parent, to.x - 6, to.y - 5, 0, 0); a.style.borderColor = "transparent transparent transparent " + color; a.style.borderStyle = "solid"; a.style.borderWidth = "6px"; calendar.elements.linkshadow.push(a); }; linktools.drawLinkXy = function(from, to, props) { var indent = calendar.eventHeight/2; var width = props.width || 1; var type = props.type || "FinishToStart"; var color = props.color; var style = props.style; var layer = props.layer || "Above"; var above = layer === "Above"; var divLinks = above ? calendar.divLinksAbove : calendar.divLinksBelow; var height = calendar.eventHeight; var bottom = calendar.linkBottomMargin; //var border = width + "px " + style + " " + color; var applyBorder = function(div, which) { if (color) { div.style["border" + which + "Color"] = color; } if (style) { div.style["border" + which + "Style"] = style; } }; var divs = []; var saveDiv = function(div, dontHover) { calendar.elements.links.push(div); activateHover(div); activateContextMenu(div); div.divs = divs; // required for hover if (!dontHover) { divs.push(div); } }; var activateContextMenu = function(div) { div.oncontextmenu = function(ev) { ev = ev || window.event; if (calendar.contextMenuLink) { var link = new DayPilot.Link(props, calendar); calendar.contextMenuLink.show(link); } ev.cancelBubble = true; ev.preventDefault ? ev.preventDefault() : null; } }; var activateHover = function(div) { div.onmouseenter = function() { DayPilot.Util.addClass(div.divs, calendar._prefixCssClass("_link_hover")); }; div.onmouseleave = function() { DayPilot.Util.removeClass(div.divs, calendar._prefixCssClass("_link_hover")); }; }; if (type === "FinishToStart") { if (from.y === to.y) { // same line var startx = from.x; var starty = from.y + height - bottom; //var tox = to.x + indent; var tox = to.x; //var toy = start.y; var h1 = DayPilot.Util.div(divLinks, startx, starty, tox - from.x, width); h1.style.boxSizing = "border-box"; h1.style.borderBottomWidth = width + "px"; h1.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h1, props.cssClass); applyBorder(h1, "Bottom"); saveDiv(h1); var a; if (color) { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 0, 0); a.style.borderWidth = "6px"; a.style.borderColor = "transparent transparent transparent " + color; a.style.borderStyle = "solid"; } else { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 6, 6); a.className = calendar._prefixCssClass("_link_arrow_right"); DayPilot.Util.addClass(a, props.cssClass); } saveDiv(a, true); } else if (from.x > to.x) { var above = 5; var midy = to.y - above; var h1 = DayPilot.Util.div(divLinks, from.x, from.y + height - bottom, indent + width, width); h1.style.boxSizing = "border-box"; h1.style.borderBottomWidth = width + "px"; h1.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h1, props.cssClass); applyBorder(h1, "Bottom"); saveDiv(h1); var v1 = DayPilot.Util.div(divLinks, from.x + indent, from.y + height - bottom, width, midy - (from.y + height - bottom)); v1.style.boxSizing = "border-box"; v1.style.borderRightWidth = width + "px"; v1.className = calendar._prefixCssClass("_link_vertical"); DayPilot.Util.addClass(v1, props.cssClass); applyBorder(v1, "Right"); saveDiv(v1); var h2 = DayPilot.Util.div(divLinks, to.x - indent, midy, from.x + 2*indent + width - to.x, width); h2.style.boxSizing = "border-box"; h2.style.borderBottomWidth = width + "px"; h2.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h2, props.cssClass); applyBorder(h2, "Bottom"); saveDiv(h2); var v2 = DayPilot.Util.div(divLinks, to.x - indent, midy, width, to.y - midy + height - bottom); v2.style.boxSizing = "border-box"; v2.style.borderRightWidth = width + "px"; v2.className = calendar._prefixCssClass("_link_vertical"); DayPilot.Util.addClass(v2, props.cssClass); applyBorder(v2, "Right"); saveDiv(v2); var h3 = DayPilot.Util.div(divLinks, to.x - indent, to.y + height - bottom, indent, width); h3.style.boxSizing = "border-box"; h3.style.borderBottomWidth = width + "px"; h3.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h3, props.cssClass); applyBorder(h3, "Bottom"); saveDiv(h3); var a; if (color) { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 0, 0); a.style.borderWidth = "6px"; a.style.borderColor = "transparent transparent transparent " + color; a.style.borderStyle = "solid"; } else { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 6, 6); a.className = calendar._prefixCssClass("_link_arrow_right"); DayPilot.Util.addClass(a, props.cssClass); } saveDiv(a, true); } else { var startx = from.x; var starty = from.y + height - bottom; var tox = to.x + indent; var toy = to.y; var h1 = DayPilot.Util.div(divLinks, startx, starty, tox - from.x, width); h1.style.boxSizing = "border-box"; h1.style.borderBottomWidth = width + "px"; h1.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h1, props.cssClass); applyBorder(h1, "Bottom"); saveDiv(h1); var v1 = DayPilot.Util.div(divLinks, tox, starty, width, toy - starty); v1.style.boxSizing = "border-box"; v1.style.borderRightWidth = width + "px"; v1.className = calendar._prefixCssClass("_link_vertical"); DayPilot.Util.addClass(v1, props.cssClass); applyBorder(v1, "Right"); saveDiv(v1); var a; if (color) { a = DayPilot.Util.div(divLinks, tox - 5 + Math.floor(width/2), toy - 5, 0, 0); a.style.borderColor = color + " transparent transparent transparent"; a.style.borderStyle = "solid"; a.style.borderWidth = "5px"; } else { a = DayPilot.Util.div(divLinks, tox - 6 + Math.floor(width/2), toy - 6, 6, 6); a.className = calendar._prefixCssClass("_link_arrow_down"); DayPilot.Util.addClass(a, props.cssClass); } saveDiv(a, true); } } else if (type === "StartToFinish") { var above = 5; var midy = to.y - above; //var midy = DayPilot.Util.avg(from.y, to.y); var h1 = DayPilot.Util.div(divLinks, to.x, to.y + height - bottom, indent + width, width); h1.style.boxSizing = "border-box"; h1.style.borderBottomWidth = width + "px"; h1.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h1, props.cssClass); applyBorder(h1, "Bottom"); saveDiv(h1); var v1 = DayPilot.Util.div(divLinks, to.x + indent, to.y + height - bottom, width, midy - (to.y + height - bottom) + 0); v1.style.boxSizing = "border-box"; v1.style.borderRightWidth = width + "px"; v1.className = calendar._prefixCssClass("_link_vertical"); DayPilot.Util.addClass(v1, props.cssClass); applyBorder(v1, "Right"); saveDiv(v1); var h2 = DayPilot.Util.div(divLinks, from.x - indent, midy, to.x + 2*indent + width - from.x, width); h2.style.boxSizing = "border-box"; h2.style.borderBottomWidth = width + "px"; h2.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h2, props.cssClass); applyBorder(h2, "Bottom"); saveDiv(h2); var v2 = DayPilot.Util.div(divLinks, from.x - indent, midy, width, from.y + height - bottom - midy + 0); v2.style.boxSizing = "border-box"; v2.style.borderRightWidth = width + "px"; v2.className = calendar._prefixCssClass("_link_vertical"); DayPilot.Util.addClass(v2, props.cssClass); applyBorder(v2, "Right"); saveDiv(v2); var h3 = DayPilot.Util.div(divLinks, from.x - indent, from.y + height - bottom, indent, width); h3.style.boxSizing = "border-box"; h3.style.borderBottomWidth = width + "px"; h3.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h3, props.cssClass); applyBorder(h3, "Bottom"); saveDiv(h3); var a; if (color) { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 0, 0); a.style.borderColor = "transparent " + color + " transparent transparent"; a.style.borderStyle = "solid"; a.style.borderWidth = "6px"; } else { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 6, 6); a.className = calendar._prefixCssClass("_link_arrow_left"); DayPilot.Util.addClass(a, props.cssClass); } saveDiv(a, true); } else if (type === "StartToStart") { var nx = Math.min(from.x, to.x) - indent; var h1 = DayPilot.Util.div(divLinks, nx, from.y + height - bottom, from.x - nx, width); h1.style.boxSizing = "border-box"; h1.style.borderBottomWidth = width + "px"; h1.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h1, props.cssClass); applyBorder(h1, "Bottom"); saveDiv(h1); var v1 = DayPilot.Util.div(divLinks, nx, from.y + height - bottom, width, to.y - from.y); v1.style.boxSizing = "border-box"; v1.style.borderRightWidth = width + "px"; v1.className = calendar._prefixCssClass("_link_vertical"); DayPilot.Util.addClass(v1, props.cssClass); applyBorder(v1, "Right"); saveDiv(v1); var h3 = DayPilot.Util.div(divLinks, nx, to.y + height - bottom, to.x - nx, width); h3.style.boxSizing = "border-box"; h3.style.borderBottomWidth = width + "px"; h3.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h3, props.cssClass); applyBorder(h3, "Bottom"); saveDiv(h3); var a; if (color) { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 0, 0); a.style.borderColor = "transparent transparent transparent " + color; a.style.borderStyle = "solid"; a.style.borderWidth = "6px"; } else { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 6, 6); a.className = calendar._prefixCssClass("_link_arrow_right"); DayPilot.Util.addClass(a, props.cssClass); } saveDiv(a, true); } else if (type === "FinishToFinish") { //var midy = DayPilot.Util.avg(from.y, to.y); var fx = Math.max(to.x, from.x) + indent; var h1 = DayPilot.Util.div(divLinks, from.x, from.y + height - bottom, fx - from.x, width); h1.style.boxSizing = "border-box"; h1.style.borderBottomWidth = width + "px"; h1.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h1, props.cssClass); applyBorder(h1, "Bottom"); saveDiv(h1); var v1 = DayPilot.Util.div(divLinks, fx, from.y + height - bottom, width, to.y - from.y); v1.style.boxSizing = "border-box"; v1.style.borderRightWidth = width + "px"; v1.className = calendar._prefixCssClass("_link_vertical"); DayPilot.Util.addClass(v1, props.cssClass); applyBorder(v1, "Right"); saveDiv(v1); var h3 = DayPilot.Util.div(divLinks, to.x, to.y + height - bottom, fx - to.x, width); h3.style.boxSizing = "border-box"; h3.style.borderBottomWidth = width + "px"; h3.className = calendar._prefixCssClass("_link_horizontal"); DayPilot.Util.addClass(h3, props.cssClass); applyBorder(h3, "Bottom"); saveDiv(h3); var a; if (color) { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 0, 0); a.style.borderColor = "transparent " + color + " transparent transparent"; a.style.borderStyle = "solid"; a.style.borderWidth = "6px"; } else { a = DayPilot.Util.div(divLinks, to.x - 6, to.y + height - bottom - 5, 6, 6); a.className = calendar._prefixCssClass("_link_arrow_left"); DayPilot.Util.addClass(a, props.cssClass); } saveDiv(a, true); } }; this._linkCreateCallBack = function(args, data) { var params = {}; params.from = args.from; params.to = args.to; params.type = args.type; calendar._callBack2("LinkCreate", params, data); }; this._linkCreateNotify = function(args, data) { var params = {}; params.from = args.from; params.to = args.to; params.type = args.type; calendar._callBack2("LinkCreate", params, data, "Notify"); }; this._linkCreatePostBack = function(args, data) { var params = {}; params.from = args.from; params.to = args.to; params.type = args.type; calendar._postBack2("LinkCreate", params, data); }; this._getRowByIndex = function(i) { var top = 0; var bottom = 0; var index = 0; // visible index if (i > this.rowlist.length - 1) { throw "Row index too high (DayPilotScheduler._getRowByIndex)"; } for (var j = 0; j <= i; j++) { var row = this.rowlist[j]; if (row.hidden) { continue; } bottom += row.height; index++; } top = bottom - row.height; var result = {}; result.top = top; result.height = row.height; result.bottom = bottom; result.i = index - 1; result.data = row; return result; }; this._isShortInit = function() { // make sure it has a place to ask if (this.backendUrl) { return (typeof calendar.events.list === 'undefined') || (!calendar.events.list); } else { return false; } }; this.events.find = function(id) { if (!calendar.events.list || typeof calendar.events.list.length === 'undefined') { return null; } var len = calendar.events.list.length; for (var i = 0; i < len; i++) { if (calendar.events.list[i].id === id) { return new DayPilot.Event(calendar.events.list[i], calendar); } } return null; }; this.events.all = function() { var list = []; for (var i = 0; i < calendar.events.list.length; i++) { var e = new DayPilot.Event(calendar.events.list[i], calendar); list.push(e); } return DayPilot.list(list); }; this.events.filter = function(args) { calendar.events._filterParams = args; calendar._update({"eventsOnly":true}); }; this.events.edit = function(e) { var div = calendar._findEventDiv(e); if (!div) { return; } calendar._divEdit(div); }; this.events.load = function(url, success, error) { var onError = function(args) { var largs = {}; largs.exception = args.exception; largs.request = args.request; if (typeof error === 'function') { error(largs); } }; var onSuccess = function(args) { var r = args.request; var data; // it's supposed to be JSON try { data = DayPilot.Util.parseJSON(r.responseText); } catch (e) { var fargs = {}; fargs.exception = e; onError(fargs); return; } if (DayPilot.isArray(data)) { var sargs = {}; sargs.preventDefault = function() { this.preventDefault.value = true; }; sargs.data = data; if (typeof success === "function") { success(sargs); } if (sargs.preventDefault.value) { return; } calendar.events.list = data; if (calendar._initialized) { calendar.update(); } } }; DayPilot.ajax({ "url": url, "success": onSuccess, "error": onError }); }; this.events.findRecurrent = function(masterId, time) { if (!calendar.events.list || typeof calendar.events.list.length === 'undefined') { return null; } var len = calendar.events.list.length; for (var i = 0; i < len; i++) { if (calendar.events.list[i].recurrentMasterId === masterId && calendar.events.list[i].start.getTime() === time.getTime()) { return new DayPilot.Event(calendar.events.list[i], calendar); } } return null; }; // internal this.events._removeFromRows = function(data) { var rows = []; for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; if (row.isNewRow) { continue; } calendar._ensureRowData(i); for (var r = 0; r < row.events.length; r++) { if (row.events[r].data === data) { //data.rendered = false; rows.push(i); row.events.splice(r, 1); break; // only once per row } } } return rows; }; // internal // fast, use instead of full loadEvents() this.events._addToRows = function(data) { var rows = []; var testAll = calendar._containsDuplicateResources() || calendar.viewType === "Days"; var index = DayPilot.indexOf(calendar.events.list, data); calendar._doBeforeEventRender(index); for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; if (row.isNewRow) { continue; } calendar._ensureRowData(i); var ep = calendar._loadEvent(data, row); if (ep) { if (typeof calendar.onBeforeEventRender === 'function') { ep.cache = calendar._cache.events[index]; } rows.push(i); if (!testAll) { break; } } } return rows; }; this.events.update = function(e, data) { var params = {}; params.oldEvent = new DayPilot.Event(e.copy(), calendar); params.newEvent = new DayPilot.Event(e.temp(), calendar); var action = new DayPilot.Action(calendar, "EventUpdate", params, data); if (calendar._angular.scope) { e.commit(); calendar._angular.notify(); } else { var rows = calendar.events._removeFromRows(e.data); e.commit(); rows = rows.concat(calendar.events._addToRows(e.data)); calendar._loadRows(rows); calendar._updateRowHeights(); if (calendar._initialized) { if (calendar.viewType === "Gantt") { calendar.update(); } else { calendar._updateRowsNoLoad(rows); calendar._updateHeight(); } } } return action; }; this.events.remove = function(e, data) { var params = {}; params.e = new DayPilot.Event(e.data, calendar); var action = new DayPilot.Action(calendar, "EventRemove", params, data); var index = DayPilot.indexOf(calendar.events.list, e.data); calendar.events.list.splice(index, 1); if (calendar._angular.scope) { calendar._angular.notify(); } else { var rows = calendar.events._removeFromRows(e.data); calendar._loadRows(rows); calendar._updateRowHeights(); if (calendar._initialized) { if (calendar.viewType === "Gantt") { calendar.update(); } else { calendar._updateRowsNoLoad(rows); calendar._updateHeight(); } } } return action; }; this.events.add = function(e, data) { e.calendar = calendar; if (!calendar.events.list) { calendar.events.list = []; } calendar.events.list.push(e.data); if (calendar._angular.scope) { calendar._angular.notify(); } else { var params = {}; params.e = e; var action = new DayPilot.Action(calendar, "EventAdd", params, data); //var ri = DayPilot.indexOf(calendar.rows, calendar._findRowByResourceId(e.resource())); //var row = calendar.rows[ri]; // prepare //var start = new Date(); var rows = calendar.events._addToRows(e.data); calendar._loadRows(rows); calendar._updateRowHeights(); //var end = new Date(); if (calendar._initialized) { if (calendar.viewType === "Gantt") { calendar.update(); } else { calendar._updateRowsNoLoad(rows); calendar._updateHeight(); } } } return action; }; this.queue = {}; this.queue.list = []; this.queue.list.ignoreToJSON = true; this.queue.add = function(action) { if (!action) { return; } if (action.isAction) { calendar.queue.list.push(action); } else { throw "DayPilot.Action object required for queue.add()"; } }; this.queue.notify = function(data) { var params = {}; params.actions = calendar.queue.list; calendar._callBack2('Notify', params, data, "Notify"); calendar.queue.list = []; }; this.queue.clear = function() { calendar.queue.list = []; }; this.queue.pop = function() { return calendar.queue.list.pop(); }; this.cells.find = function(start, resource) { var pixels = calendar.getPixels(new DayPilot.Date(start)); if (!pixels) { return cellArray(); } var x = pixels.i; var row = calendar._findRowByResourceId(resource); if (!row) { return cellArray(); } var top = row.top; var y = calendar._getRow(top).i; return this.findXy(x, y); }; this.cells.findByPixels = function(x, y) { var itc = calendar._getItlineCellFromPixels(x); if (!itc) { return cellArray(); } var x = itc.x; var row = calendar._getRow(y); if (!row) { return cellArray(); } var y = row.i; return this.findXy(x, y); }; this.cells.all = function() { var list = []; // may require optimization var maxX = calendar.itline.length; var maxY = calendar.rowlist.length; for(var x = 0; x < maxX; x++) { for (var y = 0; y < maxY; y++) { var cell = calendar.cells.findXy(x, y); list.push(cell[0]); } } return cellArray(list); }; this.cells._cell = function(x, y) { var itc = calendar.itline[x]; var row = calendar.rowlist[y]; var rowOffset = row.start.getTime() - calendar._visibleStart().getTime(); var start = itc.start.addTime(rowOffset); var end = itc.end.addTime(rowOffset); var cell = {}; cell.x = x; cell.y = y; cell.i = x + "_" + y; cell.resource = row.id; cell.start = itc.start; cell.end = itc.end; cell.update = function() { // if visible if (!calendar.rowlist[cell.y].hidden) { var area = calendar._getDrawArea(); if (area.xStart <= cell.x && cell.x <= area.xEnd) { if (area.yStart <= cell.y && cell.y <= area.yEnd) { var old = calendar._cache.cells[cell.i]; calendar._deleteCell(old); calendar._drawCell(cell.x, cell.y); } } } }; cell.utilization = function(name) { if (!row.sections) { row.calculateUtilization(); } return row.sections.forRange(start, end).maxSum(name); }; cell.events = function() { return row.events.forRange(start, end); }; cell.div = calendar._cache.cells[cell.i]; var p = calendar._getCellProperties(x, y); cell.properties = p; return cell; }; /* accepts findXy(0,0) or findXy([{x:0, y:0}, {x:0, y:1}]) */ this.cells.findXy = function(x, y) { if (DayPilot.isArray(x)) { var cells = []; for (var i = 0; i < x.length; i++) { var o = x[i]; cells.push(calendar.cells._cell(o.x, o.y)); } return cellArray(cells); } else if (x === null || y === null) { return cellArray(); // empty } var cell = calendar.cells._cell(x, y); return cellArray(cell); }; var rowArray = function(a) { var list = []; if (DayPilot.isArray(a)) { for (var i = 0; i < a.length; i++) { list.push(a[i]); } } else if (typeof a === 'object') { list.push(a); } list.each = function(f) { if (!f) { return; } for (var i = 0; i < list.length; i++) { f(list[i]); } }; return list; }; var cellArray = function(a) { var list = []; if (DayPilot.isArray(a)) { for (var i = 0; i < a.length; i++) { list.push(a[i]); } } else if (typeof a === 'object') { list.push(a); } list.cssClass = function(css) { this.each(function(item) { item.properties.cssClass = DayPilot.Util.addClassToString(item.properties.cssClass, css); item.update(); }); return this; }; list.removeClass = function(css) { this.each(function(item) { item.properties.cssClass = DayPilot.Util.removeClassFromString(item.properties.cssClass, css); item.update(); }); return this; }; list.addClass = list.cssClass; list.html = function(html) { this.each(function(item) { item.properties.html = html; item.update(); }); return this; }; list.each = function(f) { if (!f) { return; } for (var i = 0; i < this.length; i++) { f(list[i]); } }; return list; }; this._angular = {}; this._angular.scope = null; this._angular.notify = function() { if (calendar._angular.scope) { calendar._angular.scope["$apply"](); } }; this.debug = new DayPilot.Debug(this); this._getRowStartInDaysView = function(date) { if (calendar.viewType !== 'Days') { throw "Checking row start when viewType !== 'Days'"; } for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; var data = row.element ? row.element.data : row.data; var start = data.start; if (date.getTime() >= start.getTime() && date.getTime() < start.addDays(1).getTime()) { return start; } } return null; }; this._getBoxStart = function(date) { if (date.ticks === this.startDate.ticks) { return date; } var cursor = this.startDate; if (date.ticks < this.startDate.ticks) { var firstCellDuration = this.itline[0].end.ticks - this.itline[0].start.ticks; while (cursor.ticks > date.ticks) { cursor = cursor.addTime(-firstCellDuration); } return cursor; } if (calendar.viewType === 'Days') { var rowStart = this._getRowStartInDaysView(date); var offset = rowStart.getTime() - calendar.startDate.getTime(); var cell = this._getItlineCellFromTime(date.addTime(-offset)); if (cell.current) { return cell.current.start.addTime(offset); } if (cell.past) { return cell.previous.end.addTime(offset); } throw "getBoxStart(): time not found"; } else { var cell = this._getItlineCellFromTime(date); if (cell.current) { return cell.current.start; } if (cell.past) { return cell.previous.end; } if (cell.hidden) { var diff = cell.next.start.getTime() - date.getTime(); var cellduration = cell.next.end.getTime() - cell.next.start.getTime(); var rounded = Math.ceil(diff / cellduration) * cellduration; var result = cell.next.start.addTime(-rounded); return result; } throw "getBoxStart(): time not found"; } /* cursor = date; var cell = null; while (cell === null) { cell = this._getItlineCellFromTime(cursor); cursor = cursor.addMinutes(1); } return cell.start; */ }; this._getShadowCoords = function(object) { // get row var row = this._getRow(calendar.coords.y); //var object = DayPilotScheduler.moving; var e = object.event; if (typeof e.end !== 'function') { throw "e.end function is not defined"; } if (!e.end()) { throw "e.end() returns null"; } var duration = DayPilot.Date.diff(e.rawend().d, e.start().d); duration = Math.max(duration, 1); var useBox = resolved.useBox(duration); var isMilestone = e.data && e.data.type === "Milestone"; var milestoneWidth = calendar.eventHeight; //var day = e.start().getDatePart(); var startOffsetTime = 0; var x = calendar.coords.x; if (isMilestone) { x += milestoneWidth/2; } if (calendar.scale === "Manual") { var minusDurationPx = (function() { var end = calendar.getDate(calendar.coords.x, true, true); var start = end.addTime(-duration); var startPix = calendar.getPixels(start).boxLeft; var endPix = calendar.getPixels(end).boxRight; var end = Math.min(endPix, calendar.coords.x); return end - startPix; })(); var offset = Math.min(DayPilotScheduler.moveOffsetX, minusDurationPx); x = calendar.coords.x - offset; } var rowOffset = 0; var useCustomRowStart = this.viewType === 'Days' || this._rowsWithCustomStart(); if (useCustomRowStart) { //rowOffset = this.rowlist[e.part.dayIndex].start.getTime() - this.startDate.getTime(); rowOffset = this.rowlist[e.part.dayIndex].start.getTime() - this._visibleStart().getTime(); } //calendar.debug.message("rowOffset: " + rowOffset); if (useBox && !isMilestone) { //startOffsetTime = e.start().getTime() - (day.getTime() + Math.floor((e.start().getHours() * 60 + e.start().getMinutes()) / calendar.cellDuration) * calendar.cellDuration * 60 * 1000); var cell = calendar._getItlineCellFromTime(e.start()); var startInTimeline = !cell.hidden && !cell.past; startOffsetTime = e.start().getTime() - this._getBoxStart(e.start().addTime(-rowOffset)).addTime(rowOffset).getTime(); if (startInTimeline) { startOffsetTime = (function(originalTime, offset) { var oticks = calendar._getCellTicks(calendar._getItlineCellFromTime(originalTime).current); var nticks = calendar._getCellTicks(calendar._getItlineCellFromPixels(x).cell); if (oticks > nticks * 1.2) { // normally one would be fine but avoid month issues when moving to shorter month (28 vs 31 days) var sign = offset > 0 ? 1 : -1; var offset = Math.abs(offset); while (offset >= nticks) { offset -= nticks; } offset *= sign; } return offset; })(e.start(), startOffsetTime); } } var dragOffsetTime = 0; // this keeps the cell offset the same after moving if (DayPilotScheduler.moveDragStart && calendar.scale !== "Manual") { if (useBox) { var estart = e.start().addTime(-rowOffset); var boxStart = this._getBoxStart(estart); dragOffsetTime = DayPilotScheduler.moveDragStart.getTime() - boxStart.getTime(); var cellDurationTicks = calendar._getCellDuration() * 60 * 1000; dragOffsetTime = Math.floor(dragOffsetTime/cellDurationTicks) * cellDurationTicks; } else { dragOffsetTime = DayPilotScheduler.moveDragStart.getTime() - e.start().addTime(rowOffset).getTime(); } } else { // external drag //dragOffsetTime = this.cellDuration * 60000 / 2; // half cell duration dragOffsetTime = 0; // half cell duration } if (this.eventMoveToPosition) { dragOffsetTime = 0; } var start = this.getDate(x, true).addTime(-dragOffsetTime).addTime(rowOffset); if (DayPilotScheduler.resizing) { start = e.start(); } if (this.snapToGrid) { // limitation: this blocks moving events before startDate start = this._getBoxStart(start.addTime(-rowOffset)).addTime(rowOffset); } start = start.addTime(startOffsetTime); var end = start.addTime(duration); var adjustedStart = start; var adjustedEnd = end; if (useCustomRowStart) { adjustedStart = start.addTime(-rowOffset); adjustedEnd = adjustedStart.addTime(duration); var currentRowOffset = row.element.data.start.getTime() - this._visibleStart().getTime(); start = adjustedStart.addTime(currentRowOffset); end = start.addTime(duration); } var startPixels = this.getPixels(adjustedStart); var endPixels = this.getPixels(adjustedEnd); var left = (useBox) ? startPixels.boxLeft : startPixels.left; var width = (useBox) ? (endPixels.boxRight - left) : (endPixels.left - left); if (isMilestone) { width = milestoneWidth; left -= width/2; } var coords = {}; coords.top = row.top; coords.left = left; coords.row = row.element; coords.rowIndex = row.i; coords.width = width; coords.start = start; coords.end = end; coords.relativeY = calendar.coords.y - row.top; return coords; }; this._getCellDuration = function() { // approximate, needs to be updated for a specific time (used only for rounding in getShadowCoords switch (this.scale) { case "CellDuration": return this.cellDuration; case "Minute": return 1; case "Hour": return 60; case "Day": return 60*24; case "Week": return 60*24*7; case "Month": return 60*24*30; case "Year": return 60*24*365; } throw "can't guess cellDuration value"; }; this._getCellTicks = function(itc) { return itc.end.ticks - itc.start.ticks; }; this._isRowDisabled = function(y) { return this.treePreventParentUsage && this._isRowParent(y); }; this._isRowParent = function(y) { var row = this.rowlist[y]; if (row.isParent) { return true; } if (this.treeEnabled) { if (row.children && row.children.length > 0) { return true; } } return false; }; this._autoexpand = {}; this._expandParent = function() { if (!calendar.treeAutoExpand) { return; } var coords = this._getShadowCoords(DayPilotScheduler.moving); var y = coords.rowIndex; var isParent = this._isRowParent(y); var expand = this._autoexpand; if (expand.timeout && expand.y !== y) { clearTimeout(expand.timeout); expand.timeout = null; } if (isParent) { expand.y = y; if (!expand.timeout) { expand.timeout = setTimeout(function() { var collapsed = !calendar.rowlist[expand.y].expanded; if (collapsed) { calendar._toggle(expand.y); calendar._moveShadow(); } expand.timeout = null; }, 500); } } }; this._updateResizingShadow = function() { var shadowWidth = DayPilotScheduler.resizingShadow.clientWidth; var shadowLeft = DayPilotScheduler.resizingShadow.offsetLeft; var e = DayPilotScheduler.resizing.event; var border = DayPilotScheduler.resizing.dpBorder; // TODO involve rowStart for Days mode var row = calendar.rowlist[DayPilotScheduler.resizing.event.part.dayIndex]; var rowOffset = 0; if (calendar.viewType === "Days") { rowOffset = row.start.getTime() - calendar.startDate.getTime(); } else { rowOffset = row.start.getTime() - calendar._visibleStart().getTime(); } var newStart = null; var newEnd = null; var exact = !calendar.snapToGrid; if (border === 'left') { newStart = calendar.getDate(shadowLeft, exact).addTime(rowOffset); newEnd = e.rawend(); } else if (border === 'right') { newStart = e.start(); newEnd = calendar.getDate(shadowLeft + shadowWidth, exact, true).addTime(rowOffset); } DayPilotScheduler.resizingShadow.start = newStart; DayPilotScheduler.resizingShadow.end = newEnd; mre.update(); }; this._img = {}; var img = this._img; // ff, ch, ie 10+ img.canvas = function() { var canvas = document.createElement("canvas"); canvas.width = 500; canvas.height = 500; var ctx = canvas.getContext("2d"); drawBorder(); canvas_point(10, 10, "red", 10); function canvas_point(x, y, color, size) { size = size || 1; ctx.save(); ctx.fillStyle = color; ctx.fillRect(x, y, size, size); ctx.restore(); } function drawBorder() { ctx.save(); ctx.strokeStyle = "black"; ctx.rect(0,0,canvas.width,canvas.height); ctx.stroke(); ctx.restore(); } function download(canvas, name) { if (navigator.msSaveBlob) { var blob = canvas.msToBlob(); navigator.msSaveBlob(blob, name); } else { var link = document.createElement("a"); link.download = name; link.href = canvas.toDataURL(); link.click(); } } download(canvas, "image.png"); //canvas.style.display = "none"; //main.appendChild(canvas); }; this._joint = {}; var joint = this._joint; joint.findJointDivs = function (e) { var id = e.data.join; if (!id) { return DayPilot.list(); } var divs = DayPilot.list(calendar.elements.events).filter(function(item) { return item.event.data.join === id && item.event !== e; }); return divs; }; this._multiresize = {}; var mre = this._multiresize; mre.divs = []; mre.list = []; mre.forbidden = false; mre.additional = function() { var list = DayPilot.list(); var draggingSelected = calendar.multiselect.isSelected(DayPilotScheduler.resizing.event); var enabled = calendar.allowMultiResize; var list = DayPilot.list(); if (draggingSelected && enabled) { list = DayPilot.list(calendar.multiselect.divs).filter(function(item) { //return item !== DayPilotScheduler.resizing && item !== moving.moving; return item !== DayPilotScheduler.resizing; }); } var j = joint.findJointDivs(DayPilotScheduler.resizing.event); list = list.concat(j); return list; }; mre.update = function() { mre.clear(); mre.draw(); }; mre.clear = function() { DayPilot.de(mre.divs); mre.divs = []; }; mre.draw = function() { if (!DayPilotScheduler.resizing) { return; } var e = DayPilotScheduler.resizing.event; var shadow = DayPilotScheduler.resizingShadow; var startOffset = shadow.start.getTime() - e.start().getTime(); var endOffset = shadow.end.getTime() - e.end().getTime(); var rowoffset = 0; mre.list = []; mre.forbidden = false; mre.invalid = false; mre.rowoffset = rowoffset; mre.additional().each(function(item) { if (!item.event) { return; } var event = item.event; var row = calendar.rowlist[event.part.dayIndex + rowoffset]; if (!row) { // don't draw it, it's out of the grid mre.invalid = true; return; } var top = event.part.top + row.top; var height = event.part.height; if (rowoffset) { top = row.top; height = row.height; } var adjustedStart = event.start().addTime(startOffset); var adjustedEnd = event.end().addTime(endOffset); var info = {}; info.event = event; info.start = adjustedStart; info.end = adjustedEnd; //info.resource = row.id; info.overlapping = false; mre.list.push(info); var startPixels = calendar.getPixels(adjustedStart); var endPixels = calendar.getPixels(adjustedEnd); // TODO wrong, use adjustedStart, adjustedEnd var duration = DayPilot.Date.diff(event.rawend().d, event.start().d); duration = Math.max(duration, 1); var useBox = resolved.useBox(duration); var left = (useBox) ? startPixels.boxLeft : startPixels.left; var width = (useBox) ? (endPixels.boxRight - left) : (endPixels.left - left); var div = document.createElement("div"); div.style.position = "absolute"; div.style.left = left + "px"; div.style.top = top + "px"; div.style.height = height + "px"; div.style.width = width + "px"; div.style.zIndex = 101; div.style.overflow = "hidden"; div.className = calendar._prefixCssClass("_shadow"); //div.event = event; div.info = info;// store for overlap checking var inner = document.createElement("div"); inner.className = calendar._prefixCssClass("_shadow_inner"); div.appendChild(inner); calendar._maind.appendChild(div); mre.divs.push(div); }); if (mre.invalid) { var cssClass = calendar._prefixCssClass("_shadow_overlap"); DayPilot.list(mre.divs).each(function(item) { DayPilot.Util.addClass(item, cssClass); }); return; } // overlap checking must be separate, after all items are rendered DayPilot.list(mre.divs).each(function(item) { if (!item.info) { return; } var div = item; var info = item.info; var event = item.info.event; var row = calendar.rowlist[event.part.dayIndex + rowoffset]; var startPixels = calendar.getPixels(info.start); var endPixels = calendar.getPixels(info.end); var left = startPixels.left; var width = endPixels.left - left; var except = DayPilot.list(mre.list).map(function(item) { return item.event.data; }).add(DayPilotScheduler.resizing.event.data); calendar._overlappingShadow(div, row, left, width, except); if (div.overlapping) { info.overlapping = true; mre.forbidden = true; } }); }; this._multimove = {}; var mm = this._multimove; mm.divs = []; mm.list = []; mm.forbidden = false; mm.verticalAll = function() { return calendar.multiMoveVerticalMode === "All"; }; mm.additional = function() { var list = DayPilot.list(); var draggingSelected = calendar.multiselect.isSelected(DayPilotScheduler.moving.event); var enabled = calendar.allowMultiMove; var list = DayPilot.list(); if (draggingSelected && enabled) { list = DayPilot.list(calendar.multiselect.divs).filter(function(item) { return item !== DayPilotScheduler.moving && item !== moving.moving; }); } var j = joint.findJointDivs(DayPilotScheduler.moving.event); list = list.concat(j); return list; }; mm.update = function() { mm.clear(); mm.draw(); }; mm.draw = function() { if (!DayPilotScheduler.moving) { return; } var e = DayPilotScheduler.moving.event; var start = DayPilotScheduler.movingShadow.start; //var end = DayPilotScheduler.movingShadow.end; var offset = start.getTime() - e.start().getTime(); var originalRow = e.part.dayIndex; var newRow = DayPilot.indexOf(calendar.rowlist, DayPilotScheduler.movingShadow.row); var rowoffset = newRow - originalRow; if (!mm.verticalAll()) { rowoffset = 0; } mm.list = []; mm.forbidden = false; mm.invalid = false; mm.rowoffset = rowoffset; mm.additional().each(function(item) { if (!item.event) { return; } var event = item.event; var row = calendar.rowlist[event.part.dayIndex + rowoffset]; if (!row) { // don't draw it, it's out of the grid mm.invalid = true; return; } var top = event.part.top + row.top; var height = event.part.height; if (rowoffset) { top = row.top; height = row.height; } var adjustedStart = event.start().addTime(offset); var adjustedEnd = event.end().addTime(offset); var info = {}; info.event = event; info.start = adjustedStart; info.end = adjustedEnd; //info.resource = row.id; info.overlapping = false; mm.list.push(info); var startPixels = calendar.getPixels(adjustedStart); var endPixels = calendar.getPixels(adjustedEnd); var duration = DayPilot.Date.diff(event.rawend().d, event.start().d); duration = Math.max(duration, 1); var useBox = resolved.useBox(duration); var left = (useBox) ? startPixels.boxLeft : startPixels.left; var width = (useBox) ? (endPixels.boxRight - left) : (endPixels.left - left); var div = document.createElement("div"); div.style.position = "absolute"; div.style.left = left + "px"; div.style.top = top + "px"; div.style.height = height + "px"; div.style.width = width + "px"; div.style.zIndex = 101; div.style.overflow = "hidden"; div.className = calendar._prefixCssClass("_shadow"); //div.event = event; div.info = info;// store for overlap checking var inner = document.createElement("div"); inner.className = calendar._prefixCssClass("_shadow_inner"); div.appendChild(inner); calendar._maind.appendChild(div); mm.divs.push(div); }); if (mm.invalid) { var cssClass = calendar._prefixCssClass("_shadow_overlap"); DayPilot.list(mm.divs).each(function(item) { DayPilot.Util.addClass(item, cssClass); }); return; } // overlap checking must be separate, after all items are rendered DayPilot.list(mm.divs).each(function(item) { if (!item.info) { return; } var div = item; var info = item.info; var event = item.info.event; var row = calendar.rowlist[event.part.dayIndex + rowoffset]; /* // should never happen, checked above if (!row) { mm.forbidden = true; return; } */ var startPixels = calendar.getPixels(info.start); var endPixels = calendar.getPixels(info.end); var left = startPixels.left; var width = endPixels.left - left; var except = DayPilot.list(mm.list).map(function(item) { return item.event.data; }).add(DayPilotScheduler.moving.event.data); calendar._overlappingShadow(div, row, left, width, except); if (div.overlapping) { info.overlapping = true; mm.forbidden = true; } }); }; mm.clear = function() { DayPilot.de(mm.divs); mm.divs = []; }; this._moveShadow = function() { var scroll = this.nav.scroll; if (!calendar.coords) { return; } if (!DayPilotScheduler.moving) { return; } calendar._hideMessage(); var shadow = DayPilotScheduler.movingShadow; var coords = this._getShadowCoords(DayPilotScheduler.moving); if (calendar._isRowDisabled(coords.rowIndex)) { return; } var ev = DayPilotScheduler.moving.event; var linepos = 0; (function calculatePosition() { //return; var y = coords.relativeY; var row = coords.row; var linesCount = row.lines.length; var top = 0; var lh = calendar._resolved.eventHeight(); var max = row.lines.length; for (var i = 0; i < row.lines.length; i++) { var line = row.lines[i]; //if (line.isFree(coords.left, coords.width)) { if (line.isFree(coords.left, calendar.cellWidth)) { max = i; break; } } var pos = Math.floor((y - top + lh / 2) / lh); // rounded position var pos = Math.min(max, pos); // no more than max var pos = Math.max(0, pos); // no less then 0 linepos = pos; })(); var verticalAllowed = (ev.cache && typeof ev.cache.moveVDisabled !== 'undefined') ? !ev.cache.moveVDisabled : !ev.data.moveVDisabled; var horizontalAllowed = (ev.cache && typeof ev.cache.moveHDisabled !== 'undefined') ? !ev.cache.moveHDisabled :!ev.data.moveHDisabled; var multimove = !mm.additional().isEmpty(); if (multimove && calendar.multiMoveVerticalMode === "Disabled") { verticalAllowed = false; } var relY = linepos * calendar._resolved.eventHeight(); if (relY > 0) { relY -= 3; } if (verticalAllowed) { if (!this._isRowDisabled(coords.rowIndex)) { shadow.row = coords.row; shadow.style.height = Math.max(coords.row.height, 0) + 'px'; shadow.style.top = (coords.top) + 'px'; if (calendar.eventMoveToPosition) { shadow.style.top = (coords.top + relY) + "px"; shadow.style.height = "3px"; shadow.line = linepos; } } else { var oldRow = shadow.row; var dir = 1; if (oldRow) { dir = coords.rowIndex < oldRow.index ? 1 : -1; } else { //oldRow = { "index": 0}; return; } for (var i = coords.rowIndex; i !== oldRow.index; i += dir) { var row = this.rowlist[i]; if (!this._isRowDisabled(i) && !row.hidden) { shadow.style.top = (row.top) + 'px'; shadow.style.height = Math.max(row.height, 0) + 'px'; shadow.row = row; if (calendar.eventMoveToPosition) { linepos = dir > 0 ? 0 : row.lines.length - 1; shadow.style.top = (coords.top + relY) + "px"; shadow.style.height = "3px"; shadow.line = linepos; } break; } } } } else { var oldRow = calendar.rowlist[ev.part.dayIndex]; //var oldRow = this.rowlist[this._getRow(parseInt(shadow.style.top)).i]; var max = oldRow.lines.length; for (var i = 0; i < oldRow.lines.length; i++) { var line = oldRow.lines[i]; if (line.isFree(coords.left, calendar.cellWidth)) { max = i; break; } } if (!multimove) { shadow.style.height = Math.max(oldRow.height, 0) + 'px'; shadow.style.top = (oldRow.top) + 'px'; } shadow.row = oldRow; if (calendar.eventMoveToPosition && !multimove) { if (coords.row === oldRow) { shadow.style.top = (oldRow.top + relY) + "px"; shadow.style.height = "3px"; shadow.line = linepos; } else { var pos = (coords.rowIndex > oldRow.index && max > 0) ? max * calendar._resolved.eventHeight() - 3 : 0; shadow.style.top = (oldRow.top + pos) + "px"; shadow.style.height = "3px"; shadow.line = 0; } } } if (horizontalAllowed) { shadow.style.left = coords.left + 'px'; if (calendar.eventMoveToPosition) { shadow.style.width = (calendar.cellWidth) + 'px'; } else { shadow.style.width = (coords.width) + 'px'; } shadow.start = coords.start; shadow.end = coords.end; } else { shadow.style.left = ev.part.left + "px"; shadow.start = ev.start(); shadow.end = ev.rawend(); } (function checkOverlap() { var row = shadow.row; var data = ev.data; var width = coords.width; var left = coords.left; var except = DayPilot.list(mm.list).map(function(item) {return item.event.data;}).add(data); calendar._overlappingShadow(shadow, row, left, width, except); //calendar._overlappingShadow(shadow, row, left, width, data); })(); (function() { var last = calendar._lastEventMoving; // don't fire the event if there is no change if (last && last.start.getTime() === shadow.start.getTime() && last.end.getTime() === shadow.end.getTime() && last.resource === shadow.row.id) { return; } mm.update(); var args = {}; args.start = shadow.start; args.end = calendar._adjustEndOut(shadow.end); args.duration = new DayPilot.Duration(args.start, args.end); args.e = ev; //args.row = shadow.row; args.resource = shadow.row.id; args.row = calendar._createRowObject(shadow.row); args.position = shadow.line; args.overlapping = shadow.overlapping || mm.forbidden; args.allowed = true; args.left = {}; args.left.html = args.start.toString(calendar.eventMovingStartEndFormat); args.left.enabled = calendar.eventMovingStartEndEnabled; args.right = {}; args.right.html = args.end.toString(calendar.eventMovingStartEndFormat); args.right.enabled = calendar.eventMovingStartEndEnabled; args.multimove = DayPilot.list(mm.list); var info = {}; info.event = ev; info.start = args.start; info.end = args.end; //info.overlapping = false; // always false, this event is not fired if overlapping is forbidden args.multimove.splice(0, 0, info); calendar._lastEventMoving = args; if (typeof calendar.onEventMoving === 'function') { calendar.onEventMoving(args); } shadow.allowed = args.allowed; calendar._disabledShadow(shadow, args); DayPilot.Util.addClass(DayPilotScheduler.moving, calendar._prefixCssClass("_event_moving_source")); calendar._showShadowHover(DayPilotScheduler.movingShadow, args); })(); }; this._overlappingShadow = function(shadow, row, left, width, data) { if (calendar.allowEventOverlap) { return; } (function calculate() { shadow.overlapping = false; for (var i = 0; i < row.lines.length; i++) { var line = row.lines[i]; if (!line.isFree(left, width, data)) { shadow.overlapping = true; return; } } if (!calendar.allowMultiRange) { return; } var rowy = row.index; // correct ? var overlaps = DayPilot.list(mr.list).some(function(item) { var div = item.div; var rleft = parseInt(div.style.left); var rwidth = parseInt(div.style.width); var ry = item.start.y; if (shadow === div) { return false; } if (ry !== rowy) { return false; } return DayPilot.Util.overlaps(left, left + width, rleft, rleft + rwidth); }); if (overlaps) { shadow.overlapping = true; return; } })(); var overlapping = shadow.overlapping; var cssClass = calendar._prefixCssClass("_shadow_overlap"); if (overlapping) { DayPilot.Util.addClass(shadow, cssClass); } else { DayPilot.Util.removeClass(shadow, cssClass); } }; this._disabledShadow = function(shadow, args) { var cssClass = calendar._prefixCssClass("_shadow_forbidden"); if (!args.allowed || mm.invalid) { DayPilot.Util.addClass(shadow, cssClass); } else { DayPilot.Util.removeClass(shadow, cssClass); } }; this._showShadowHover = function(shadow, args) { /* * uses: * * args.left.width (optional) * args.left.html * args.left.enabled * * args.right.width (optional) * args.right.html * args.right.enabled * */ //var shadow = DayPilotScheduler.movingShadow; var space = 5; this._clearShadowHover(); var pos = {}; pos.left = parseInt(shadow.style.left); pos.top = parseInt(shadow.style.top); pos.right = pos.left + parseInt(shadow.style.width); var width = args.left.width || 10; var left = document.createElement("div"); left.style.position = "absolute"; left.style.left = (pos.left - width - space) + "px"; left.style.top = pos.top + "px"; left.style.height = calendar.eventHeight + "px"; left.style.overflow = "hidden"; left.innerHTML = args.left.html; left.className = this._prefixCssClass("_event_move_left"); if (args.left.enabled) { calendar.divHover.appendChild(left); } if (args.left.width) { left.style.width = width + "px"; } else { left.style.whiteSpace = "nowrap"; var nwidth = left.offsetWidth; var nleft = pos.left - nwidth - space; left.style.width = nwidth + "px"; left.style.left = nleft + "px"; } var right = document.createElement("div"); right.style.position = "absolute"; right.style.left = (pos.right + space) + "px"; right.style.top = pos.top + "px"; right.style.height = calendar.eventHeight + "px"; right.style.overflow = "hidden"; if (args.right.width) { right.style.width = args.right.width + "px"; } else { right.style.whiteSpace = "nowrap"; } right.innerHTML = args.right.html; right.className = this._prefixCssClass("_event_move_right"); if (args.right.enabled) { calendar.divHover.appendChild(right); } }; this._clearShadowHover = function() { calendar.divHover.innerHTML = ''; // clear }; this._loadRowHeaderColumns = function() { if (this.rowHeaderColumns) { this.rowHeaderCols = DayPilot.Util.propArray(this.rowHeaderColumns, "width"); } } this._getTotalRowHeaderWidth = function() { var totalWidth = 0; this._loadRowHeaderColumns(); if (this.rowHeaderCols) { for (var i = 0; i < this.rowHeaderCols.length; i++) { totalWidth += this.rowHeaderCols[i]; } } else { totalWidth = this.rowHeaderWidth; } return totalWidth; }; this._getAreaRowsWithMargin = function() { return this._getAreaRows(calendar.progressiveRowRenderingPreload); }; this._getAreaRows = function(margin) { //var margin = calendar.progressiveRowRenderingPreload; var margin = margin || 0; var start = 0; var end = calendar.rowlist.length; var progressive = calendar.progressiveRowRendering; if (progressive) { var area = calendar._getDrawArea(); start = area.yStart; end = area.yEnd + 1; start = Math.max(0, start - margin); end = Math.min(calendar.rowlist.length, end + margin); } return { "start": start, "end": end } }; this._autoRowHeaderWidth = function() { if (!this._visible()) { // not visible, doesn't make sense now return; } if (!this.rowHeaderWidthAutoFit) { return; } /* if (this.cellWidthSpec === 'Auto') { calendar.debug.message("AutoRowHeaderWidth turned off because CellWidthSpec is set to 'Auto'.", "warning"); return; } */ var table = this.divHeader; if (!table) { return; } if (!table.rows) { return; } var max = []; var range = calendar._getAreaRowsWithMargin(); for (var i = range.start; i < range.end; i++) { var row = table.rows[i]; if (!row) { continue; } if (row.hidden) { continue; } if (row.autofitDone) { continue; } row.autofitDone = true; //var left = 0; for (var j = 0; j < row.cells.length; j++) { var inner = row.cells[j].firstChild.firstChild; if (!inner || !inner.style) { continue; } var oldWidth = inner.style.width; var oldRight = inner.style.right; inner.style.position = "absolute"; inner.style.width = "auto"; inner.style.right = "auto"; inner.style.whiteSpace = "nowrap"; var w = inner.offsetWidth + 2; inner.style.position = ""; inner.style.width = oldWidth; inner.style.right = oldRight; inner.style.whiteSpace = ""; if (typeof max[j] === 'undefined') { max[j] = 0; } max[j] = Math.max(max[j], w); } } var maxAll = 0; var needsUpdate = false; this._loadRowHeaderColumns(); if (this.rowHeaderCols) { for (var i = 0; i < max.length; i++) { if (this.rowHeaderCols[i]) { if (max[i] > this.rowHeaderCols[i]) { this.rowHeaderCols[i] = max[i]; needsUpdate = true; } maxAll += this.rowHeaderCols[i]; } } } else { maxAll = this.rowHeaderWidth; if (this.rowHeaderWidth < max[0]) { maxAll = max[0]; needsUpdate = true; } } if (calendar.progressiveRowRendering) { //needsUpdate = true; } if (needsUpdate) { if (this._splitter) { // update header this._splitter.widths = this.rowHeaderCols; this._splitter.updateWidths(); // update cells DayPilot.Util.updatePropsFromArray(this.rowHeaderColumns, "width", this.rowHeaderCols); } if (!this.rowHeaderScrolling) { this.rowHeaderWidth = maxAll; } this._updateRowHeaderWidth(); this._updateAutoCellWidth(); } }; this._drawResHeader = function() { this._resHeaderDivBased = true; //DayPilot.puc(parent); //parent.innerHTML = ''; this._loadRowHeaderColumns(); //var rowHeaderCols = this.rowHeaderCols; //var columns = rowHeaderCols ? this.rowHeaderCols.length : 0; var totalWidth = this._getTotalRowHeaderWidth(); var wrap = this.divHeader; if (wrap) { wrap.innerHTML = ''; DayPilot.puc(wrap); } else { wrap = document.createElement("div"); wrap.onmousemove = function() { calendar._out(); }; if (!this.cssOnly) { wrap.className = this._prefixCssClass("resourceheader"); } this.divHeader = wrap; } wrap.style.width = totalWidth + "px"; wrap.style.height = calendar._innerHeightTree + "px"; wrap.rows = []; var progressive = calendar.progressiveRowRendering; if (progressive) { doNothing(); } else { var m = this.rowlist.length; for (var i = 0; i < m; i++) { calendar._drawRow(i); } } calendar._drawResScrollSpace(); this.divResScroll.appendChild(wrap); if (this.rowHeaderWidthAutoFit) { this._autoRowHeaderWidth(); } }; this._drawResHeadersProgressive = function() { if (!calendar.progressiveRowRendering) { return; } var area = this._getAreaRowsWithMargin(); for (var i = 0; i < calendar.rowlist.length; i++) { if (area.start <= i && i < area.end) { calendar._drawRow(i); } else { calendar._deleteRow(i); } } if (this.rowHeaderWidthAutoFit) { var originalWidth = calendar._getOuterRowHeaderWidth(); this._autoRowHeaderWidth(); var newWidth = calendar._getOuterRowHeaderWidth(); if (newWidth !== originalWidth) { var originalCellWidth = this.cellWidth; this._calculateCellWidth(); var newCellWidth = this.cellWidth; if (newCellWidth !== originalCellWidth) { this._prepareItline(); this._drawTimeHeader(); this._updateHeight(); this._loadEvents(); } } } }; this._drawResScrollSpace = function() { /* if (calendar.nav.resScrollSpace) { return; } */ var wrap = calendar.divHeader; var rowHeaderCols = this.rowHeaderCols; var columns = rowHeaderCols ? this.rowHeaderCols.length : 0; var totalWidth = this._getTotalRowHeaderWidth(); //var r = table.insertRow(-1); //var c = r.insertCell(-1); var c = document.createElement("div"); c.style.position = "absolute"; c.style.top = this._innerHeightTree + "px"; c.colSpan = columns + 1; c.style.width = totalWidth + "px"; c.style.height = (calendar.divResScroll.clientHeight + 20) + "px"; wrap.appendChild(c); calendar.nav.resScrollSpace = c; //c.style.borderRight = "1px solid " + this.borderColor; if (!this.cssOnly) { c.style.backgroundColor = this.hourNameBackColor; c.style.cursor = 'default'; } c.setAttribute("unselectable", "on"); if (!this.cssOnly) { c.className = this._prefixCssClass('rowheader'); c.style.fontSize = "1px"; c.innerHTML = " "; } if (this.cssOnly) { var div = document.createElement("div"); div.style.position = "relative"; div.style.height = "100%"; div.className = this._prefixCssClass('_rowheader'); c.appendChild(div); } }; this._deleteRow = function(i) { var row = calendar.divHeader.rows[i]; if (!row) { return; } DayPilot.de(row.cells); calendar.divHeader.rows[i] = null; }; this._drawRowForced = function(i) { this._deleteRow(i); this._drawRow(i); } this._drawRow = function(i) { var wrap = calendar.divHeader; var divHeader = this.divHeader; if (divHeader.rows[i]) { // already rendered return; } var rowHeaderCols = this.rowHeaderCols; var columns = rowHeaderCols ? this.rowHeaderCols.length : 0; var totalWidth = this._getTotalRowHeaderWidth(); var row = this.rowlist[i]; if (!row) { // not found return; } //var node = this.tree[i]; if (row.hidden) { return; } var args = this._doBeforeRowHeaderRender(row); divHeader.rows[i] = {}; divHeader.rows[i].cells = []; var c = document.createElement("div"); c.style.position = "absolute"; c.style.top = row.top + "px"; c.row = row; c.index = i; var props = args.row; var width = rowHeaderCols ? rowHeaderCols[0] : this.rowHeaderWidth; c.style.width = (width) + "px"; c.style.border = "0px none"; if (!this.cssOnly) { c.style.borderRight = "1px solid " + this.borderColor; c.style.backgroundColor = typeof props.backColor === 'undefined' ? calendar.hourNameBackColor : props.backColor; c.style.fontFamily = this.headerFontFamily; c.style.fontSize = this.headerFontSize; c.style.color = this.headerFontColor; c.style.cursor = 'default'; c.style.padding = '0px'; } if (props.toolTip) { c.title = props.toolTip; } c.setAttribute("unselectable", "on"); //c.setAttribute('resource', row.id); c.onmousemove = calendar._onResMouseMove; c.onmouseout = calendar._onResMouseOut; c.onmouseup = calendar._onResMouseUp; c.oncontextmenu = calendar._onResRightClick; c.onclick = calendar._onResClick; c.ondblclick = calendar._onResDoubleClick; var div = document.createElement("div"); div.style.width = (width) + "px"; div.setAttribute("unselectable", "on"); div.className = this.cssOnly ? this._prefixCssClass('_rowheader') : this._prefixCssClass('rowheader'); if (props.cssClass) { DayPilot.Util.addClass(div, props.cssClass); } if (props.backColor) { div.style.background = props.backColor; } div.style.height = (row.height) + "px"; div.style.overflow = 'hidden'; div.style.position = 'relative'; var inner = document.createElement("div"); //inner.style.width = "100%"; inner.setAttribute("unselectable", "on"); inner.className = this.cssOnly ? this._prefixCssClass('_rowheader_inner') : ""; //inner.style.position = 'absolute'; div.appendChild(inner); var moving = this.rowMoveHandling !== "Disabled"; var dragHandleWidth = 10; var areas = props.areas || []; if (moving && !props.moveDisabled) { // add moving handle areas.push({ "v": "Hover", "w": dragHandleWidth, "bottom": 0, "top": 0, "left": 0, "css": calendar._prefixCssClass("_rowmove_handle"), "action": "Move" }); } var ro = calendar._createRowObject(row); DayPilot.Areas.attach(div, ro, { "areas": areas, "allowed": function() { return !rowmoving.row; } }); var border = document.createElement("div"); border.style.position = "absolute"; border.style.bottom = "0px"; border.style.width = "100%"; border.style.height = "1px"; if (this.cssOnly) { border.className = this._prefixCssClass("_resourcedivider"); } else { border.style.backgroundColor = this.borderColor; } //div.dpDivider = border; div.appendChild(border); (function drawText() { if (calendar.treeEnabled && !row.isNewRow) { var left = row.level * calendar.treeIndent + calendar.treeImageMarginLeft; if (moving) { left += dragHandleWidth; } var width = 10; var expand = document.createElement("div"); expand.style.width = "10px"; expand.style.height = width + "px"; expand.style.backgroundRepeat = "no-repeat"; expand.style.position = 'absolute'; expand.style.left = left + 'px'; expand.style.top = calendar.treeImageMarginTop + "px"; if (!row.loaded && row.children.length === 0) { if (calendar.treeImageExpand && !calendar.cssOnly) { expand.style.backgroundImage = "url('" + calendar.treeImageExpand + "')"; } expand.className = calendar.cssOnly ? calendar._prefixCssClass('_tree_image_expand') : calendar._prefixCssClass('tree_image_expand'); expand.style.cursor = 'pointer'; expand.index = i; expand.onclick = function(ev) { calendar._loadNode(this.index); ev = ev || window.event; ev.cancelBubble = true; }; } else if (row.children.length > 0) { if (row.expanded) { if (calendar.treeImageCollapse && !calendar.cssOnly) { expand.style.backgroundImage = "url('" + calendar.treeImageCollapse + "')"; } expand.className = calendar.cssOnly ? calendar._prefixCssClass('_tree_image_collapse') : calendar._prefixCssClass('tree_image_collapse'); } else { if (calendar.treeImageExpand && !calendar.cssOnly) { expand.style.backgroundImage = "url('" + calendar.treeImageExpand + "')"; } expand.className = calendar.cssOnly ? calendar._prefixCssClass('_tree_image_expand') : calendar._prefixCssClass('tree_image_expand'); } expand.style.cursor = 'pointer'; expand.index = i; expand.onclick = function(ev) { calendar._toggle(this.index); ev = ev || window.event; ev.cancelBubble = true; }; } else { if (calendar.treeImageNoChildren && !calendar.cssOnly) { //expand.src = calendar.treeImageNoChildren; expand.style.backgroundImage = "url('" + calendar.treeImageNoChildren + "')"; } expand.className = calendar.cssOnly ? calendar._prefixCssClass('_tree_image_no_children') : calendar._prefixCssClass('tree_image_no_children'); } inner.appendChild(expand); } var text = document.createElement("div"); if (calendar.treeEnabled) { text.style.marginLeft = (left + width) + "px"; } else if (!calendar.cssOnly) { text.style.marginLeft = "4px"; } text.innerHTML = props.html; c.textDiv = text; inner.appendChild(text); })(); c.appendChild(div); if (props.areas) { for (var j = 0; j < props.areas.length; j++) { var area = props.areas[j]; var v = area.v || "Visible"; if (v !== "Visible") { continue; } var r = calendar._createRowObject(row); var a = DayPilot.Areas.createArea(div, r, area); div.appendChild(a); } } wrap.appendChild(c); divHeader.rows[i].cells.push(c); if (!row.columns || row.columns.length === 0) { c.colSpan = columns > 0 ? columns : 1; div.style.width = totalWidth + "px"; } else { var left = width; for (var j = 1; j < columns; j++) { //var c = r.insertCell(-1); var c = document.createElement("div"); c.style.position = "absolute"; c.style.top = row.top + "px"; c.style.left = left + "px"; wrap.appendChild(c); divHeader.rows[i].cells.push(c); c.row = row; c.index = i; //c.style.width = (rowHeaderCols[j]) + "px"; if (!this.cssOnly) { c.style.borderRight = "1px solid " + this.borderColor; //c.style.borderBottom = "1px solid " + this.borderColor; c.style.backgroundColor = props.backColor; c.style.fontFamily = this.headerFontFamily; c.style.fontSize = this.headerFontSize; c.style.color = this.headerFontColor; c.style.cursor = 'default'; c.style.padding = '0px'; } if (props.toolTip) { c.title = props.toolTip; } c.setAttribute("unselectable", "on"); if (!this.cssOnly) { c.className = this._prefixCssClass('rowheader'); } //c.setAttribute('resource', row.id); c.onmousemove = calendar._onResMouseMove; c.onmouseout = calendar._onResMouseOut; c.onmouseup = calendar._onResMouseUp; c.oncontextmenu = calendar._onResRightClick; c.onclick = calendar._onResClick; c.ondblclick = calendar._onResDoubleClick; var div = document.createElement("div"); var w = this.cssOnly ? rowHeaderCols[j] : rowHeaderCols[j] - 1; left += w; if (props.backColor) { div.style.backgroundColor = props.backColor; } div.style.width = w + "px"; div.style.height = (row.height) + "px"; div.style.overflow = 'hidden'; div.style.position = 'relative'; div.setAttribute("unselectable", "on"); if (this.cssOnly) { DayPilot.Util.addClass(div, this._prefixCssClass("_rowheader")); DayPilot.Util.addClass(div, this._prefixCssClass("_rowheadercol")); DayPilot.Util.addClass(div, this._prefixCssClass("_rowheadercol" + j)); } if (props.cssClass) { DayPilot.Util.addClass(div, props.cssClass); } var inner = document.createElement("div"); //inner.style.position = 'absolute'; inner.setAttribute("unselectable", "on"); if (this.cssOnly) { inner.className = this._prefixCssClass("_rowheader_inner"); } div.appendChild(inner); var border = document.createElement("div"); border.style.position = "absolute"; border.style.bottom = "0px"; border.style.width = "100%"; border.style.height = "1px"; border.className = this._prefixCssClass("_resourcedivider"); if (!this.cssOnly) { border.style.backgroundColor = this.borderColor; } div.appendChild(border); var text = document.createElement("div"); if (!this.cssOnly) { text.style.marginLeft = '4px'; } var col = props.columns[j - 1]; var innerHTML = col && col.html ? col.html : ""; text.innerHTML = innerHTML; c.textDiv = text; inner.appendChild(text); c.appendChild(div); } } }; this._onResRightClick = function() { var row = this.row; if (row.contextMenu) { row.contextMenu.show(calendar._createRowObject(row)); } return false; }; this._onResClick = function(ev) { if (rowtools.cancelClick) { return; } var row = this.row; var r = calendar._createRowObject(row, this.index); if (row.isNewRow) { calendar._rowtools.edit(row); return; } calendar._rowClickDispatch(r, ev.ctrlKey, ev.shiftKey, ev.metaKey); }; this._onResDoubleClick = function(ev) { if (calendar.timeouts.resClick) { for (var toid in calendar.timeouts.resClick) { window.clearTimeout(calendar.timeouts.resClick[toid]); } calendar.timeouts.resClick = null; } var row = this.row; var e = calendar._createRowObject(row, this.index); if (calendar._api2()) { var args = {}; args.resource = e; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onRowDoubleClick === 'function') { calendar.onRowDoubleClick(args); if (args.preventDefault.value) { return; } } switch (calendar.rowDoubleClickHandling) { case 'PostBack': calendar.rowDoubleClickPostBack(e); break; case 'CallBack': calendar.rowDoubleClickCallBack(e); break; case 'Select': calendar._rowSelectDispatch(row, ev.ctrlKey, ev.shiftKey, ev.metaKey); break; case 'Edit': calendar._rowtools.edit(row); break; } if (typeof calendar.onRowDoubleClicked === 'function') { calendar.onRowDoubleClicked(args); } } else { switch (calendar.rowDoubleClickHandling) { case 'PostBack': calendar.rowDoubleClickPostBack(e); break; case 'CallBack': calendar.rowDoubleClickCallBack(e); break; case 'JavaScript': calendar.onRowDoubleClick(e); break; case 'Select': calendar._rowSelectDispatch(row, ev.ctrlKey, ev.shiftKey, ev.metaKey); break; case 'Edit': calendar._rowtools.edit(row); break; } } }; this.rowDoubleClickPostBack = function(e, data) { var params = {}; params.resource = e; this._postBack2("RowDoubleClick", params, data); }; this.rowDoubleClickCallBack = function(e, data) { var params = {}; params.resource = e; this._callBack2("RowDoubleClick", params, data); }; this._onTimeClick = function(ev) { var cell = {}; cell.start = this.cell.start; cell.level = this.cell.level; cell.end = this.cell.end; if (!cell.end) { cell.end = new DayPilot.Date(cell.start).addMinutes(calendar.cellDuration); } calendar._timeHeaderClickDispatch(cell); }; this._createRowObject = function(row) { return new DayPilot.Row(row, calendar); }; this._ensureRowData = function(i) { var row = this.rowlist[i]; if (!row.events) { row.resetEvents(); } if (row.data) { return; } row.data = {}; // to be used later during client-side operations // rowStart row.data.start = new DayPilot.Date(row.start); // rowStartTicks row.data.startTicks = row.data.start.getTime(); // rowEnd var duration = this._visibleEnd().getTime() - this._visibleStart().getTime(); row.data.end = resolved.isResourcesView() ? row.data.start.addTime(duration) : row.data.start.addDays(1); // rowEndTicks row.data.endTicks = row.data.end.getTime(); // rowOffset if (calendar.viewType === "Days") { row.data.offset = row.start.getTime() - this.startDate.getTime(); } else { row.data.offset = row.start.getTime() - this._visibleStart().getTime(); } row.data.i = i; }; this._loadEvents = function(events) { if (events) { this.events.list = events; } else if (!this.events.list) { this.events.list = []; } eventloading.prepareRows(true); var list = this.events.list; var listlength = list.length; var ober = typeof this.onBeforeEventRender === 'function'; var rows; var isRes = calendar.viewType === "Resources"; for (var j = 0; j < listlength; j++) { var edata = list[j]; if (!edata) { continue; } if (ober) { this._doBeforeEventRender(j); } if (edata.resource === "*") { rows = calendar.rowlist; } else if (isRes) { rows = eventloading.rowcache[edata.resource]; } else if (calendar.viewType === "Days") { rows = calendar.rowlist; } else if (calendar.viewType === "Gantt") { rows = eventloading.rowcache[edata.id]; } for (var x = 0; rows && x < rows.length; x++) { var row = rows[x]; var ep = this._loadEvent(edata, row); if (!ep) { continue; } if (ober) { ep.cache = this._cache.events[j]; } } } // sort events inside rows for (var i = 0; i < this.rowlist.length; i++) { var row = this.rowlist[i]; this._loadRow(row); } this._updateRowHeights(); }; // assumes rows collection is created this._loadEventsOld = function(events) { var loadCache = []; var updatedRows = []; var append = null; if (events && add) { // append new events var supplied = events; var append = []; for (var i = 0; i < supplied.length; i++) { var e = supplied[i]; var found = false; for (var j = 0; j < this.events.list.length; j++) { var ex = this.events.list[j]; // this causes changed events to be rendered again if (ex.id === e.id && ex.start.toString() === e.start.toString() && ex.resource === e.resource) { //if (ex.id === e.id) { var rows = calendar.events._removeFromRows(ex); updatedRows = updatedRows.concat(rows); this.events.list[j] = e; found = true; break; } } if (!found) { append.push(e); } } this.events.list = this.events.list.concat(append); //events = this.events; } else if (events) { this.events.list = events; } else if (!this.events.list) { this.events.list = []; } var list = append || this.events.list; if (events) { this.events.list = events; } else if (!this.events.list) { this.events.list = []; } var list = this.events.list; var eventsLength = list.length; if (typeof this.onBeforeEventRender === 'function') { var start = append ? this.events.list.length - append.length : 0; //var start = 0; var end = this.events.list.length; for (var i = start; i < end; i++) { this._doBeforeEventRender(i); } } var useLoadCache = !this._containsDuplicateResources(); var optimizedLoading = true; if (optimizedLoading) { var resetEvents = !append || typeof row.events === "undefined"; eventloading.prepareRows(resetEvents); for (var j = 0; list && j < eventsLength; j++) { if (loadCache[j]) { continue; } var edata = list[j]; if (!edata) { continue; } var rows = []; if (edata.resource === "*") { rows = calendar.rowlist; } else if (calendar.viewType === "Days") { rows = calendar.rowlist; } else if (calendar.viewType === "Gantt") { rows = eventloading.rowcache[edata.id]; } else { rows = eventloading.rowcache[edata.resource]; } for (var x = 0; rows && x < rows.length; x++) { var row = rows[x]; var ep = this._loadEvent(edata, row); if (!ep) { continue; } if (typeof this.onBeforeEventRender === 'function') { ep.cache = this._cache.events[j + start]; } updatedRows.push(row.index); } } } else { // first, load event parts into rows for (var i = 0; i < this.rowlist.length; i++) { var row = this.rowlist[i]; if (!append || typeof row.events === "undefined") { row.resetEvents(); } //row.lines = []; calendar._ensureRowData(i); if (this._isRowDisabled(i)) { continue; } for (var j = 0; list && j < eventsLength; j++) { if (loadCache[j]) { continue; } var e = list[j]; var ep = this._loadEvent(e, row); if (!ep) { continue; } if (typeof this.onBeforeEventRender === 'function') { ep.cache = this._cache.events[j + start]; } updatedRows.push(i); // load cache is disabled to allow rows with duplicate ids if (useLoadCache) { if (ep.data.resource !== "*" && ep.part.start.getTime() === ep.start().getTime() && ep.part.end.getTime() === ep.rawend().getTime()) { loadCache[j] = true; } } } } } /* DayPilot.dynlist(this.rowlist).each(function(item) { calendar._loadRow(item); }); */ // sort events inside rows for (var i = 0; i < this.rowlist.length; i++) { var row = this.rowlist[i]; this._loadRow(row); } this._updateRowHeights(); return DayPilot.ua(updatedRows); }; this._eventloading = {}; var eventloading = this._eventloading; eventloading.rowCache = {}; eventloading.prepareRows = function(resetEvents) { eventloading.rowcache = {}; // initialize for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; if (resetEvents) { row.resetEvents(); } calendar._ensureRowData(i); if (!row.id) { continue; } var key = row.id.toString(); if (!eventloading.rowcache[key]) { eventloading.rowcache[key] = []; } eventloading.rowcache[key].push(row); } }; eventloading.loadEvent = function(edata) { }; this._containsDuplicateResources = function() { var idlist = {}; if (calendar.viewType !== "Resources") { return false; } for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; var id = row.id; if (idlist[id]) { return true; } idlist[id] = true; } return false; }; this._doBeforeEventRender = function(i) { var cache = this._cache.events; var data = this.events.list[i]; var evc = {}; // make a copy for (var name in data) { evc[name] = data[name]; } if (typeof this.onBeforeEventRender === 'function') { var args = {}; args.e = evc; this.onBeforeEventRender(args); } cache[i] = evc; }; // internal this._loadRow = function(row) { row.lines = []; row.sections = null; //row.blocks = []; if (row.isNewRow) { return; } if (this.sortDirections) { row.events.sort(this._eventComparerCustom); } else { row.events.sort(this._eventComparer); } var collapsible = calendar.groupConcurrentEvents; if (collapsible) { for (var i = 0; i < row.blocks.length; i++) { row.blocks[i].events = []; } } // put into lines for (var j = 0; j < row.events.length; j++) { var e = row.events[j]; row.putIntoLine(e); if (collapsible) { row.putIntoBlock(e); } } //row.calculateUtilization(); // calculate line tops var lineTop = 0; for (var i = 0; i < row.lines.length; i++) { var line = row.lines[i]; line.top = lineTop; lineTop += (line.height || row.eventHeight) * this.eventStackingLineHeight/100; } if (collapsible) { for (var j = 0; j < row.blocks.length; j++) { var block = row.blocks[j]; block.lines = []; block.events.sort(this._eventComparerCustom); for (var k = 0; k < block.events.length; k++) { var e = block.events[k]; block.putIntoLine(e); } if (block.lines.length <= calendar.groupConcurrentEventsLimit) { block.expanded = true; } // calculate line tops var lineTop = 0; for (var i = 0; i < block.lines.length; i++) { var line = block.lines[i]; line.top = lineTop; lineTop += (line.height || row.eventHeight) * this.eventStackingLineHeight/100; } } } }; // internal this._loadRows = function(rows) { // row indices rows = DayPilot.ua(rows); // unique for (var i = 0; i < rows.length; i++) { var ri = rows[i]; calendar._loadRow(calendar.rowlist[ri]); } for (var i = 0; i < rows.length; i++) { var ri = rows[i]; var row = calendar.rowlist[ri]; calendar._updateEventPositionsInRow(row); } }; this._rowsWithCustomStart = function() { var start = calendar.scale === "Manual" ? calendar.itline[0].start : calendar.startDate; return DayPilot.list(calendar.rowlist).some(function(item) { if (!item.start) { return false; } return item.start.getTime() !== new DayPilot.Date(start).getTime(); }); }; // internal // returns ep if the event was added to this row, otherwise null this._loadEvent = function(e, row) { var start = new DayPilot.Date(e.start); var end = new DayPilot.Date(e.end); /* if (calendar.eventEndSpec === "Date") { end = end.getDatePart().addDays(1); } */ end = calendar._adjustEndIn(end); var startTicks = start.ticks; var endTicks = end.ticks; if (endTicks < startTicks) { // skip invalid events return null; } var cache = null; if (typeof calendar.onBeforeEventRender === 'function') { var index = DayPilot.indexOf(calendar.events.list, e); cache = calendar._cache.events[index]; } if (cache) { if (cache.hidden) { return null; } } else if (e.hidden) { return null; } // belongs here var belongsHere = false; switch (this.viewType) { case 'Days': belongsHere = !(endTicks <= row.data.startTicks || startTicks >= row.data.endTicks) || (startTicks === endTicks && startTicks === row.data.startTicks); break; case 'Resources': belongsHere = (row.id === e.resource || row.id === "*" || e.resource === "*") && (!(endTicks <= row.data.startTicks || startTicks >= row.data.endTicks) || (startTicks === endTicks && startTicks === row.data.startTicks)); break; case 'Gantt': belongsHere = (row.id === e.id) && !(endTicks <= row.data.startTicks || startTicks >= row.data.endTicks); break; } if (!belongsHere) { return null; } var ep = new DayPilot.Event(e, calendar); // event part ep.part.dayIndex = row.data.i; //ep.part.start = row.data.startTicks < startTicks ? ep.start() : row.data.start; ep.part.start = row.data.startTicks < startTicks ? start : row.data.start; //ep.part.end = row.data.endTicks > endTicks ? ep.end() : row.data.end; ep.part.end = row.data.endTicks > endTicks ? end : row.data.end; var partStartPixels = this.getPixels(ep.part.start.addTime(-row.data.offset)); var partEndPixels = this.getPixels(ep.part.end.addTime(-row.data.offset)); //if (ep.part.start.getTime() === ep.part.end.getTime()) { if (ep.part.start.ticks === ep.part.end.ticks) { partEndPixels = this.getPixels(ep.part.end.addTime(-row.data.offset).addTime(1)); } if (cache && cache.height) { ep.part.height = cache.height; } var left = partStartPixels.left; var right = partEndPixels.left; // events in the hidden areas if (left === right && (partStartPixels.cut || partEndPixels.cut)) { return null; } ep.part.box = resolved.useBox(endTicks - startTicks); var milestoneWidth = calendar.eventHeight; if (e.type === "Milestone") { var width = e.width || milestoneWidth; ep.part.end = ep.part.start; ep.part.left = left - width /2; ep.part.width = width; ep.part.barLeft = 0; ep.part.barWidth = width; } else if (ep.part.box) { var boxLeft = partStartPixels.boxLeft; var boxRight = partEndPixels.boxRight; //var itc = this._getItlineCellFromPixels() //ep.part.left = Math.floor(left / this.cellWidth) * this.cellWidth; ep.part.left = boxLeft; ep.part.width = boxRight - boxLeft; ep.part.barLeft = Math.max(left - ep.part.left, 0); // minimum 0 ep.part.barWidth = Math.max(right - left, 1); // minimum 1 } else { ep.part.left = left; ep.part.width = Math.max(right - left, 0); ep.part.barLeft = 0; ep.part.barWidth = Math.max(right - left - 1, 1); } if (typeof calendar.onEventFilter === "function" && calendar.events._filterParams) { var args = {}; args.filter = calendar.events._filterParams; args.visible = true; args.e = ep; calendar.onEventFilter(args); if (!args.visible) { return null; } } row.events.push(ep); return ep; }; this._eventComparer = function(a, b) { if (!a || !b || !a.start || !b.start) { return 0; // no sorting, invalid arguments } var byStart = a.start().ticks - b.start().ticks; if (byStart !== 0) { return byStart; } var byEnd = b.end().ticks - a.end().ticks; // desc return byEnd; }; this._eventComparerCustom = function(a, b) { if (!a || !b) { return 0; // no sorting, invalid arguments } if (!a.data || !b.data || !a.data.sort || !b.data.sort || a.data.sort.length === 0 || b.data.sort.length === 0) { // no custom sorting, using default sorting (start asc, end asc); return calendar._eventComparer(a, b); } var result = 0; var i = 0; while (result === 0 && a.data.sort[i] && b.data.sort[i]) { if (a.data.sort[i] === b.data.sort[i]) { result = 0; } else { result = calendar._stringComparer(a.data.sort[i], b.data.sort[i], calendar.sortDirections[i]); } i++; } return result; }; this._stringComparer = function(a, b, direction) { var asc = (direction !== "desc"); var aFirst = asc ? -1 : 1; var bFirst = -aFirst; if (a === null && b === null) { return 0; } // nulls first if (b === null) { // b is smaller return bFirst; } if (a === null) { return aFirst; } //return asc ? a.localeCompare(a, b) : -a.localeCompare(a, b); var ar = []; ar[0] = a; ar[1] = b; ar.sort(); return a === ar[0] ? aFirst : bFirst; }; this._rowSelectDispatch = function(row, ctrl, shift, meta) { if (calendar._api2()) { var index = DayPilot.indexOf(calendar.rowlist, row); var e = calendar._createRowObject(row, index); var selected = DayPilot.indexOf(rowtools.selected, row) !== -1; var change = selected ? "deselected" : "selected"; var args = {}; args.row = e; args.selected = selected; args.ctrl = ctrl; args.shift = shift; args.meta = meta; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onRowSelect === 'function') { calendar.onRowSelect(args); if (args.preventDefault.value) { return; } } switch (calendar.rowSelectHandling) { case 'PostBack': calendar.rowSelectPostBack(e, change); break; case 'CallBack': calendar.rowSelectCallBack(e, change); break; case 'Update': rowtools.select(row, ctrl, shift, meta); break; } if (typeof calendar.onRowSelected === 'function') { args.selected = DayPilot.indexOf(rowtools.selected, row) !== -1; calendar.onRowSelected(args); } } else { rowtools.select(row, ctrl, shift); var index = DayPilot.indexOf(calendar.rowlist, row); var e = calendar._createRowObject(row, index); var selected = DayPilot.indexOf(rowtools.selected, row) !== -1; var change = selected ? "deselected" : "selected"; switch (calendar.rowSelectHandling) { case 'PostBack': calendar.rowSelectPostBack(e, change); break; case 'CallBack': calendar.rowSelectCallBack(e, change); break; case 'JavaScript': calendar.onRowSelect(e, change); break; } } }; this.rowSelectPostBack = function(r, change, data) { var params = {}; params.resource = r; params.change = change; this._postBack2('RowSelect', params, data); }; this.rowSelectCallBack = function(r, change, data) { var params = {}; params.resource = r; params.change = change; this._callBack2('RowSelect', params, data); }; this.rows = {}; this.rows.selection = {}; var rowsel = this.rows.selection; rowsel.get = function() { var list = []; DayPilot.list(rowtools.selected).each(function(item) { list.push(calendar._createRowObject(item)); }); return list; }; rowsel.clear = function() { rowtools.clearSelection(); }; rowsel.add = function(row) { if (!row || !row.isRow) { throw "DayPilot.Scheduler.rows.selection.add(): DayPilot.Row object expected"; } var alreadyThere = DayPilot.list(rowtools.selected).some(function(item) { return item === row.$.row; }); if (!alreadyThere) { rowtools.selected.push(row.$.row); } rowtools._updateHighlighting(); }; this.rows.all = function() { var list = []; for(var i = 0; i < calendar.rowlist.length; i++) { var r = calendar._createRowObject(calendar.rowlist[i]); list.push(r); } return rowArray(list); }; this.rows.each = function(f) { calendar.rows.all().each(f); }; this.rows.filter = function(param) { calendar.rows._filterParams = param; calendar._update({"immediateEvents": true}); }; this.rows.find = function(id, start) { var rows = calendar.rows.all(); for (var i = 0; i < rows.length; i++) { var item = rows[i]; if (item.id === id) { if (typeof start === "string") { if (start === item.start.toString()) { return item; } } else { return item; } } } }; this.rows.load = function(url) { DayPilot.ajax({ "url": url, "success": function(args) { var r = args.request; var data = DayPilot.Util.parseJSON(r.responseText); if (DayPilot.isArray(data)) { calendar.resources = data; if (calendar._initialized) { calendar.update(); } } } }); }; this.rows.expand = function(levels) { var rows = []; var level = levels || 1; for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; var withinLevel = level === -1; if (row.level < level) { withinLevel = true; } if (withinLevel && !row.expanded && row.children && row.children.length > 0) { rows.push(row.index); } } if (rows.length === 0) { return; } if (rows.length === 1) { calendar._toggle(rows[0]); } else { for (var i = 0; i < rows.length; i++) { var index = rows[i]; var row = calendar.rowlist[index]; row.expanded = true; } calendar._update(); } }; this.rows.expandAll = function() { calendar.rows.expand(-1); }; this.rows.headerHide = function() { calendar._rowHeaderHidden = true; calendar._updateRowHeaderWidthOuter(); calendar._updateAutoCellWidth(); }; this.rows.headerShow = function() { calendar._rowHeaderHidden = false; calendar._updateRowHeaderWidthOuter(); calendar._updateAutoCellWidth(); }; this.rows.headerToggle = function() { if (calendar._rowHeaderHidden) { calendar.rows.headerShow(); } else { calendar.rows.headerHide(); } }; this._rowMoveDispatch = function() { var source = rowmoving.source; var target = rowmoving.target; var position = rowmoving.position; rowtools.resetMoving(); if (calendar._api2()) { var args = {}; args.source = calendar._createRowObject(source); args.target = calendar._createRowObject(target); args.position = position; args.preventDefault = function() { this.preventDefault.value = true; }; if (typeof calendar.onRowMove === "function") { calendar.onRowMove(args); if (args.preventDefault.value) { return; } } switch (calendar.rowMoveHandling) { case "Update": rowtools.move(args); break; case "CallBack": calendar.rowMoveCallBack(args.source, args.target, args.position); break; case "PostBack": calendar.rowMovePostBack(args.source, args.target, args.position); break; case "Notify": rowtools.move(args); calendar.rowMoveNotify(args.source, args.target, args.position); break; } if (typeof calendar.onRowMoved === "function") { calendar.onRowMoved(args); } } else { //rowtools.move(args); var source = calendar._createRowObject(source); var target = calendar._createRowObject(target); var position = position; switch (calendar.rowMoveHandling) { case "CallBack": calendar.rowMoveCallBack(source, target, position); break; case "PostBack": calendar.rowMovePostBack(source, target, position); break; case "JavaScript": calendar.onRowMove(source, target, position); break; } } }; /** * @param rows Array of strings (row IDs) * @private */ this._loadSelectedRows = function(rows) { var list = DayPilot.list(rows); rowtools.selected = []; list.each(function(item) { var row = calendar._findRowByResourceId(item); if (row) { rowtools.selected.push(row); } }); rowtools._updateHighlighting(); }; this._rowtools = {}; var rowtools = this._rowtools; rowtools.edit = function(row) { var input = rowtools._textarea(row); }; /* rowtools.findFirst = function(ro) { if (ro._row) { return ro._row; } return calendar._findRowByResourceId(ro.id); }; */ rowtools.createOverlay = function(row) { var width = calendar._getTotalRowHeaderWidth(); var css = calendar._prefixCssClass("_rowmove_source"); var div = DayPilot.Util.div(calendar.divHeader, 0, row.top, width, row.height); div.className = css; row.moveOverlay = div; /* var div = document.createElement("div"); div.style.position = "absolute"; div.style.left = "0px"; div.style.right = "0px"; div.style.top = "0px"; div.style.bottom = "0px"; div.className = calendar._prefixCssClass("_rowmove_source"); var r = rowtools._findTableRow(row); var c = r.cells[0]; c.firstChild.appendChild(div); c.movingoverlay = div; */ }; rowtools.deleteOverlay = function(row) { DayPilot.de(row.moveOverlay); row.moveOverlay = null; /* var r = rowtools._findTableRow(row); var c = r.cells[0]; if (c.movingoverlay) { DayPilot.de(c.movingoverlay); }*/ }; rowtools._textarea = function(row) { var r = rowtools._findTableRow(row); var c = r.cells[0]; if (c.input) { return c.input; } var width = c.clientWidth; if (row.isNewRow) { width = calendar._getOuterRowHeaderWidth(); } var input = document.createElement("textarea"); input.style.position = "absolute"; input.style.top = "0px"; input.style.left = "0px"; input.style.width = width + "px"; input.style.height = row.height + "px"; input.style.border = "0px none"; input.style.overflow = "hidden"; input.style.boxSizing = "border-box"; input.style.resize = "none"; //input.style.lineHeight = row.height + "px"; var object = c.textDiv; input.style.fontFamily = DayPilot.gs(object, 'fontFamily') || DayPilot.gs(object, 'font-family'); input.style.fontSize = DayPilot.gs(object, 'fontSize') || DayPilot.gs(object, 'font-size'); input.value = row.html; c.firstChild.appendChild(input); c.input = input; var remove = function() { try { c.input.parentNode.removeChild(c.input); } catch(e) { doNothing(); } c.input = null; }; input.focus(); input.onblur = function() { input.onblur = null; var newText = input.value; var index = DayPilot.indexOf(calendar.rowlist, row); remove(); if (!input.canceled) { calendar._rowEditDispatch(row, newText); } }; input.onkeydown = function(e) { var keynum = (window.event) ? event.keyCode : e.keyCode; if (keynum === 27) { input.canceled = true; remove(); } if (keynum === 13) { input.onblur(); return false; } return true; }; if (input.setSelectionRange) { input.setSelectionRange(0, 9999); // using this instead of .select() that is not fully supported in mobile Safari } else { input.select(); } return input; }; rowtools.selected = []; rowtools.select = function(row, ctrl, shift, meta) { var selected = DayPilot.indexOf(rowtools.selected, row) !== -1; if (ctrl || meta) { if (selected) { rowtools.unselect(row); DayPilot.rfa(rowtools.selected, row); return; } } else { selected = false; rowtools.clearSelection(); } rowtools._highlight(row); // selected list if (!selected) { rowtools.selected.push(row); } }; rowtools._updateHighlighting = function() { for (var i = 0; i < rowtools.selected.length; i++) { var row = rowtools.selected[i]; rowtools._highlight(row); } }; rowtools._highlight = function(row) { // cells var y = DayPilot.indexOf(calendar.rowlist, row); if (y === -1) { // not found, search using id var idrow = calendar._findRowByResourceId(row.id).index; if (idrow) { y = idrow.index; } else { return; } } var cl = calendar._prefixCssClass("_cell_selected"); var cells = []; for(var i = 0; i < calendar.itline.length; i++) { var c = {}; c.x = i; c.y = y; cells.push(c); } calendar.cells.findXy(cells).addClass(cl); // header var cl = calendar._prefixCssClass("_rowheader_selected"); var table = calendar.divHeader; for (var y = 0; y < table.rows.length; y++) { var r = table.rows[y]; if (r && r.cells[0] && r.cells[0].row === row) { for (var x = 0; x < r.cells.length; x++) { var c = r.cells[x]; var first = c.firstChild; DayPilot.Util.addClass(first, cl); } } } }; rowtools._isSelected = function(id) { for (var i = 0; i < rowtools.selected.length; i++) { var row = rowtools.selected[i]; if (row.id === id) { return true; } } return false; }; rowtools._getSelectedList = function() { var list = []; if (!rowtools.selected) { return list; } for(var i = 0; i < rowtools.selected.length; i++) { var row = rowtools.selected[i]; var index = DayPilot.indexOf(calendar.rowlist, row); var r = calendar._createRowObject(row, index); list.push(r.toJSON()); } return list; }; rowtools.unselect = function(row) { // cells var cl = calendar._prefixCssClass("_cell_selected"); var y = DayPilot.indexOf(calendar.rowlist, row); var cells = []; for(var i = 0; i < calendar.itline.length; i++) { var c = {}; c.x = i; c.y = y; cells.push(c); } calendar.cells.findXy(cells).removeClass(cl); // header var cl = calendar._prefixCssClass("_rowheader_selected"); var table = calendar.divHeader; var r = rowtools._findTableRow(row); if (r) { for (var x = 0; x < r.cells.length; x++) { var c = r.cells[x]; var first = c.firstChild; DayPilot.Util.removeClass(first, cl); } } }; rowtools.clearSelection = function() { for(var j = 0; j < rowtools.selected.length; j++) { var row = rowtools.selected[j]; rowtools.unselect(row); } // clear the list rowtools.selected = []; }; rowtools._findTableRow = function(row) { var table = calendar.divHeader; for (var y = 0; y < table.rows.length; y++) { var r = table.rows[y]; if (r && r.cells[0] && r.cells[0].row === row) { return r; } } return null; }; // helper rowtools.selectById = function(id) { var row = calendar._findRowByResourceId(id); if (row) { rowtools.select(row); } }; rowtools.startMoving = function(row) { var rowmoving = DayPilot.Global.rowmoving; rowmoving.row = row; rowmoving.cursor = calendar.divResScroll.style.cursor; calendar.divResScroll.style.cursor = "move"; rowtools.createOverlay(row); }; rowtools.resetMoving = function() { calendar.divResScroll.style.cursor = rowmoving.cursor; DayPilot.de(rowmoving.div); rowtools.deleteOverlay(rowmoving.row); DayPilot.Global.rowmoving = rowmoving = {}; }; rowtools.move = function(args) { // modify .resources var source = args.source.$.row.resource; var target = args.target.$.row.resource; var position = args.position; if (position === "forbidden") { return; } // remove from source var sourceParent = restools.findParentArray(source); if (!sourceParent) { throw "Cannot find source node parent"; } var sourceIndex = DayPilot.indexOf(sourceParent, source); sourceParent.splice(sourceIndex, 1); // move to target var targetParent = restools.findParentArray(target); if (!targetParent) { throw "Cannot find target node parent"; } var targetIndex = DayPilot.indexOf(targetParent, target); switch (position) { case "before": targetParent.splice(targetIndex, 0, source); break; case "after": targetParent.splice(targetIndex + 1, 0, source); break; case "child": if (!target.children) { target.children = []; target.expanded = true; } target.children.push(source); break; } calendar.update(); }; var restools = {}; restools.findParentArray = function(res) { return restools.findInArray(calendar.resources, res); }; restools.findInArray = function(array, res) { if (DayPilot.indexOf(array, res) !== -1) { return array; } for(var i = 0; i < array.length; i++) { var r = array[i]; if (r.children && r.children.length > 0) { var parent = restools.findInArray(r.children, res); if (parent) { return parent; } } } return null; }; this._loadResources = function() { this.rowlist = []; var resources = this.resources; var force = this._serverBased(); if (!force) { if (this.viewType === "Gantt") { resources = this._loadResourcesGantt(); } else if (this.viewType === "Days") { resources = this._loadResourcesDays(); } } if (force && this.viewType === "Days" && (!resources || resources.length === 0)) { resources = this._loadResourcesDays(); } // pass by reference var index = {}; index.i = 0; this._loadResourceChildren(resources, index, 0, null, this.treeEnabled, false); this._ensureFilteredParents(); var newResourceRow = calendar.rowCreateHandling !== "Disabled"; if (newResourceRow) { this._createNewResourceRow(); } this._updateSelectedRows(); }; this._ensureFilteredParents = function() { for (var i = 0; i < calendar.rowlist.length; i++) { } }; this._createNewResourceRow = function() { var r = {}; r.id = "NEW"; r.isNewRow = true; r.html = ""; //r.moveEnabled = false; r.loaded = true; r.start = this.startDate; r.children = []; r.height = calendar.eventHeight; r.marginBottom = 0; r.marginTop = 0; r.getHeight = function() { return calendar.eventHeight + calendar.rowMarginBottom + calendar.rowMarginTop; //return Math.max(calendar.rowMinHeight, calendar.eventHeight + calendar.rowMarginBottom); }; r.putIntoLine = function() {}; r.resetEvents = function() {}; this.rowlist.push(r); }; this._updateSelectedRows = function() { var list = []; for (var i = 0; i < calendar.rowlist.length; i++) { var row = calendar.rowlist[i]; var id = row.id; if (rowtools._isSelected(id)) { list.push(row); } } rowtools.selected = list; }; this._loadResourcesGantt = function() { var list = []; if (this._ganttAppendToResources && this.resources) { for (var i = 0; i < this.resources.length; i++) { list.push(this.resources[i]); } } if (!this.events.list) { return; } //this.resources = []; for (var i = 0; i < this.events.list.length; i++) { var e = this.events.list[i]; var r = {}; r.id = e.id; r.name = e.text; list.push(r); } return list; }; this._loadResourcesDays = function() { var list = []; var locale = this._resolved.locale(); for (var i = 0; i < this.days; i++) { var d = this.startDate.addDays(i); var r = {}; r.name = d.toString(locale.datePattern, locale); r.start = d; list.push(r); } return list; }; this._visibleStart = function() { if (this.itline && this.itline.length > 0) { return this.itline[0].start; } return this.startDate; }; this._visibleEnd = function() { if (this.itline && this.itline.length > 0) { return this.itline[this.itline.length - 1].end; } return this.startDate.addDays(this.days); }; this.visibleStart = function() { return this._visibleStart(); }; this.visibleEnd = function() { return this._visibleEnd(); }; this._loadResourceChildren = function(resources, index, level, parent, recursively, hidden) { if (!resources) { return; } for (var i = 0; i < resources.length; i++) { if (!resources[i]) { continue; } var additional = {}; additional.level = level; additional.hidden = hidden; additional.index = index.i; //var res = this._createBeforeResHeaderRenderArgs(resources[i], additional); var res = this._doBeforeResHeaderRender(resources[i], additional); var row = {}; // defined values row.backColor = res.backColor; row.cssClass = res.cssClass; row.expanded = res.expanded; row.name = res.name; row.html = res.html ? res.html : row.name; row.eventHeight = typeof res.eventHeight !== 'undefined' ? res.eventHeight : calendar._resolved.eventHeight(); row.minHeight = typeof res.minHeight !== 'undefined' ? res.minHeight : calendar.rowMinHeight; row.marginBottom = typeof res.marginBottom !== 'undefined' ? res.marginBottom : calendar.rowMarginBottom; row.marginTop = typeof res.marginTop !== 'undefined' ? res.marginTop : calendar.rowMarginTop; row.loaded = !res.dynamicChildren; // default is true row.id = res.id || res.value; // accept both id and value row.toolTip = res.toolTip; row.children = []; row.columns = []; row.start = res.start ? new DayPilot.Date(res.start) : this._visibleStart(); row.isParent = res.isParent; row.contextMenu = res.contextMenu ? DayPilot.Util.evalVariable(res.contextMenu) : this.contextMenuResource; row.areas = res.areas; row.moveDisabled = res.moveDisabled; // custom properties row.tags = res.tags; // gantt row.task = res.task; // calculated row.height = row.eventHeight; // TODO might not be necessary row.hidden = hidden; row.level = level; row.index = index.i; // reference to resource row.resource = resources[i]; // event ordering row.lines = []; row.blocks = []; row.isRow = true; // functions row.getHeight = function() { var height = 0; if (calendar.groupConcurrentEvents) { for (var i = 0; i < this.blocks.length; i++) { var block = this.blocks[i]; height = Math.max(height, block.getHeight()); } } else { if (this.lines.length > 0) { var last = this.lines.length - 1; var line = this.lines[last]; var lheight = line.height || this.eventHeight; var top = line.top || 0; height = top + lheight; } } if (height === 0) { height = this.eventHeight; } return (height > this.minHeight) ? height : this.minHeight; }; row.resetEvents = function() { var r = this; r.events = []; r.events.forRange = function(start, end) { var result = []; for (var i = 0; i < r.events.length; i++) { var ev = r.events[i]; if (DayPilot.Util.overlaps(ev.start(), ev.end(), start, end)) { result.push(ev); } } return result; }; }; row.calculateUtilization = function() { var r = this; var sections = r.sections = getSections(); for (var i = 0; i < sections.length; i++) { var section = sections[i]; section.events = []; //var test = section.start.addTime(1); for (var x = 0; x < r.events.length; x++) { var e = r.events[x]; if (DayPilot.Util.overlaps(section.start, section.end, e.start(), e.rawend())) { section.events.push(e); } } section.sum = function(name) { var sum = 0; for (var i = 0; i < this.events.length; i++) { var e = this.events[i]; var value = e.data[name]; if (typeof value === 'number') { sum += value; } } return sum; } } function getPoints() { var points = []; for (var i = 0; i < r.events.length; i++) { var e = r.events[i]; if (!DayPilot.contains(points, e.start().toString())) { points.push(e.start().toString()); } if (!DayPilot.contains(points, e.rawend().toString())) { points.push(e.rawend().toString()); } } points.sort(); return points; } function getSections() { var points = getPoints(); var sections = []; var section = { "start": r.data.start}; for (var i = 0; i < points.length; i++) { section.end = new DayPilot.Date(points[i]); sections.push(section); section = { "start": new DayPilot.Date(points[i])}; } section.end = r.data.end; sections.push(section); sections.forRange = function(start, end) { var list = []; for (var i = 0; i < this.length; i++) { var section = this[i]; if (DayPilot.Util.overlaps(start, end, section.start, section.end)) { list.push(section); } } list.maxSum = function(name) { var max = 0; for (var i = 0; i < this.length; i++) { var section = this[i]; var sum = section.sum(name); if (sum > max) { max = sum; } } return max; }; return list; }; return sections; } }; row.putIntoLine = function(ep) { var thisRow = this; for (var i = 0; i < this.lines.length; i++) { var line = this.lines[i]; if (line.isFree(ep.part.left, ep.part.width)) { line.add(ep); return i; } } var line = []; line.height = 0; line.add = function(ep) { this.push(ep); if (ep.part.height > line.height) { line.height = ep.part.height; } }; line.isFree = function(colStart, colWidth, except) { //var free = true; var end = colStart + colWidth - 1; var max = this.length; for (var i = 0; i < max; i++) { var e = this[i]; if (!(end < e.part.left || colStart > e.part.left + e.part.width - 1)) { if (DayPilot.contains(except, e.data)) { continue; } return false; } } return true; }; line.add(ep); this.lines.push(line); return this.lines.length - 1; }; row.putIntoBlock = function(ep) { for (var i = 0; i < this.blocks.length; i++) { var block = this.blocks[i]; if (DayPilot.indexOf(block.events, ep) !== -1) { return; } if (block.overlapsWith(ep.part.left, ep.part.width)) { //block.putIntoLine(ep); block.events.push(ep); ep.part.block = block; block.min = Math.min(block.min, ep.part.left); block.max = Math.max(block.max, ep.part.left + ep.part.width); return i; } } // no suitable block found, create a new one var block = {}; block.expanded = false; block.row = this; block.events = []; block.lines = []; block.putIntoLine = function(ep) { var thisCol = this; for (var i = 0; i < this.lines.length; i++) { var line = this.lines[i]; if (line.isFree(ep.part.left, ep.part.width)) { line.add(ep); return i; } } var line = []; line.height = 0; line.add = function(ep) { this.push(ep); if (ep.part.height > line.height) { line.height = ep.part.height; } }; line.isFree = function(start, width) { //var free = true; var end = start + width - 1; var max = this.length; for (var i = 0; i < max; i++) { var e = this[i]; if (!(end < e.part.left || start > e.part.left + e.part.width - 1)) { return false; } } return true; }; line.add(ep); this.lines.push(line); //return this.lines.length - 1; }; block.overlapsWith = function(start, width) { var end = start + width - 1; if (!(end < this.min || start > this.max - 1)) { return true; } return false; }; block.getHeight = function() { if (!this.expanded) { return calendar.eventHeight; } if (this.lines.length > 0) { var last = this.lines.length - 1; var line = this.lines[last]; var lheight = line.height || calendar.eventHeight; var top = line.top || 0; return top + lheight; } }; //block.putIntoLine(ep); block.events.push(ep); ep.part.block = block; block.min = ep.part.left; block.max = ep.part.left + ep.part.width; this.blocks.push(block); //return this.blocks.length - 1; }; row._makeVisibleDefaultHidden = hidden; row._makeVisibleParent = parent; row._makeVisibleOnFilter = function() { if (this._makeVisibleDefaultHidden) { return; } this.hidden = false; if (this._makeVisibleParent) { this._makeVisibleParent._makeVisibleOnFilter(); } }; this.rowlist.push(row); if (typeof calendar.onRowFilter === "function" && calendar.rows._filterParams) { var args = {}; //args.visible = !hidden; args.visible = true; args.row = calendar._createRowObject(row); args.filter = calendar.rows._filterParams; calendar.onRowFilter(args); if (!args.visible) { row.hidden = true; } else { if (parent) { parent._makeVisibleOnFilter(); } } } if (parent !== null) { parent.children.push(index.i); } if (res.columns) { for (var j = 0; j < res.columns.length; j++) { row.columns.push(res.columns[j]); // plain copy, it's the same structure } } index.i++; if (recursively && res.children && res.children.length) { //this.hasChildren = true; //var hiddenChildren = row.hidden || !row.expanded; var hiddenChildren = hidden || !row.expanded; this._loadResourceChildren(res.children, index, level + 1, row, true, hiddenChildren); } } }; this._doBeforeRowHeaderRender = function(row) { if (row.isNewRow) { return { "row": { // "children": [], "cssClass": calendar._prefixCssClass("_row_new"), "moveDisabled": true, "html": "" } }; } var args = {}; args.row = this._createRowObject(row); //args.client = {}; DayPilot.Util.copyProps(row, args.row, ['html', 'backColor', 'cssClass', 'toolTip', 'contextMenu', 'moveDisabled']); args.row.columns = DayPilot.Util.createArrayCopy(row.columns, ['html']); args.row.areas = DayPilot.Util.createArrayCopy(row.areas); if (typeof args.row.columns === 'undefined' && calendar.rowHeaderColumns && calendar.rowHeaderColumns.length > 0) { r.columns = []; for (var i = 0; i < calendar.rowHeaderColumns.length; i++) { r.columns.push({}); } } if (typeof this.onBeforeRowHeaderRender === "function") { this.onBeforeRowHeaderRender(args); } return args; }; this._doBeforeResHeaderRender = function(res, additional) { var r = this._createBeforeResHeaderRenderArgs(res, additional); if (typeof this.onBeforeResHeaderRender === 'function') { var args = {}; args.resource = r; this.onBeforeResHeaderRender(args); } return r; }; this._createBeforeResHeaderRenderArgs = function(res, additional) { var r = {}; // extra properties like level, index, hidden for (var name in additional) { r[name] = additional[name]; } // shallow copy // TODO resolve children, columns for (var name in res) { r[name] = res[name]; } if (typeof res.html === 'undefined') { r.html = res.name; } if (typeof r.columns === 'undefined' && calendar.rowHeaderColumns && calendar.rowHeaderColumns.length > 0) { r.columns = []; for (var i = 0; i < calendar.rowHeaderColumns.length; i++) { r.columns.push({}); } } return r; }; this._initPrepareDiv = function() { this._loadTop(); this.nav.top.dp = this; this.nav.top.innerHTML = ""; // TODO remove if (!this.cssOnly) { this.nav.top.style.border = "1px solid " + this.borderColor; } else { DayPilot.Util.addClass(this.nav.top, this._prefixCssClass("_main")); } if (DayPilot.browser.ie9) { DayPilot.Util.addClass(this.nav.top, this._prefixCssClass("_browser_ie9")); } if (DayPilot.browser.ie8) { DayPilot.Util.addClass(this.nav.top, this._prefixCssClass("_browser_ie8")); } this.nav.top.style.MozUserSelect = 'none'; this.nav.top.style.KhtmlUserSelect = 'none'; this.nav.top.style.webkitUserSelect = 'none'; this.nav.top.style.WebkitTapHighlightColor = "rgba(0,0,0,0)"; this.nav.top.style.WebkitTouchCallout = "none"; if (this.width) { this.nav.top.style.width = this.width; } if (this.heightSpec === "Parent100Pct") { this.nav.top.style.height = "100%"; } //this.nav.top.style.boxSizing = "border-box"; this.nav.top.style.lineHeight = "1.2"; this.nav.top.style.position = "relative"; if (!this.visible) { this.nav.top.style.display = "none"; } /* // moved to maind this.nav.top.onmousemove = function(ev) { ev = ev || window.event; ev.insideMainD = true; if (window.event) { window.event.srcElement.inside = true; } }; */ this.nav.top.onmousemove = this._onTopMouseMove; this.nav.top.ontouchstart = touch.onMainTouchStart; this.nav.top.ontouchmove = touch.onMainTouchMove; this.nav.top.ontouchend = touch.onMainTouchEnd; if (this.hideUntilInit && this.backendUrl) { this.nav.top.style.visibility = 'hidden'; } var rowHeaderWidth = this._getOuterRowHeaderWidth(); var layout = this._resolved.layout(); if (layout === 'DivBased') { // left var left = document.createElement("div"); //left.style.cssFloat = "left"; //left.style.styleFloat = "left"; // IE7 left.style.position = "absolute"; left.style.left = "0px"; left.style.width = (rowHeaderWidth) + "px"; left.appendChild(this._drawCorner()); // divider horizontal var dh1 = document.createElement("div"); dh1.style.height = "1px"; dh1.className = this._prefixCssClass("_divider_horizontal"); if (!this.cssOnly) { dh1.style.backgroundColor = this.borderColor; } left.appendChild(dh1); this.nav.dh1 = dh1; left.appendChild(this._drawResScroll()); this.nav.left = left; // divider var divider = document.createElement("div"); divider.style.position = "absolute"; divider.style.left = (rowHeaderWidth) + "px"; //divider.style.cssFloat = "left"; //divider.style.styleFloat = "left"; // IE7 divider.style.width = resolved.splitterWidth() + "px"; divider.style.height = (this._getTotalHeaderHeight() + this._getScrollableHeight()) + "px"; divider.className = this._prefixCssClass("_divider") + " " + this._prefixCssClass("_splitter"); // TODO _divider is obsolete divider.setAttribute("unselectable", "on"); if (!this.cssOnly) { divider.style.backgroundColor = this.borderColor; } this.nav.divider = divider; // maybe not the best place if (this.rowHeaderScrolling) { this._activateSplitter(); } // right var right = document.createElement("div"); right.style.marginRight = '1px'; right.style.position = 'relative'; right.appendChild(this._drawTimeHeaderDiv()); this.nav.right = right; // divider horizontal #2 var dh2 = document.createElement("div"); dh2.style.height = "1px"; dh2.style.position = "absolute"; dh2.style.top = this._getTotalHeaderHeight() + "px"; dh2.style.width = "100%"; dh2.className = this._prefixCssClass("_divider_horizontal"); if (!this.cssOnly) { dh2.style.backgroundColor = this.borderColor; } right.appendChild(dh2); this.nav.dh2 = dh2; right.appendChild(this._drawMainContent()); // clear var clear = document.createElement("div"); clear.style.clear = 'left'; // add all at once this.nav.top.appendChild(left); this.nav.top.appendChild(divider); this.nav.top.appendChild(right); this.nav.top.appendChild(clear); } else { var table = document.createElement("table"); table.cellPadding = 0; table.cellSpacing = 0; table.border = 0; // required for proper width measuring (onresize) table.style.position = 'absolute'; if (!this.cssOnly) { table.style.backgroundColor = this.hourNameBackColor; } var row1 = table.insertRow(-1); var td1 = row1.insertCell(-1); td1.appendChild(this._drawCorner()); var td2 = row1.insertCell(-1); td2.appendChild(this._drawTimeHeaderDiv()); var row2 = table.insertRow(-1); var td3 = row2.insertCell(-1); td3.appendChild(this._drawResScroll()); var td4 = row2.insertCell(-1); td4.appendChild(this._drawMainContent()); this.nav.top.appendChild(table); } // hidden fields this._vsph = document.createElement("div"); //this.vsph.id = this.id + "_vsph"; this._vsph.style.display = "none"; this.nav.top.appendChild(this._vsph); if (this._isAspnetWebForms()) { var stateInput = document.createElement("input"); stateInput.type = "hidden"; stateInput.id = this.id + "_state"; stateInput.name = this.id + "_state"; this.nav.state = stateInput; this.nav.top.appendChild(stateInput); } var margin = 5; var loading = document.createElement("div"); loading.style.position = 'absolute'; loading.style.left = (this._getOuterRowHeaderWidth() + resolved.splitterWidth() + 5) + "px"; loading.style.top = (this._getTotalHeaderHeight() + 5) + "px"; loading.style.display = 'none'; if (!this.cssOnly) { loading.style.backgroundColor = this.loadingLabelBackColor; loading.style.fontSize = this.loadingLabelFontSize; loading.style.fontFamily = this.loadingLabelFontFamily; loading.style.color = this.loadingLabelFontColor; loading.style.padding = '2px'; } loading.innerHTML = this.loadingLabelText; DayPilot.Util.addClass(loading, this._prefixCssClass("_loading")); this.nav.loading = loading; this.nav.top.appendChild(loading); this._drawRowHeaderHideIcon(); }; this._onTopMouseMove = function(ev) { if (rowmoving.row) { var coords = DayPilot.mo3(calendar.divHeader, ev); var ri = calendar._getRow(coords.y); var row = calendar.rowlist[ri.i]; if (row.isNewRow) { return; } var relative = coords.y - ri.top; var rowheight = ri.bottom - ri.top; var third1 = rowheight/3; var third2 = third1*2; var mid = rowheight/2; var position = "before"; var hasChildren = row.children && row.children.length > 0; var sourceInParents = (function() { var i = ri.i; var lastlevel = row.level; while (i >= 0) { var r = calendar.rowlist[i]; i--; if (lastlevel <= r.level) { continue; } if (r === rowmoving.row) { return true; } if (r.level === 0) { return false; } lastlevel = r.level; } return false; })(); var childEnabled = true; if (sourceInParents || ri.i === rowmoving.row.index) { position = "forbidden"; } else if (childEnabled) { if (hasChildren) { if (relative < mid) { position = "before"; } else { position = "child"; } } else { if (relative < third1) { position = "before"; } else if (relative < third2) { position = "child"; } else { position = "after"; } } } else { if (hasChildren) { position = "before"; } else { if (relative < mid) { position = "before"; } else { position = "after"; } } } if (rowmoving.row.moveDisabled) { position = "forbidden"; } rowmoving.calendar = calendar; rowmoving.source = rowmoving.row; rowmoving.target = calendar.rowlist[ri.i]; rowmoving.position = position; var changed = (function() { if (!rowmoving.last) { return true; } if (rowmoving.last.target !== rowmoving.target) { return true; } if (rowmoving.last.position !== rowmoving.position) { return true; } return false; })(); if (changed) { if (typeof calendar.onRowMoving === 'function') { var args = {}; args.source = calendar._createRowObject(rowmoving.source); args.target = calendar._createRowObject(rowmoving.target); args.position = position; calendar.onRowMoving(args); rowmoving.position = args.position; } } else if (rowmoving.last) { rowmoving.position = rowmoving.last.position; } rowmoving.last = {}; rowmoving.last.target = rowmoving.target; rowmoving.last.position = rowmoving.position; (function drawRowPosition() { if (rowmoving.div) { DayPilot.de(rowmoving.div); } var top = ri.top; var pos = rowmoving.position; var ro = calendar.rowlist[ri.i]; var level = ro.level; var left = level * calendar.treeIndent; switch (pos) { case "before": top = ri.top; break; case "child": top = ri.top + mid; //left += calendar.treeIndent; break; case "after": top = ri.bottom; break; case "forbidden": top = ri.top + mid; break; } var width = calendar._getTotalRowHeaderWidth() - left; var position = document.createElement("div"); position.style.position = "absolute"; position.style.left = left + "px"; position.style.width = width + "px"; //position.style.height = "2px"; position.style.top = top + "px"; //position.style.backgroundColor = "#999"; position.className = calendar._prefixCssClass("_rowmove_position_" + pos); rowmoving.div = position; calendar.divResScroll.appendChild(position); /* if (pos === 'child') { var plus = document.createElement("div"); plus.style.position = "absolute"; plus.style.left = left + "px"; plus.style.top = top + "px"; plus.style.color = "#999"; plus.innerHTML = "+"; calendar.divResScroll.appendChild(plus); rowmoving.div = []; rowmoving.div.push(position); rowmoving.div.push(plus); } else if (pos === 'forbidden') { var plus = document.createElement("div"); plus.style.position = "absolute"; plus.style.left = left + "px"; plus.style.top = top + "px"; plus.style.color = "red"; plus.innerHTML = "x"; calendar.divResScroll.appendChild(plus); rowmoving.div = []; rowmoving.div.push(position); rowmoving.div.push(plus); } */ })(); } else if (DayPilotScheduler.splitting) { var width = DayPilot.mo3(calendar.nav.top, ev).x; var max = calendar._getTotalRowHeaderWidth(); var newWidth = Math.min(max, width - 1); calendar.rowHeaderWidth = newWidth; calendar._rowHeaderHidden = false; calendar._updateRowHeaderWidthOuter(); } }; // update all positions that depend on header height this._updateHeaderHeight = function() { var height = this._getTotalHeaderHeight(); this.nav.corner.style.height = (height) + "px"; //this.divCorner.style.height = (height) + "px"; this.divTimeScroll.style.height = height + "px"; this.divNorth.style.height = height + "px"; if (this.nav.dh1 && this.nav.dh2) { this.nav.dh1.style.top = height + "px"; this.nav.dh2.style.top = height + "px"; } this.nav.loading.style.top = (height + 5) + "px"; this.nav.scroll.style.top = (height + 1) + "px"; }; this._getOuterRowHeaderWidth = function() { if (this._rowHeaderHidden) { return 0; } var fixed = this.rowHeaderScrolling; if (fixed) { return this.rowHeaderWidth; } return this._getTotalRowHeaderWidth(); }; this._activateSplitter = function() { var div = this.nav.divider; div.style.cursor = "col-resize"; div.setAttribute("unselectable", "on"); div.onmousedown = function(ev) { var splitting = DayPilotScheduler.splitting = {}; splitting.cursor = calendar.nav.top.style.cursor; splitting.cleanup = function() { calendar.nav.top.style.cursor = splitting.cursor; if (typeof calendar.onRowHeaderResized === "function") { var args = {}; calendar.onRowHeaderResized(args); } }; calendar.nav.top.style.cursor = "col-resize"; return false; }; }; this._updateRowHeaderWidthOuter = function() { var dividerWidth = resolved.splitterWidth(); var width = this._getOuterRowHeaderWidth(); this.nav.corner.style.width = width + "px"; this.divCorner.style.width = width + "px"; this.divResScroll.style.width = width + "px"; this.nav.left.style.width = (width) + "px"; this.nav.divider.style.left = (width) + "px"; if (this.nav.message) { this.nav.message.style.left = (width + dividerWidth) + "px"; } if (this.nav.loading) { this.nav.loading.style.left = (width + dividerWidth + 5) + "px"; } if (this.nav.hideIcon) { var hi = this.nav.hideIcon; var showCss = calendar._prefixCssClass("_header_icon_show"); var hideCss = calendar._prefixCssClass("_header_icon_hide"); hi.style.left = (width + dividerWidth - 1) + "px"; if (calendar._rowHeaderHidden) { DayPilot.Util.removeClass(hi, hideCss); DayPilot.Util.addClass(hi, showCss); } else { DayPilot.Util.removeClass(hi, showCss); DayPilot.Util.addClass(hi, hideCss); } } }; this._updateRowHeaderWidthInner = function() { this._loadRowHeaderColumns(); var total = this._getTotalRowHeaderWidth(); var updateCell = function(cell, width, left) { if (!cell || !cell.style) { return; } var div = cell.firstChild; if (calendar._resHeaderDivBased) { cell.style.width = width + "px"; div.style.width = width + "px"; if (typeof left === "number") { cell.style.left = left + "px"; } } else { div.style.width = width + "px"; } }; var table = this.divHeader; table.style.width = total + "px"; var range = calendar._getAreaRowsWithMargin(); for (var i = range.start; i < range.end; i++) { var row = table.rows[i]; if (!row) { continue; } var cell = row.cells[0]; if (cell.colSpan > 1) { var cell = row.cells[0]; updateCell(cell, total); } else { if (this.rowHeaderCols) { var left = 0; for (var j = 0; j < row.cells.length; j++) { var width = this.rowHeaderCols[j]; var cell = row.cells[j]; updateCell(cell, width, left); left += width; } } else { var width = this.rowHeaderWidth; var cell = row.cells[0]; updateCell(cell, width); } } } if (calendar.nav.resScrollSpace) { calendar.nav.resScrollSpace.style.width = total + "px"; } this._crosshairHide(); // update }; this._updateRowHeaderWidth = function() { this._updateRowHeaderWidthOuter(); this._updateRowHeaderWidthInner(); }; this._drawHeaderColumns = function() { var div = calendar.nav.corner; /* var sampleProps = [ { title: 'Event', width: 150 }, { title: 'Duration', width: 100 }, ]; */ var props = this.rowHeaderColumns; var scroll = document.createElement("div"); scroll.style.position = "absolute"; scroll.style.bottom = "0px"; scroll.style.left = "0px"; scroll.style.width = "100%"; scroll.style.height = resolved.headerHeight() + "px"; scroll.style.overflow = "hidden"; calendar.nav.columnScroll = scroll; var row = document.createElement("div"); row.style.position = "absolute"; row.style.bottom = "0px"; row.style.left = "0px"; row.style.width = "5000px"; //row.style.width = "100%"; row.style.height = resolved.headerHeight() + "px"; row.style.overflow = "hidden"; row.className = this._prefixCssClass("_columnheader"); scroll.appendChild(row); var inner = document.createElement("div"); inner.style.position = "absolute"; inner.style.top = "0px"; inner.style.bottom = "0px"; inner.style.left = "0px"; inner.style.right = "0px"; inner.className = this._prefixCssClass("_columnheader_inner"); row.appendChild(inner); var splitter = new DayPilot.Splitter(inner); splitter.widths = DayPilot.Util.propArray(props, "width"); splitter.height = resolved.headerHeight(); splitter.css.title = this._prefixCssClass("_columnheader_cell"); splitter.css.titleInner = this._prefixCssClass("_columnheader_cell_inner"); splitter.css.splitter = this._prefixCssClass("_columnheader_splitter"); splitter.titles = DayPilot.Util.propArray(props, "title"); splitter.updating = function(args) { //calendar.rowHeaderCols = this.widths; DayPilot.Util.updatePropsFromArray(calendar.rowHeaderColumns, "width", this.widths); calendar._updateRowHeaderWidth(); if (calendar.cellWidthSpec === "Auto") { } }; splitter.updated = function(rargs) { calendar._updateAutoCellWidth(); if (calendar._api2()) { if (typeof calendar.onRowHeaderColumnResized === "function") { var args = {}; args.column = calendar.rowHeaderColumns[rargs.index]; calendar.onRowHeaderColumnResized(args); }; } else { switch (calendar.rowHeaderColumnResizedHandling) { case "CallBack": break; case "PostBack": break; case "JavaScript": if (typeof calendar.onRowHeaderColumnResized === "function") { var args = {}; args.column = calendar.rowHeaderColumns[rargs.index]; calendar.onRowHeaderColumnResized(args); }; break; } } }; splitter.color = '#000000'; splitter.opacity = 30; //splitter.height = 19; splitter.init(); div.appendChild(scroll); this._splitter = splitter; }; this._updateCorner = function() { var div = this.nav.corner; div.innerHTML = ''; div.className = this.cssOnly ? this._prefixCssClass('_corner') : this._prefixCssClass('corner'); if (!this.cssOnly) { div.style.backgroundColor = this.hourNameBackColor; div.style.fontFamily = this.hourFontFamily; div.style.fontSize = this.hourFontSize; div.style.cursor = 'default'; } var inner = document.createElement("div"); inner.style.position = "absolute"; inner.style.top = "0px"; inner.style.left = "0px"; inner.style.right = "0px"; inner.style.bottom = "0px"; if (this.cssOnly) { inner.className = this._prefixCssClass('_corner_inner'); } this.divCorner = inner; inner.innerHTML = ' '; if (this.rowHeaderColumns && this.rowHeaderColumns.length > 0) { var mini = document.createElement("div"); mini.style.position = "absolute"; mini.style.top = "0px"; mini.style.left = "0px"; mini.style.right = "0px"; mini.style.bottom = (resolved.headerHeight() + 1) + "px"; div.appendChild(mini); var divider = document.createElement("div"); divider.style.position = "absolute"; divider.style.left = "0px"; divider.style.right = "0px"; divider.style.height = "1px"; divider.style.bottom = (resolved.headerHeight()) + "px"; divider.className = this._prefixCssClass("_divider"); div.appendChild(divider); mini.appendChild(inner); this._drawHeaderColumns(); } else { div.appendChild(inner); } }; this._drawRowHeaderHideIcon = function() { if (!this.rowHeaderHideIconEnabled) { return; } var marginTop = 3; var left = this._getOuterRowHeaderWidth() + resolved.splitterWidth() - 1; var width = 10; var height = 20; var top = this._getTotalHeaderHeight() + marginTop; var div = DayPilot.Util.div(this.nav.top, left, top, width, height); //div.style.backgroundColor = "gray"; div.style.cursor = "pointer"; div.className = calendar._prefixCssClass("_header_icon"); DayPilot.Util.addClass(div, calendar._prefixCssClass("_header_icon_hide")); div.onclick = function() { calendar.rows.headerToggle(); }; this.nav.hideIcon = div; }; this._drawCorner = function() { var rowHeaderWidth = this._getOuterRowHeaderWidth(); var div = document.createElement("div"); calendar.nav.corner = div; div.style.width = rowHeaderWidth + "px"; div.style.height = (this._getTotalHeaderHeight()) + "px"; div.style.overflow = 'hidden'; div.style.position = 'relative'; div.setAttribute("unselectable", "on"); div.onmousemove = function() { calendar._out(); }; div.oncontextmenu = function() { return false; }; this._updateCorner(); return div; }; this._getTotalHeaderHeight = function() { if (this.timeHeader) { var lines = this.timeHeader.length; /* if (!this.showBaseTimeHeader) { lines -= 1; } */ return lines * resolved.headerHeight(); } return 2 * resolved.headerHeight(); }; this._rowHeaderScrollSyncTimeout = null; this._drawResScroll = function() { var div = document.createElement("div"); if (!this.cssOnly) { div.style.backgroundColor = this.hourNameBackColor; } div.style.width = (this._getOuterRowHeaderWidth()) + "px"; div.style.height = this._getScrollableHeight() + "px"; div.style.overflow = 'hidden'; div.style.position = 'relative'; div.className = calendar._prefixCssClass("_rowheader_scroll"); div.onmousemove = function() { calendar._out(); }; div.onscroll = function() { if (calendar.nav.columnScroll && calendar.rowHeaderScrolling) { calendar.nav.columnScroll.scrollLeft = div.scrollLeft; } if (calendar._rowHeaderScrollSyncTimeout) { clearTimeout(calendar._rowHeaderScrollSyncTimeout); } calendar._rowHeaderScrollSyncTimeout = setTimeout(function() { calendar.nav.scroll.scrollTop = div.scrollTop; }, 500); }; div.onwheel = function(ev) { var delta = ev.deltaY > 0 ? calendar.eventHeight : -calendar.eventHeight; calendar.nav.scroll.scrollTop = div.scrollTop + delta; ev.preventDefault && ev.preventDefault(); }; div.onmousewheel = function(ev) { ev = ev || window.event; var delta = ev.wheelDelta < 0 ? calendar.eventHeight : -calendar.eventHeight; calendar.nav.scroll.scrollTop = div.scrollTop + delta; ev.preventDefault && ev.preventDefault(); ev.returnValue = false; }; div.oncontextmenu = function() { return false; }; div.onmouseenter = function() { if (calendar.rowHeaderScrolling) { div.style.overflowX = "auto"; } }; div.onmouseleave = function() { if (calendar.rowHeaderScrolling) { div.style.overflowX = "hidden"; } }; this.divResScroll = div; this._scrollRes = div; return div; }; this._setRightColWidth = function(div) { if (resolved.layout() === 'TableBased') { var width = parseInt(this.width, 10); var isPercentage = (this.width.indexOf("%") !== -1); var isIE = /MSIE/i.test(navigator.userAgent); var rowHeaderWidth = this._getTotalRowHeaderWidth(); if (isPercentage) { if (this.nav.top && this.nav.top.offsetWidth > 0) { div.style.width = (this.nav.top.offsetWidth - 6 - rowHeaderWidth) + "px"; } } else { // fixed div.style.width = (width - rowHeaderWidth) + "px"; } } }; this._resize = function() { if (calendar._resolved.layout() === 'TableBased') { calendar._setRightColWidth(calendar.nav.scroll); calendar._setRightColWidth(calendar.divTimeScroll); } //calendar.debug.message("window.resize"); calendar._updateHeight(); calendar._updateAutoCellWidth(); //calendar._updateHeight(); calendar._cache.drawArea = null; calendar._findHeadersInViewPort(); }; this._updateAutoCellWidth = function() { //calendar.debug.message("updateAutoCellWidth: _initialized: " + calendar._initialized + " cellWidthSpec: " + calendar.cellWidthSpec); if (!calendar._initialized) { return; } if (calendar.cellWidthSpec !== 'Auto') { return; } // TODO detect a real dimension change //calendar.debug.message("cell width recalc in _resize"); calendar._calculateCellWidth(); calendar._prepareItline(); calendar._drawTimeHeader(); calendar._deleteCells(); calendar._drawCells(); calendar._deleteSeparators(); calendar._drawSeparators(); calendar._deleteEvents(); calendar._loadEvents(); calendar._drawEvents(); }; this._calculateCellWidth = function() { // only valid for automatic cell width if (this.cellWidthSpec !== 'Auto') { return; } var total = this.nav.top.clientWidth; var header = this._getOuterRowHeaderWidth(); var full = total - header; var cell = full / this._cellCount(); this.cellWidth = Math.floor(cell); //calendar.debug.message("AutoCellWidth: " + this.cellWidth); }; this._getScrollableWidth = function() { // only the visible part /* if (this.nav.scroll) { this.debug.message("scrollableWidth/clientWidth: " + this.nav.scroll.clientWidth); return this.nav.scroll.clientWidth; } */ // // TODO get directly from nav.scroll (but it may not be ready yet) var total = this.nav.top.clientWidth; var header = this._getOuterRowHeaderWidth(); var manualAdjustment = 2; var height = this._getScrollableHeight(); var innerHeight = this._getScrollableInnerHeight(); var scrollBarWidth = 0; if (innerHeight > height) { scrollBarWidth = DayPilot.swa(); } var full = total - header - manualAdjustment - scrollBarWidth; this.debug.message("scrollableWidth: " + full); return full; }; this._drawTimeHeaderDiv = function() { var div = document.createElement("div"); div.style.overflow = 'hidden'; if (!this.cssOnly) { div.style.backgroundColor = this.hourNameBackColor; //div.style.borderRight = "1px solid " + this.borderColor; } div.style.position = 'absolute'; div.style.display = 'block'; div.style.top = "0px"; div.style.width = "100%"; div.style.height = this._getTotalHeaderHeight() + "px"; div.style.overflow = "hidden"; div.onmousemove = function() { calendar._out(); if (calendar.cellBubble) { calendar.cellBubble.delayedHide(); } }; this._setRightColWidth(div); this.divTimeScroll = div; var inner = document.createElement("div"); /* if (!this.cssOnly) { inner.style.borderTop = "1px solid " + this.borderColor; } */ inner.style.width = (this._cellCount() * this.cellWidth + 5000) + "px"; this.divNorth = inner; div.appendChild(inner); return div; }; this._getScrollableHeight = function() { var height = 0; if (this.heightSpec === 'Fixed' || this.heightSpec === "Parent100Pct") { return this.height ? this.height : 0; } else { height = this._getScrollableInnerHeight(); } if (this.heightSpec === 'Max' && height > this.height) { return this.height; } return height; }; this._getScrollableInnerHeight = function() { var height; if (this._innerHeightTree) { var scrollHeight = DayPilot.sh(calendar.nav.scroll); if (scrollHeight === 0) { // no horizontal scrollbar height = this._innerHeightTree; } else { height = this._innerHeightTree + scrollHeight; // guessing that the vertical scrollbar width is the same as horizontal scrollbar height, used to be 18 hardcoded } } else { height = this.rowlist.length * this._resolved.eventHeight(); } return height; }; /* this._findGrouplineX = function(left) { for (var i = 0; i < this.groupline.length; i++) { var cell = this.groupline[i]; if (left >= cell.left && left < cell.left + cell.width) { return i; } } return this.groupline.length - 1; }; */ this._out = function() { this._crosshairHide(); this._stopScroll(); this._cellhoverout(); }; this._drawMainContent = function() { var div = document.createElement("div"); /* if (this.cellWidthSpec === "Auto") { div.style.overflowX = "hidden"; div.style.overflowY = "auto"; } else {*/ div.style.overflow = "auto"; div.style.overflowX = "auto"; div.style.overflowY = "auto"; //} //div.style.overflow = "scroll"; div.style.position = "absolute"; div.style.height = (this._getScrollableHeight()) + "px"; div.style.top = (this._getTotalHeaderHeight() + 1) + "px"; div.style.width = "100%"; if (!this.cssOnly) { div.style.backgroundColor = this.emptyBackColor; } div.className = this._prefixCssClass("_scrollable"); div.oncontextmenu = function() { return false; }; this._setRightColWidth(div); //this.divScroll = div; this.nav.scroll = div; this._maind = document.createElement("div"); this._maind.style.MozUserSelect = "none"; this._maind.style.KhtmlUserSelect = "none"; this._maind.style.webkitUserSelect = "none"; this._maind.daypilotMainD = true; this._maind.calendar = this; // used in DayPilotScheduler.gTouchMove // Android browser bug if (android) { this._maind.style.webkitTransform = "translateZ(0px)"; } this._maind.style.position = 'absolute'; //this._maind.style.overflow = "hidden"; var gridwidth = this._getGridWidth(); if (gridwidth > 0 && !isNaN(gridwidth)) { this._maind.style.width = (gridwidth) + "px"; } this._maind.setAttribute("unselectable", "on"); this._maind.onmousedown = this._onMaindMouseDown; this._maind.onmousemove = this._onMaindMouseMove; this._maind.onmouseup = this._onMaindMouseUp; // there used to be a typo here this._maind.oncontextmenu = this._onMaindRightClick; this._maind.ondblclick = this._onMaindDblClick; this._maind.className = this._prefixCssClass("_matrix"); this.divStretch = document.createElement("div"); this.divStretch.style.position = 'absolute'; this.divStretch.style.height = '1px'; this._maind.appendChild(this.divStretch); this.divCells = document.createElement("div"); this.divCells.style.position = 'absolute'; this.divCells.oncontextmenu = this._onMaindRightClick; this._maind.appendChild(this.divCells); this.divLines = document.createElement("div"); this.divLines.style.position = 'absolute'; this.divLines.oncontextmenu = this._onMaindRightClick; this._maind.appendChild(this.divLines); this.divBreaks = document.createElement("div"); this.divBreaks.style.position = 'absolute'; this.divBreaks.oncontextmenu = this._onMaindRightClick; this._maind.appendChild(this.divBreaks); this.divSeparators = document.createElement("div"); this.divSeparators.style.position = 'absolute'; this.divSeparators.oncontextmenu = this._onMaindRightClick; this._maind.appendChild(this.divSeparators); this.divLinksBelow = document.createElement("div"); this.divLinksBelow.style.position = "absolute"; this._maind.appendChild(this.divLinksBelow); this.divCrosshair = document.createElement("div"); this.divCrosshair.style.position = 'absolute'; this.divCrosshair.ondblclick = this._onMaindDblClick; this._maind.appendChild(this.divCrosshair); this.divRange = document.createElement("div"); this.divRange.style.position = 'absolute'; this.divRange.oncontextmenu = this._onMaindRightClick; this._maind.appendChild(this.divRange); this.divEvents = document.createElement("div"); this.divEvents.style.position = 'absolute'; this._maind.appendChild(this.divEvents); this.divSeparatorsAbove = document.createElement("div"); this.divSeparatorsAbove.style.position = 'absolute'; this.divSeparatorsAbove.oncontextmenu = this._onMaindRightClick; this._maind.appendChild(this.divSeparatorsAbove); this.divLinksAbove = document.createElement("div"); this.divLinksAbove.style.position = "absolute"; this._maind.appendChild(this.divLinksAbove); this.divLinkShadow = document.createElement("div"); this.divLinkShadow.style.position = "absolute"; this._maind.appendChild(this.divLinkShadow); this.divLinkpoints = document.createElement("div"); this.divLinkpoints.style.position = "absolute"; this._maind.appendChild(this.divLinkpoints); this.divRectangle = document.createElement("div"); this.divRectangle.style.position = "absolute"; this._maind.appendChild(this.divRectangle); this.divHover = document.createElement("div"); this.divHover.style.position = 'absolute'; this._maind.appendChild(this.divHover); // TODO add scroll labels div.appendChild(this._maind); return div; }; this._overlay = {}; var overlay = this._overlay; overlay.create = function() { if (calendar.nav.overlay) { return; } var div = document.createElement('div'); div.style.position = "absolute"; div.style.left = "0px"; div.style.right = "0px"; div.style.top = "0px"; div.style.bottom = "0px"; div.className = calendar._prefixCssClass("_block"); calendar.nav.top.appendChild(div); calendar.nav.overlay = div; }; overlay.show = function() { overlay.create(); calendar.nav.overlay.style.display = ''; }; overlay.hide = function() { if (calendar.nav.overlay) { calendar.nav.overlay.style.display = 'none'; } }; this._loadingStart = function(immediately) { if (calendar.loadingTimeout) { window.clearTimeout(calendar.loadingTimeout); } var delay = immediately ? 0 : 100; calendar.loadingTimeout = window.setTimeout(function() { if (calendar.loadingLabelVisible) { calendar.nav.loading.innerHTML = calendar.loadingLabelText; calendar.nav.loading.style.display = ''; } if (calendar.blockOnCallBack) { overlay.show(); } }, delay); }; this._loadingStop = function(msg) { //calendar.status.loadingEvents = false; if (this.loadingTimeout) { window.clearTimeout(this.loadingTimeout); } if (msg) { this.nav.loading.innerHTML = msg; window.setTimeout(function() { calendar._loadingStop(); }, 1000); } else { this.nav.loading.style.display = 'none'; if (this.blockOnCallBack) { overlay.hide(); } } }; this._prepareVariables = function() { this.startDate = new DayPilot.Date(this.startDate).getDatePart(); //this._getEventHeightFromCss(); }; this._getDimensionsFromCss = function(className) { var div = document.createElement("div"); div.style.position = "absolute"; div.style.top = "-2000px"; div.style.left = "-2000px"; div.className = this._prefixCssClass(className); document.body.appendChild(div); var height = div.offsetHeight; var width = div.offsetWidth; document.body.removeChild(div); var result = {}; result.height = height; result.width = width; return result; }; // interval defined in seconds, minimum 30 seconds this._startAutoRefresh = function(forceEnabled) { if (forceEnabled) { this.autoRefreshEnabled = true; } if (!this.autoRefreshEnabled) { return; } if (this.autoRefreshCount >= this.autoRefreshMaxCount) { return; } //calendar.debug.message("autorefresh started"); this._pauseAutoRefresh(); var interval = this.autoRefreshInterval; if (!interval || interval < 10) { throw "The minimum autoRefreshInterval is 10 seconds"; } //this.autoRefresh = interval * 1000; this.autoRefreshTimeout = window.setTimeout(function() { calendar._doRefresh(); }, this.autoRefreshInterval * 1000); }; this._pauseAutoRefresh = function() { if (this.autoRefreshTimeout) { window.clearTimeout(this.autoRefreshTimeout); } }; this._doRefresh = function() { // skip if an operation is active if (!DayPilotScheduler.resizing && !DayPilotScheduler.moving && !DayPilotScheduler.drag && !DayPilotScheduler.range) { var skip = false; if (typeof this.onAutoRefresh === 'function') { var args = {}; args.i = this.autoRefreshCount; args.preventDefault = function() { this.preventDefault.value = true; }; calendar.onAutoRefresh(args); if (args.preventDefault.value) { skip = true; } } if (!skip && this._serverBased()) { this.commandCallBack(this.autoRefreshCommand); } this.autoRefreshCount++; } if (this.autoRefreshCount < this.autoRefreshMaxCount) { this.autoRefreshTimeout = window.setTimeout(function() { calendar._doRefresh(); }, this.autoRefreshInterval * 1000); } }; this._registerGlobalHandlers = function() { if (!DayPilotScheduler.globalHandlers) { DayPilotScheduler.globalHandlers = true; DayPilot.re(document, 'mousemove', DayPilotScheduler.gMouseMove); DayPilot.re(document, 'mouseup', DayPilotScheduler.gMouseUp); DayPilot.re(document, 'keyup', DayPilotScheduler.gKeyUp); DayPilot.re(document, 'mousedown', DayPilotScheduler.gMouseDown); DayPilot.re(document, 'touchmove', DayPilotScheduler.gTouchMove); DayPilot.re(document, 'touchend', DayPilotScheduler.gTouchEnd); //DayPilot.re(window, 'unload', DayPilotScheduler.gUnload); } DayPilot.re(window, 'resize', this._resize); }; this._registerOnScroll = function() { this.nav.scroll.root = this; // might not be necessary this.nav.scroll.onscroll = this._onScroll; calendar._scrollPos = this.nav.scroll.scrollLeft; calendar._scrollTop = this.nav.scroll.scrollTop; calendar._scrollWidth = this.divNorth.clientWidth; // this is always available, divScroll might be not (if there are no resources) }; this._saveState = function() { if (!this.nav.state) { return; } //var start = new Date(); var state = {}; state.scrollX = this.nav.scroll.scrollLeft; state.scrollY = this.nav.scroll.scrollTop; if (this.syncResourceTree) { state.tree = this._getTreeState(); } this.nav.state.value = DayPilot.he(DayPilot.JSON.stringify(state)); }; this._drawSeparators = function() { if (!this.separators) { return; } for (var i = 0; i < this.separators.length; i++) { this._drawSeparator(i); } }; this._batch = {}; this._batch.step = 300; this._batch.delay = 10; this._batch.mode = "display"; this._batch.layers = true; this._updateEventPositionsInRow = function(row) { var alwaysRecalculate = true; var eventMarginTop = this.durationBarDetached ? -10 : 0; var lineTop = 0; for (var j = 0; j < row.lines.length; j++) { var line = row.lines[j]; for (var k = 0; k < line.length; k++) { var e = line[k]; // do something faster instead, probably move it to another function if (!e.part.top || alwaysRecalculate) { e.part.line = j; if (!e.part.height) { e.part.height = row.eventHeight; } //e.part.top = j * (e.part.height + eventMarginTop) + eventMarginTop; e.part.top = lineTop + row.marginTop; e.part.detachedBarTop = e.part.top - eventMarginTop; //e.part.height = this._resolved.eventHeight(); e.part.right = e.part.left + e.part.width; e.part.fullTop = this.rowlist[e.part.dayIndex].top + e.part.top; e.part.fullBottom = e.part.fullTop + e.part.height; } } lineTop += (line.height || row.eventHeight) * this.eventStackingLineHeight/100; } }; // batch rendering flushes events in 10-item batches this._drawEvents = function(batch) { var step = this._batch.step; // batch size var layers = this._batch.layers; // experimental if (layers) { // create a new layer calendar.divEvents = document.createElement("div"); calendar.divEvents.style.position = 'absolute'; // relative // calendar.maind.appendChild(this.divEvents); calendar._maind.insertBefore(this.divEvents, this.divSeparatorsAbove); } if (this._batch.mode === 'display') { this.divEvents.style.display = 'none'; } else if (this._batch.mode === 'visibility') { this.divEvents.style.visibility = 'hidden'; } var dynamic = this.dynamicEventRendering === 'Progressive'; var area = this._getDrawArea(); var top = area.pixels.top; var bottom = area.pixels.bottom; for (var i = 0; i < this.rowlist.length; i++) { var row = this.rowlist[i]; var rowTop = row.top - this.dynamicEventRenderingMargin; var rowBottom = rowTop + row.height + 2 * this.dynamicEventRenderingMargin; if (dynamic && (bottom <= rowTop || top >= rowBottom)) { continue; } this._updateEventPositionsInRow(row); for (var j = 0; j < row.lines.length; j++) { var line = row.lines[j]; for (var k = 0; k < line.length; k++) { var e = line[k]; var rendered = this._drawEvent(e); if (batch && rendered) { step--; // flush if (step <= 0) { this.divEvents.style.visibility = ''; this.divEvents.style.display = ''; window.setTimeout(function() { calendar._drawEvents(batch); }, calendar._batch.delay); return; } } } } } this.divEvents.style.display = ''; this._findEventsInViewPort(); linktools.load(); this._loadingStop(); }; this._drawEventsInRow = function(rowIndex) { // not hiding and showing this.divEvents, caused flickering var row = this.rowlist[rowIndex]; // create new layer this.divEvents = document.createElement("div"); this.divEvents.style.position = 'absolute'; // relative this.divEvents.style.display = 'none'; //this.maind.appendChild(this.divEvents); this._maind.insertBefore(this.divEvents, this.divSeparatorsAbove); var eventMarginTop = this.durationBarDetached ? 10 : 0; this._updateEventPositionsInRow(row); //var lineTop = 0; for (var j = 0; j < row.lines.length; j++) { var line = row.lines[j]; for (var k = 0; k < line.length; k++) { var e = line[k]; /* // this must always be perfomed during row redrawing e.part.line = j; if (!e.part.height) { e.part.height = row.eventHeight; } //e.part.height = row.eventHeight; e.part.top = line.top + row.marginTop; //e.part.top = j * (e.part.height + eventMarginTop) + eventMarginTop; e.part.detachedBarTop = e.part.top - eventMarginTop; e.part.right = e.part.left + e.part.width; e.part.fullTop = this.rowlist[e.part.dayIndex].top + e.part.top; e.part.fullBottom = e.part.fullTop + e.part.height; */ // batch rendering not supported here this._drawEvent(e); } //lineTop += (line.height || row.eventHeight) * this.eventStackingLineHeight / 100; } this.divEvents.style.display = ''; //this._findEventsInViewPort(); //this.multiselect.redraw(); }; this._deleteEvents = function() { if (this.elements.events) { var length = this.elements.events.length; for (var i = 0; i < length; i++) { var div = this.elements.events[i]; this._deleteEvent(div); } } this.elements.events = []; }; this._deleteEventsInRow = function(rowIndex) { //var count = 0; if (this.elements.events) { var length = this.elements.events.length; var removed = []; for (var i = 0; i < length; i++) { var div = this.elements.events[i]; if (div.row === rowIndex) { this._deleteEvent(div); removed.push(i); //count += 1; } } for (var i = removed.length - 1; i >= 0; i--) { this.elements.events.splice(removed[i], 1); } } }; this._deleteEvent = function(div) { // direct event handlers div.onclick = null; div.oncontextmenu = null; div.onmouseover = null; div.onmouseout = null; div.onmousemove = null; div.onmousedown = null; div.ondblclick = null; if (div.event) { if (!div.isBar) { div.event.rendered = null; } div.event = null; } if (div.related) { DayPilot.de(div.related); } if (div.parentNode) { div.parentNode.removeChild(div); } }; this._deleteBlock = function(div) { if (div.event) { div.event.rendered = false; } div.onclick = null; div.onmousedown = null; div.event = null; if (div.parentNode) { div.parentNode.removeChild(div); } }; // deletes events that are out of the current view // keeps the last "keepPlus" number of events outside of the view this._deleteOldEvents = function(keepPlus) { if (!keepPlus) { keepPlus = 0; } if (this.dynamicEventRendering !== 'Progressive') { return; } this.divEvents.style.display = 'none'; var updated = []; var deleted = 0; var length = this.elements.events.length; for (var i = length - 1; i >= 0; i--) { var div = this.elements.events[i]; if (this._oldEvent(div.event)) { if (keepPlus > 0) { keepPlus--; updated.unshift(div); } else { this._deleteEvent(div); deleted++; } } else { updated.unshift(div); } } this.elements.events = updated; this.divEvents.style.display = ''; }; this._deleteOldCells = function(keepPlus) { var updated = []; var deleted = 0; var area = this._getDrawArea(); var length = this.elements.cells.length; for (var i = length - 1; i >= 0; i--) { var div = this.elements.cells[i]; var visible = (area.xStart < div.coords.x && div.coords.x <= area.xEnd) && (area.yStart < div.coords.y && div.coords.y <= area.yEnd); if (!visible) { if (keepPlus > 0) { keepPlus--; updated.unshift(div); } else { this._deleteCell(div); deleted++; } } else { updated.unshift(div); } } }; this._deleteCell = function(div) { if (!div) { return; } var x = div.coords.x; var y = div.coords.y; // remove div var index = DayPilot.indexOf(calendar.elements.cells, div); calendar.elements.cells.splice(index, 1); if (div.parentNode) { div.parentNode.removeChild(div); } // remove from cache calendar._cache.cells[x + "_" + y] = null; }; this._deleteSeparators = function() { if (this.elements.separators) { for (var i = 0; i < this.elements.separators.length; i++) { var div = this.elements.separators[i]; //DayPilot.pu(div); // not necessary DayPilot.de(div); //div.parentNode.removeChild(div); } } this.elements.separators = []; }; this._hiddenEvents = function() { var dynamic = this.dynamicEventRendering === 'Progressive'; if (!this.nav.scroll) { return false; } var top = this.nav.scroll.scrollTop; var bottom = top + this.nav.scroll.clientHeight; for (var i = 0; i < this.rowlist.length; i++) { var row = this.rowlist[i]; var rowTop = row.top; var rowBottom = row.top + row.height; if (dynamic && (bottom <= rowTop || top >= rowBottom)) { continue; } for (var j = 0; j < row.lines.length; j++) { var line = row.lines[j]; for (var k = 0; k < line.length; k++) { var e = line[k]; if (this._hiddenEvent(e)) { return true; } } } } return false; }; this._hiddenEvent = function(data) { if (data.rendered) { return false; } var dynamic = this.dynamicEventRendering === 'Progressive'; var left = this.nav.scroll.scrollLeft; var right = left + this.nav.scroll.clientWidth; var eventLeft = data.Left; var eventRight = data.Left + data.Width; if (dynamic && (right <= eventLeft || left >= eventRight)) { return false; } return true; }; this._oldEvent = function(ev) { if (!ev.rendered) { // just for the case, these events might not have Top defined return true; } var area = this._getDrawArea(); var top = area.pixels.top; var bottom = area.pixels.bottom; var left = area.pixels.left - this.dynamicEventRenderingMargin; var right = area.pixels.right + this.dynamicEventRenderingMargin; var eventLeft = ev.part.left; var eventRight = ev.part.right; var eventTop = ev.part.fullTop; var eventBottom = ev.part.fullBottom; if (right <= eventLeft || left >= eventRight) { return true; } if (bottom <= eventTop || top >= eventBottom) { return true; } return false; }; this._drawBlock = function(block) { if (block.rendered) { return false; } var left = block.min; var width = block.max - block.min; var height = calendar.eventHeight; var top = block.row.top; var div = document.createElement("div"); div.style.position = 'absolute'; div.style.left = left + 'px'; div.style.top = top + 'px'; div.style.width = width + 'px'; div.style.height = height + 'px'; // temp styling div.className = calendar._prefixCssClass("_event_group"); div.style.cursor = "pointer"; var args = {}; args.group = {}; args.group.count = block.events.length; args.group.html = "[+] " + block.events.length + " events"; if (typeof calendar.onBeforeGroupRender === "function") { calendar.onBeforeGroupRender(args); } var inner = document.createElement("div"); inner.innerHTML = args.group.html; div.appendChild(inner); div.onmousedown = function(ev) { var ev = ev || window.event; ev.cancelBubble = true; }; div.onclick = function(ev) { var block = div.event; block.expanded = true; calendar._deleteBlock(div); var elindex = DayPilot.indexOf(calendar.elements.events, div); if (elindex !== -1) { calendar.elements.events.splice(elindex, 1); } //calendar._drawEvents(); calendar._updateRowHeights(); calendar._updateRowsNoLoad(block.part.dayIndex); calendar._updateHeight(); var ev = ev || window.event; ev.cancelBubble = true; }; // make it compatible with event.part // TODO resolve block.part = {}; block.part.left = left; block.part.width = width; block.part.dayIndex = DayPilot.indexOf(calendar.rowlist, block.row); block.part.top = 0; block.client = {}; block.client.html = function() { return args.group.html; }; div.event = block; // add it to the events collection this.elements.events.push(div); // draw the div this.divEvents.appendChild(div); block.rendered = true; return true; }; // returns true if the event was actually rendered this._drawEvent = function(data) { if (data.rendered) { return false; } if (calendar.groupConcurrentEvents) { var block = data.part.block; if (block.events.length > 1 && !block.expanded) { return calendar._drawBlock(block); } } //var dynamic = this.dynamicEventRendering === 'Progressive' && !this.dynamicLoading; var dynamic = this.dynamicEventRendering === 'Progressive'; /* var left = this.nav.scroll.scrollLeft - this.dynamicEventRenderingMargin; var right = left + this.nav.scroll.clientWidth + 2 * this.dynamicEventRenderingMargin; */ var area = this._getDrawArea(); var left = area.pixels.left - this.dynamicEventRenderingMargin; var right = area.pixels.right + this.dynamicEventRenderingMargin; var eventLeft = data.part.left; var eventRight = data.part.left + data.part.width; if (dynamic && (right <= eventLeft || left >= eventRight)) { // dynamic rendering, event outside of the current view return false; } var rowIndex = data.part.dayIndex; var borders = !this.cssOnly && this.eventBorderVisible; var width = data.part.width; var height = data.part.height; if (borders) { width -= 2; height -= 2; } var cache = data.cache || data.data; // make sure it's not negative width = Math.max(0, width); height = Math.max(0, height); var row = this.rowlist[rowIndex]; if (row.hidden) { return false; } // prepare the top position var rowTop = row.top; //var line = data.part.top / this.eventHeight; var div = document.createElement("div"); /* div.style.KhtmlUserSelect = 'none'; div.style.MozUserSelect = 'none'; div.style.webkitUserSelect = 'none'; */ var barDetached = this.durationBarDetached; div.related = []; if (barDetached) { var barLeft = data.part.barLeft; var barWidth = data.part.barWidth; if (this.durationBarMode === "PercentComplete") { barLeft = 0; barWidth = (cache.complete || 0) / 100 * width; } var bar = document.createElement("div"); bar.style.position = 'absolute'; bar.style.left = (data.part.left + barLeft) + 'px'; bar.style.top = (rowTop + data.part.detachedBarTop) + 'px'; bar.style.width = barWidth + 'px'; bar.style.height = 5 + 'px'; bar.style.backgroundColor = "black"; bar.type = "detachedBar"; div.related.push(bar); // add it to the events collection //this.elements.bars.push(bar); // draw the div this.divEvents.appendChild(bar); } if (data.data.htmlLeft) { var margin = 5; var divLeft = document.createElement("div"); divLeft.style.position = 'absolute'; divLeft.style.right = -(data.part.left - margin) + 'px'; divLeft.style.top = (rowTop + data.part.top) + 'px'; divLeft.style.height = calendar.eventHeight + 'px'; divLeft.style.boxSizing = "border-box"; divLeft.innerHTML = data.data.htmlLeft; divLeft.className = calendar._prefixCssClass("_event_left"); divLeft.type = "divLeft"; div.related.push(divLeft); // draw the div this.divEvents.appendChild(divLeft); } if (data.data.htmlRight) { var margin = 5; var divRight = document.createElement("div"); divRight.style.position = 'absolute'; divRight.style.left = (data.part.left + data.part.width + margin) + 'px'; divRight.style.top = (rowTop + data.part.top) + 'px'; divRight.style.height = calendar.eventHeight + 'px'; divRight.style.boxSizing = "border-box"; divRight.innerHTML = data.data.htmlRight; divRight.className = calendar._prefixCssClass("_event_right"); divRight.type = "divRight"; div.related.push(divRight); // draw the div this.divEvents.appendChild(divRight); } var top = rowTop + data.part.top; //div.data = data; div.style.position = 'absolute'; div.style.left = data.part.left + 'px'; div.style.top = (rowTop + data.part.top) + 'px'; div.style.width = width + 'px'; div.style.height = height + 'px'; if (!this.cssOnly) { if (calendar.eventBorderVisible) { div.style.border = '1px solid ' + (cache.borderColor || this.eventBorderColor); } div.style.backgroundColor = data.client.backColor(); div.style.fontSize = this.eventFontSize; div.style.cursor = 'default'; div.style.fontFamily = this.eventFontFamily; div.style.color = cache.fontColor || this.eventFontColor; // TODO move inside Event as fontColor() if (cache.backImage && !this.durationBarVisible) { div.style.backgroundImage = "url(" + cache.backImage + ")"; if (cache.backRepeat) { div.style.backgroundRepeat = cache.backRepeat; } } if (this._resolved.rounded()) { div.style.MozBorderRadius = "5px"; div.style.webkitBorderRadius = "5px"; div.style.borderRadius = "5px"; } } if (!calendar.eventTextWrappingEnabled) { div.style.whiteSpace = 'nowrap'; } div.style.overflow = 'hidden'; div.className = this.cssOnly ? this._prefixCssClass("_event") : this._prefixCssClass("event"); if (data.data.type === "Milestone") { DayPilot.Util.addClass(div, calendar._prefixCssClass("_task_milestone")); } if (data.data.type === "Group") { DayPilot.Util.addClass(div, calendar._prefixCssClass("_task_parent")); // remove DayPilot.Util.addClass(div, calendar._prefixCssClass("_task_group")); } if (cache.cssClass) { DayPilot.Util.addClass(div, cache.cssClass); } var lineClasses = true; if (lineClasses) { DayPilot.Util.addClass(div, this._prefixCssClass("_event_line" + data.part.line)); } div.setAttribute("unselectable", "on"); if (this.showToolTip && !this.bubble) { div.title = data.client.toolTip(); } div.onmousemove = this._onEventMouseMove; div.onmouseout = this._onEventMouseOut; div.onmousedown = this._onEventMouseDown; div.ontouchstart = touch.onEventTouchStart; div.ontouchmove = touch.onEventTouchMove; div.ontouchend = touch.onEventTouchEnd; if (data.client.clickEnabled()) { div.onclick = this._onEventClick; } if (data.client.doubleClickEnabled()) { div.ondblclick = this._eventDoubleClickDispatch; } div.oncontextmenu = this._eventRightClickDispatch; var inside = []; var durationBarHeight = 0; // inner divs if (this.cssOnly) { var inner = document.createElement("div"); inner.setAttribute("unselectable", "on"); inner.className = calendar._prefixCssClass("_event_inner"); if (data.data.additionalClassName) { inner.className += " " + data.data.additionalClassName; } if (data.data.collisionCount) { inner.setAttribute("collision-count", data.data.collisionCount); } inner.innerHTML = data.client.innerHTML(); if (cache.backColor) { inner.style.background = cache.backColor; if (DayPilot.browser.ie9 || DayPilot.browser.ielt9) { inner.style.filter = ''; } } if (cache.fontColor) { inner.style.color = cache.fontColor; } if (cache.borderColor) { inner.style.borderColor = cache.borderColor; } if (cache.backImage) { inner.style.backgroundImage = "url(" + cache.backImage + ")"; if (cache.backRepeat) { inner.style.backgroundRepeat = cache.backRepeat; } } div.appendChild(inner); var startsHere = data.start().getTime() === data.part.start.getTime(); var endsHere = data.rawend().getTime() === data.part.end.getTime(); if (!startsHere) { DayPilot.Util.addClass(div, this._prefixCssClass("_event_continueleft")); } if (!endsHere) { DayPilot.Util.addClass(div, this._prefixCssClass("_event_continueright")); } if (data.client.barVisible() && width > 0) { var barLeft = 100 * data.part.barLeft / (width); // % var barWidth = Math.ceil(100 * data.part.barWidth / (width)); // % if (this.durationBarMode === "PercentComplete") { barLeft = 0; barWidth = cache.complete || 0; } var bar = document.createElement("div"); bar.setAttribute("unselectable", "on"); bar.className = this._prefixCssClass("_event_bar"); bar.style.position = "absolute"; if (cache.barBackColor) { bar.style.backgroundColor = cache.barBackColor; } var barInner = document.createElement("div"); barInner.setAttribute("unselectable", "on"); barInner.className = this._prefixCssClass("_event_bar_inner"); barInner.style.left = barLeft + "%"; //barInner.setAttribute("barWidth", data.part.barWidth); // debug if (0 < barWidth && barWidth <= 1) { barInner.style.width = "1px"; } else { barInner.style.width = barWidth + "%"; } if (cache.barColor) { barInner.style.backgroundColor = cache.barColor; } if (cache.barImageUrl) { barInner.style.backgroundImage = "url(" + cache.barImageUrl + ")"; } bar.appendChild(barInner); div.appendChild(bar); } } else { if (data.client.barVisible()) { durationBarHeight = calendar.durationBarHeight; // white space left inside.push("
"); // white space right inside.push(""); if (this.durationBarMode === "Duration") { inside.push(""); inside.push(""); } inside.push("