SmartIT_Extensions/BMC/smart-it-full/scripts/vendor/daypilot-8.0.3413/Scheduler.src.js

16840 lines
581 KiB
JavaScript

/* 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 = "&nbsp;";
}
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 = '&nbsp;';
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("<div unselectable='on' style='left:0px;background-color:white;width:");
inside.push(data.part.barLeft);
inside.push("px;height:2px;font-size:1px;position:absolute'></div>");
// white space right
inside.push("<div unselectable='on' style='left:");
inside.push(data.part.barLeft + data.part.barWidth);
inside.push("px;background-color:white;width:");
inside.push(width - (data.part.barLeft + data.part.barWidth));
inside.push("px;height:2px;font-size:1px;position:absolute'></div>");
if (this.durationBarMode === "Duration") {
inside.push("<div unselectable='on' style='width:");
inside.push(data.part.barWidth);
inside.push("px;margin-left:");
inside.push(data.part.barLeft);
inside.push("px;height:");
}
else {
inside.push("<div unselectable='on' style='width:");
inside.push(cache.complete);
inside.push("%;margin-left:0px;height:");
}
inside.push(durationBarHeight - 1);
inside.push("px;background-color:");
inside.push(data.client.barColor());
if (cache.barImageUrl) {
inside.push(";background-image:url(");
inside.push(cache.barImageUrl);
inside.push(")");
}
inside.push(";font-size:1px;position:relative'></div>");
inside.push("<div unselectable='on' style='width:");
inside.push(width);
inside.push("px;height:1px;background-color:");
inside.push((cache.borderColor || this.eventBorderColor));
inside.push(";font-size:1px;overflow:hidden;position:relative'></div>");
}
inside.push("<div unselectable='on' style='padding-left:1px;width:");
inside.push(width - 1);
inside.push("px;height:");
inside.push(height - durationBarHeight);
inside.push("px;");
if (calendar.rtl) {
inside.push("direction:rtl;");
}
if (cache.backImage && this.durationBarVisible) {
inside.push("background-image:url(");
inside.push(cache.backImage);
inside.push(");");
if (cache.backRepeat) {
inside.push("background-repeat:");
inside.push(cache.backRepeat);
inside.push(";");
}
}
inside.push("'>");
inside.push(data.client.innerHTML());
inside.push("</div>");
div.innerHTML = inside.join('');
}
div.row = rowIndex;
if (cache.areas) {
for (var i = 0; i < cache.areas.length; i++) {
var area = cache.areas[i];
var v = area.v || "Visible";
if (v !== "Visible") {
continue;
}
var a = DayPilot.Areas.createArea(div, data, area);
div.appendChild(a);
}
}
// add it to the events collection
this.elements.events.push(div);
// draw the div
this.divEvents.appendChild(div);
data.rendered = true;
// init code for the event
//div.event = new DayPilotScheduler.Event(div.data, calendar);
div.event = data;
if (calendar.multiselect._shouldBeSelected(div.event)) {
calendar.multiselect.add(div.event, true);
calendar.multiselect._update(div);
}
if (calendar._api2()) {
if (typeof calendar.onAfterEventRender === 'function') {
var args = {};
args.e = div.event;
args.div = div;
calendar.onAfterEventRender(args);
}
}
else {
if (calendar.afterEventRender) {
calendar.afterEventRender(div.event, div);
}
}
return true;
};
this._api2 = function() {
return calendar.api === 2;
};
this._updateEventTops = function() {
for (var i = 0; i < this.elements.events.length; i++) {
var div = this.elements.events[i];
var event = div.event;
var rowIndex = event.part.dayIndex;
var row = this.rowlist[rowIndex];
var rowTop = row.top;
var top = rowTop + event.part.top;
div.style.top = top + 'px';
if (DayPilot.isArray(div.related)) {
for (var j = 0; j < div.related.length; j++) {
var rel = div.related[j];
if (rel.type === "divLeft" || rel.type === "divRight") {
rel.style.top = top + 'px';
}
}
}
/*
if (div.bar) {
div.bar.style.top = (rowTop + event.part.top + 10) + 'px'; // HACK
}*/
}
};
this._findEventDiv = function(e) {
if (!e) {
return null;
}
for (var i = 0; i < calendar.elements.events.length; i++) {
var div = calendar.elements.events[i];
if (div.event === e || div.event.data === e.data) {
return div;
}
}
return null;
};
this._onEventMouseOut = function(ev) {
var div = this;
DayPilot.Areas.hideAreas(div, ev);
if (calendar.cssOnly) {
DayPilot.Util.removeClass(div, calendar._prefixCssClass("_event_hover"));
}
calendar._doEventMouseOut(div);
if (!linking.source) {
linktools.hideLinkpointsWithDelay();
}
if (calendar.bubble && calendar.eventHoverHandling === 'Bubble') {
calendar.bubble.hideOnMouseOut();
}
};
this._doEventMouseOver = function(div) {
if (typeof this.onEventMouseOver === "function") {
var args = {};
args.div = div;
args.e = div.event;
this.onEventMouseOver(args);
}
};
this._doEventMouseOut = function(div) {
if (typeof this.onEventMouseOut === "function") {
var args = {};
args.div = div;
args.e = div.event;
this.onEventMouseOut(args);
}
};
this._onEventMouseMove = function(ev) {
ev = ev || window.event;
if (calendar.cellBubble) { calendar.cellBubble.delayedHide(); }
var div = this;
while (div && !div.event) { // make sure it's the top event div
div = div.parentNode;
}
calendar._eventUpdateCursor(div, ev);
if (!div.active) {
var areas = [];
if (calendar.eventDeleteHandling !== "Disabled") {
var top = calendar.durationBarVisible ? calendar.durationBarHeight : 0;
areas.push({"action":"JavaScript","v":"Hover","w":17,"h":17,"top": top + 2,"right":2, "css": calendar._prefixCssClass("_event_delete"),"js":function(e) { calendar._eventDeleteDispatch(e); } });
}
var list = div.event.cache ? div.event.cache.areas : div.event.data.areas;
if (list && list.length > 0) {
areas = areas.concat(list);
}
DayPilot.Areas.showAreas(div, div.event, null, areas);
if (calendar.cssOnly) {
DayPilot.Util.addClass(div, calendar._prefixCssClass("_event_hover"));
}
calendar._doEventMouseOver(div);
}
if (calendar.linkCreateHandling !== "Disabled" && !linking.source) {
linktools.clearHideTimeout();
linktools.hideLinkpoints();
if (!DayPilotScheduler.moving && !DayPilotScheduler.resizing) {
linktools.showLinkpoint(div);
}
}
if (ev.srcElement) {
ev.srcElement.insideEvent = true;
}
else {
ev.insideEvent = true;
}
// bubbling must be allowed, required for moving and resizing
//ev.cancelBubble = true;
};
this._moving = {};
var moving = this._moving;
this._onEventMouseDown = function(ev) {
calendar._out();
/*
calendar._crosshairHide();
calendar._stopScroll();
*/
if (typeof DayPilot.Bubble !== 'undefined') {
DayPilot.Bubble.hideActive();
}
ev = ev || window.event;
var button = DayPilot.Util.mouseButton(ev);
if (button.left) {
var shift = ev.shiftKey;
if (calendar.multiSelectRectangle !== "Disabled" && shift) {
rectangle.start();
return false;
}
if (this.style.cursor === 'w-resize' || this.style.cursor === 'e-resize') {
// set
DayPilotScheduler.resizing = this;
DayPilotScheduler.originalMouse = DayPilot.mc(ev);
// cursor
document.body.style.cursor = this.style.cursor;
linktools.hideLinkpoints();
}/*
else if () {
//var mv = this;
DayPilotScheduler.moving = this;
DayPilotScheduler.originalMouse = DayPilot.mc(ev);
DayPilotScheduler.moveOffsetX = DayPilot.mo3(this, ev).x;
DayPilotScheduler.moveDragStart = calendar.getDate(calendar.coords.x, true);
// cursor
document.body.style.cursor = 'move';
linktools.hideLinkpoints();
}*/
else if ((this.style.cursor === 'move') || (calendar.moveBy === 'Full' && this.event.client.moveEnabled())) {
moving.start = true;
moving.moving = this;
moving.originalMouse = DayPilot.mc(ev);
moving.moveOffsetX = DayPilot.mo3(this, ev).x;
moving.moveDragStart = calendar.getDate(calendar.coords.x, true);
linktools.hideLinkpoints();
}
}
ev.cancelBubble = true;
return false;
};
this._touch = {};
var touch = calendar._touch;
touch.active = false;
touch.start = false;
touch.timeouts = [];
touch.onEventTouchStart = function(ev) {
// iOS
if (touch.active || touch.start) {
return;
}
// prevent onMainTouchStart
ev.stopPropagation();
touch.clearTimeouts();
touch.start = true;
touch.active = false;
var div = this;
var holdfor = calendar.tapAndHoldTimeout;
touch.timeouts.push(window.setTimeout(function() {
touch.active = true;
touch.start = false;
calendar.coords = touch.relativeCoords(ev);
ev.preventDefault();
switch (calendar.eventTapAndHoldHandling) {
case "Move":
//touch.startMoving(div, coords);
touch.startMoving(div, ev);
break;
case "ContextMenu":
//var div = this;
var e = div.event;
if (DayPilot.Menu) {
DayPilot.Menu.touchPosition(ev);
}
var menu = e.client.contextMenu();
if (menu) {
menu.show(e);
}
else {
if (calendar.contextMenu) {
calendar.contextMenu.show(e);
}
}
break;
}
}, holdfor));
};
touch.onEventTouchMove = function(ev) {
touch.clearTimeouts();
touch.start = false;
};
touch.onEventTouchEnd = function(ev) {
if (DayPilot.Util.isMouseEvent(ev)) {
return;
}
touch.clearTimeouts();
// quick tap
if (touch.start) {
touch.start = false;
//touch.active = false;
ev.preventDefault();
ev.stopPropagation();
var div = this;
window.setTimeout(function() {
calendar._eventClickSingle(div, ev);
});
}
window.setTimeout(function() {
touch.start = false;
touch.active = false;
}, 500);
};
touch.onMainTouchStart = function(ev) {
// prevent after-alert firing on iOS
if (touch.active || touch.start) {
return;
}
touch.clearTimeouts();
touch.start = true;
touch.active = false;
var holdfor = calendar.tapAndHoldTimeout;
touch.timeouts.push(window.setTimeout(function() {
touch.active = true;
touch.start = false;
ev.preventDefault();
calendar.coords = touch.relativeCoords(ev);
touch.range = calendar._rangeFromCoords();
}, holdfor));
var tapAllowed = true;
if (tapAllowed) {
calendar.coords = touch.relativeCoords(ev);
}
};
touch.onMainTouchMove = function(ev) {
touch.clearTimeouts();
touch.start = false;
if (touch.active) {
ev.preventDefault();
calendar.coords = touch.relativeCoords(ev);
if (DayPilotScheduler.moving) {
touch.updateMoving();
return;
}
if (touch.range) {
var range = touch.range;
range.end = {
x: Math.floor(calendar.coords.x / calendar.cellWidth)
};
calendar._drawRange(range);
}
}
};
touch.onMainTouchEnd = function(ev) {
touch.clearTimeouts();
var tapAllowed = true;
if (touch.active) {
if (DayPilotScheduler.moving) {
ev.preventDefault();
var e = DayPilotScheduler.moving.event;
var newStart = DayPilotScheduler.movingShadow.start;
var newEnd = DayPilotScheduler.movingShadow.end;
var newResource = (calendar.viewType !== 'Days') ? DayPilotScheduler.movingShadow.row.id : null;
var external = DayPilotScheduler.drag ? true : false;
//var line = DayPilotScheduler.movingShadow.line;
var overlapping = DayPilotScheduler.movingShadow.overlapping;
var forbidden = !DayPilotScheduler.movingShadow.allowed;
DayPilot.Util.removeClass(DayPilotScheduler.moving, calendar._prefixCssClass("_event_moving_source"));
// clear the moving state
DayPilot.de(DayPilotScheduler.movingShadow);
calendar._clearShadowHover();
DayPilotScheduler.movingShadow.calendar = null;
document.body.style.cursor = '';
DayPilotScheduler.moving = null;
DayPilotScheduler.movingShadow = null;
calendar._multimove.clear();
if (overlapping || forbidden || calendar._multimove.forbidden || calendar._multimove.invalid) {
return;
}
calendar._eventMoveDispatch(e, newStart, newEnd, newResource, external);
}
if (touch.range) {
var range = touch.range;
touch.range = null;
var shadow = calendar.elements.range2;
if (shadow && shadow.overlapping) {
calendar.clearSelection();
}
else {
calendar._timeRangeSelectedDispatchFromRange(range);
}
/*
var sel = calendar._getSelection(touch.range);
touch.range = null;
calendar._timeRangeSelectedDispatch(sel.start, sel.end, sel.resource);
*/
}
}
else if (touch.start && tapAllowed) { // simple tap
var range = calendar._rangeFromCoords();
calendar._drawRange(range);
var shadow = calendar.elements.range2;
if (shadow && shadow.overlapping) {
calendar.clearSelection();
}
else {
calendar._timeRangeSelectedDispatchFromRange(range);
}
/*
var sel = calendar._getSelection(range);
calendar._timeRangeSelectedDispatch(sel.start, sel.end, sel.resource);
*/
}
window.setTimeout(function() {
touch.start = false;
touch.active = false;
}, 500);
};
touch.clearTimeouts = function() {
for (var i = 0; i < touch.timeouts.length; i++) {
clearTimeout(touch.timeouts[i]);
}
touch.timeouts = [];
};
touch.relativeCoords = function(ev) {
var ref = calendar._maind;
var x = ev.touches[0].pageX;
var y = ev.touches[0].pageY;
var abs = DayPilot.abs(ref);
var coords = {x: x - abs.x, y: y - abs.y, toString: function() { return "x: " + this.x + ", y:" + this.y; } };
return coords;
};
// coords - page coords
touch.startMoving = function(div, ev) {
var coords = {x: ev.touches[0].pageX, y: ev.touches[0].pageY};
DayPilotScheduler.moving = div;
DayPilotScheduler.originalMouse = coords;
var absE = DayPilot.abs(div);
DayPilotScheduler.moveOffsetX = coords.x - absE.x;
//var absR = DayPilot.abs(calendar.maind);
//var x = coords.x - absR.x;
DayPilotScheduler.moveDragStart = calendar.getDate(calendar.coords.x, true);
DayPilotScheduler.movingShadow = calendar._createShadow(div, calendar.shadow);
// update dimensions
calendar._moveShadow();
};
// coords - relative to maind
touch.updateMoving = function() {
if (DayPilotScheduler.movingShadow && DayPilotScheduler.movingShadow.calendar !== calendar) {
DayPilotScheduler.movingShadow.calendar = null;
DayPilot.de(DayPilotScheduler.movingShadow);
DayPilotScheduler.movingShadow = null;
}
if (!DayPilotScheduler.movingShadow) {
var mv = DayPilotScheduler.moving;
DayPilotScheduler.movingShadow = calendar._createShadow(mv, calendar.shadow);
}
DayPilotScheduler.moving.target = calendar; //might not be necessary, the target is in DayPilotScheduler.activeCalendar
calendar._moveShadow();
};
this._eventUpdateCursor = function(div, ev) {
/*
if (calendar.moveBy === "Disabled" || calendar.moveBy === "None") {
return;
}
*/
// const
var resizeMargin = this.eventResizeMargin;
var moveMargin = this.eventMoveMargin;
var object = div;
if (typeof (DayPilotScheduler) === 'undefined') {
return;
}
// position
var offset = DayPilot.mo3(div, ev);
if (!offset) {
return;
}
calendar.eventOffset = offset;
if (DayPilotScheduler.resizing) {
return;
}
if (DayPilotScheduler.moving) {
return;
}
var isFirstPart = object.event.part.start.toString() === object.event.start().toString();
var isLastPart = object.event.part.end.toString() === object.event.rawend().toString();
// top
if (calendar.moveBy === 'Top' && offset.y <= moveMargin && object.event.client.moveEnabled() && calendar.eventMoveHandling !== 'Disabled') { // TODO disabled check not necessary
if (isFirstPart) {
div.style.cursor = 'move';
}
else {
div.style.cursor = 'not-allowed';
}
}
// left resizing
else if ((calendar.moveBy === 'Top' || calendar.moveBy === 'Full') && offset.x <= resizeMargin && object.event.client.resizeEnabled() && calendar.eventResizeHandling !== 'Disabled') { // TODO disabled check not necessary
if (isFirstPart) {
div.style.cursor = "w-resize";
div.dpBorder = 'left';
}
else {
div.style.cursor = 'not-allowed';
}
}
// left moving
else if (calendar.moveBy === 'Left' && offset.x <= moveMargin && object.event.client.moveEnabled() && calendar.eventMoveHandling !== 'Disabled') { // TODO disabled check not necessary
if (isFirstPart) {
div.style.cursor = "move";
}
else {
div.style.cursor = 'not-allowed';
}
}
// right
else if (div.offsetWidth - offset.x <= resizeMargin && object.event.client.resizeEnabled() && calendar.eventResizeHandling !== 'Disabled') { // TODO disabled check not necessary
if (isLastPart) {
div.style.cursor = "e-resize";
div.dpBorder = 'right';
}
else {
div.style.cursor = 'not-allowed';
}
}
else if (!DayPilotScheduler.resizing && !DayPilotScheduler.moving) {
if (object.event.client.clickEnabled() && calendar.eventClickHandling !== 'Disabled') { // TODO disabled check not necessary
div.style.cursor = 'pointer';
}
else {
div.style.cursor = 'default';
}
}
if (typeof (DayPilotBubble) !== 'undefined' && calendar.bubble && calendar.eventHoverHandling === 'Bubble') {
if (div.style.cursor === 'default' || div.style.cursor === 'pointer') {
// preventing Chrome bug
var notMoved = this._lastOffset && offset.x === this._lastOffset.x && offset.y === this._lastOffset.y;
if (!notMoved) {
this._lastOffset = offset;
calendar.bubble.showEvent(div.event);
}
}
else {
/*
// disabled, now it is hidden on click
DayPilotBubble.hideActive();
*/
}
}
};
this._cellCount = function() {
if (this.viewType !== 'Days') {
return this.itline.length;
// TODO broken for nonbusiness
//return Math.floor(this.days * 24 * 60 / this.cellDuration);
}
else {
return Math.floor(24 * 60 / this.cellDuration);
}
};
this._getSelection = function(range) {
//var range = DayPilotScheduler.range;
var range = range || DayPilotScheduler.range || DayPilotScheduler.rangeHold;
if (!range) {
return null;
}
var row = calendar.rowlist[range.start.y];
if (!row) {
return null;
}
var r = range._customized ? range._customized : range;
//calendar.debug.message("getSelection, x: " + r.start.x);
var resource = row.id;
var startX = r.end.x > r.start.x ? r.start.x : r.end.x;
var endX = (r.end.x > r.start.x ? r.end.x : r.start.x);
var rowOffset = 0;
if (calendar.viewType === 'Days') {
rowOffset = row.start.getTime() - calendar.startDate.getTime();
}
else {
var rowOffset = row.start.getTime() - this._visibleStart().getTime(); // may be incorrect
}
var start = this.itline[startX].start.addTime(rowOffset);
var end = this.itline[endX].end.addTime(rowOffset);
//end = calendar._adjustEndOut(end);
return new DayPilot.Selection(start, end, resource, calendar);
};
this._createEdit = function(object) {
var parentTd = object.parentNode;
var edit = document.createElement('textarea');
edit.style.position = 'absolute';
edit.style.width = ((object.offsetWidth < 100) ? 100 : (object.offsetWidth - 2)) + 'px';
edit.style.height = (object.offsetHeight - 2) + 'px'; //offsetHeight
edit.style.fontFamily = DayPilot.gs(object, 'fontFamily') || DayPilot.gs(object, 'font-family');
edit.style.fontSize = DayPilot.gs(object, 'fontSize') || DayPilot.gs(object, 'font-size');
edit.style.left = object.offsetLeft + 'px';
edit.style.top = object.offsetTop + 'px';
edit.style.border = '1px solid black';
edit.style.padding = '0px';
edit.style.marginTop = '0px';
edit.style.backgroundColor = 'white';
edit.value = DayPilot.tr(object.event.text());
edit.event = object.event;
parentTd.appendChild(edit);
return edit;
};
this._divEdit = function(object) {
if (DayPilotScheduler.editing) {
DayPilotScheduler.editing.blur();
//return;
}
if (!object.event) {
return;
}
var edit = this._createEdit(object);
DayPilotScheduler.editing = edit;
edit.onblur = function() {
//var id = object.event.value();
//var tag = object.event.tag();
edit.onblur = null;
DayPilotScheduler.editing = null;
if (edit.parentNode) {
edit.parentNode.removeChild(edit);
}
if (!object.event) {
return;
}
var oldText = object.event.text();
var newText = edit.value;
if (oldText === newText || edit.canceling) {
return;
}
//object.style.display = 'none';
calendar._eventEditDispatch(object.event, newText);
};
edit.onmousedown = function(e) {
e = e || window.event;
e.stopPropagation && e.stopPropagation();
};
edit.onkeypress = function(e) {
var keynum = (window.event) ? event.keyCode : e.keyCode;
if (keynum === 13) {
this.onblur();
return false;
}
return true;
};
edit.cancel = function() {
if (DayPilotScheduler.editing) {
DayPilotScheduler.editing.canceling = true;
DayPilotScheduler.editing.blur();
}
};
edit.onkeydown = function(e) {
var keynum = (window.event) ? event.keyCode : e.keyCode;
if (keynum === 27) {
DayPilotScheduler.editing.cancel();
//DayPilotScheduler.editing.blur();
/*edit.parentNode.removeChild(edit);
DayPilotScheduler.editing = false;*/
}
};
edit.select();
edit.focus();
};
this._onResMouseMove = function(ev) {
var td = this;
if (typeof (DayPilotBubble) !== 'undefined') {
if (calendar.cellBubble) {
calendar.cellBubble.hideOnMouseOut();
}
if (calendar.resourceBubble) {
var res = {};
res.calendar = calendar;
res.id = td.row.id;
res.toJSON = function() {
var json = {};
json.id = this.id;
return json;
};
calendar.resourceBubble.showResource(res);
}
}
/*
var div = td.firstChild; // rowheader
if (!div.active) {
var row = calendar.rowlist[td.index];
var r = calendar._createRowObject(row);
r.areas = row.areas;
DayPilot.Areas.showAreas(div, r);
}
*/
};
this._onResMouseOut = function(ev) {
var td = this;
if (typeof (DayPilotBubble) !== 'undefined' && calendar.resourceBubble) {
calendar.resourceBubble.hideOnMouseOut();
}
var div = td.firstChild;
DayPilot.Areas.hideAreas(div, ev);
div.data = null;
};
this._onResMouseUp = function(ev) {
if (rowmoving.row) {
// testing a hack
rowtools.cancelClick = true;
setTimeout(function() {
rowtools.cancelClick = false;
}, 100);
}
};
this._drawTimeHeader = function() {
this._drawTimeHeader2();
return;
};
this._drawTimeHeader2 = function() {
if (!this.timeHeader) {
//calendar.debug.message("drawTimeHeader: timeHeader not available");
return; // mvc shortInit
}
this._cache.timeHeader = {};
var header = document.createElement("div");
header.style.position = "relative";
this.nav.timeHeader = header;
for (var y = 0; y < this.timeHeader.length; y++) {
var row = this.timeHeader[y];
for (var x = 0; x < row.length; x++) {
this._drawTimeHeaderCell2(x, y);
}
}
var north = this.divNorth;
DayPilot.puc(north);
north.innerHTML = '';
north.appendChild(header);
//north.style.width = (this._cellCount() * this.cellWidth + 5000) + "px";
var gridwidth = this._getGridWidth();
north.style.width = (this._getGridWidth() + 5000) + "px";
var corner = this.divCorner;
if (!this.cssOnly) {
corner.style.backgroundColor = this.cornerBackColor;
}
if (this.cornerHtml) {
corner.innerHTML = this.cornerHtml;
}
else {
corner.innerHTML = '';
}
var gridwidth = this._getGridWidth();
if (gridwidth > 0) {
this.divStretch.style.width = (this._getGridWidth()) + "px";
}
};
this._getGroupName = function(h, cellGroupBy) {
var html = null;
var locale = this._resolved.locale();
var cellGroupBy = cellGroupBy || this.cellGroupBy;
var from = h.start;
var to = h.end;
var locale = this._resolved.locale();
switch (cellGroupBy) {
case 'Hour':
html = (calendar._resolved.timeFormat() === 'Clock12Hours') ? from.toString("h tt", locale) : from.toString("H", locale);
break;
case 'Day':
html = from.toString(locale.datePattern);
break;
case 'Week':
html = resolved.weekStarts() === 1 ? from.weekNumberISO() : from.weekNumber(); // TODO format
break;
case 'Month':
html = from.toString("MMMM yyyy", locale);
break;
case 'Year':
html = from.toString("yyyy");
break;
case 'None':
html = '';
break;
case 'Cell':
if (this.scale === 'Manual' || this.scale === 'CellDuration') { // hard-to-guess cell sizes
var duration = (h.end.ticks - h.start.ticks) / 60000;
html = this._getCellName(from, duration);
}
else {
html = this._getGroupName(h, this.scale);
}
break;
default:
throw 'Invalid cellGroupBy value';
}
return html;
};
this._getCellName = function(start, duration) {
var locale = this._resolved.locale();
var duration = duration || this.cellDuration;
if (duration < 60) // smaller than hour, use minutes
{
return start.toString("mm"); //String.Format("{0:00}", from.Minute);
}
else if (duration < 1440) // smaller than day, use hours
{
//return DayPilot.Date.hours(start.d, calendar._resolved.timeFormat() === 'Clock12Hours');
return calendar._resolved.timeFormat() === 'Clock12Hours' ? start.toString("h tt", locale) : start.toString("H", locale);
}
else if (duration < 10080) // use days
{
return start.toString("d");
}
else if (duration === 10080) {
return resolved.weekStarts() === 1 ? start.weekNumberISO() : start.weekNumber(); // TODO format
}
else
{
return start.toString("MMMM yyyy", locale);
}
};
this._addScaleSize = function(from) {
var scale = this.scale;
switch (scale) {
case "Cell":
throw "Invalid scale: Cell";
case "Manual":
throw "Internal error (addScaleSize in Manual mode)";
case "Minute":
return from.addMinutes(1);
case "CellDuration":
return from.addMinutes(this.cellDuration);
default:
return this._addGroupSize(from, scale);
}
};
this._addGroupSize = function(from, cellGroupBy) {
var to;
var daysHorizontally = this.viewType !== 'Days' ? this.days : 1;
var endDate = this.startDate.addDays(daysHorizontally);
var cellGroupBy = cellGroupBy || this.cellGroupBy;
var cellDuration = 60; // dummy value to make sure it's aligned properly
switch (cellGroupBy) {
case 'Hour':
to = from.addHours(1);
break;
case 'Day':
to = from.addDays(1);
break;
case 'Week':
to = from.addDays(1);
while (to.dayOfWeek() !== resolved.weekStarts()) {
to = to.addDays(1);
}
break;
case 'Month':
to = from.addMonths(1);
to = to.firstDayOfMonth();
//to = from.firstDayOfMonth().addDays(from.daysInMonth());
//var minDiff =
var isInt = (DayPilot.Date.diff(to.d, from.d) / (1000.0 * 60)) % cellDuration === 0;
while (!isInt) {
to = to.addHours(1);
isInt = (DayPilot.Date.diff(to.d, from.d) / (1000.0 * 60)) % cellDuration === 0;
}
break;
case 'Year':
to = from.addYears(1);
to = to.firstDayOfYear();
var isInt = (DayPilot.Date.diff(to.d, from.d) / (1000.0 * 60)) % cellDuration === 0;
while (!isInt) {
to = to.addHours(1);
isInt = (DayPilot.Date.diff(to.d, from.d) / (1000.0 * 60)) % cellDuration === 0;
}
break;
case 'None':
to = endDate;
break;
case 'Cell':
var cell = this._getItlineCellFromTime(from);
if (cell.current)
{
to = cell.current.end;
}
else
{
if (cell.past) {
to = cell.previous.end;
}
else {
to = cell.next.start;
}
/*
var cursor = from;
while (cell === null)
{
cursor = cursor.addMinutes(1);
cell = this._getItlineCellFromTime(cursor);
}
to = cell.start;
*/
}
break;
default:
throw 'Invalid cellGroupBy value';
}
if (to.getTime() > endDate.getTime()) {
to = endDate;
}
return to;
};
this._drawTimeHeaderCell2 = function(x, y) {
var header = this.nav.timeHeader;
var p = this.timeHeader[y][x];
var isGroup = y < this.timeHeader.length - 1;
var top = y * resolved.headerHeight();
var left = p.left;
var width = p.width;
var height = resolved.headerHeight();
var cell = document.createElement("div");
cell.style.position = "absolute";
cell.style.top = top + "px";
cell.style.left = left + "px";
cell.style.width = width + "px";
cell.style.height = height + "px";
if (p.toolTip) {
cell.title = p.toolTip;
}
cell.setAttribute("unselectable", "on");
cell.setAttribute("level", y);
cell.style.KhtmlUserSelect = 'none';
cell.style.MozUserSelect = 'none';
cell.style.webkitUserSelect = 'none';
cell.oncontextmenu = function() { return false; };
cell.cell = {};
cell.cell.start = p.start;
cell.cell.end = p.end;
cell.cell.level = y;
cell.cell.th = p;
cell.onclick = this._onTimeClick;
cell.style.overflow = 'hidden';
if (!calendar.timeHeaderTextWrappingEnabled) {
cell.style.whiteSpace = "nowrap";
}
if (!this.cssOnly) {
var isLast = y === this.timeHeader.length - 1;
cell.style.textAlign = "center";
cell.style.backgroundColor = (typeof cell.backColor === 'undefined') ? calendar.hourNameBackColor : cell.backColor;
cell.style.fontFamily = this.hourFontFamily;
cell.style.fontSize = this.hourFontSize;
cell.style.color = this.headerFontColor;
cell.style.cursor = 'default';
cell.style.border = '0px none';
if (!isLast) {
cell.style.height = (height - 1) + "px";
cell.style.borderBottom = "1px solid " + this.borderColor;
}
cell.style.width = (width - 1) + "px";
cell.style.borderRight = "1px solid " + this.hourNameBorderColor;
cell.style.whiteSpace = 'nowrap';
cell.className = this._prefixCssClass('timeheadergroup');
}
var inner = document.createElement("div");
inner.setAttribute("unselectable", "on");
inner.innerHTML = p.innerHTML;
if (p.backColor) {
inner.style.background = p.backColor;
}
if (this.cssOnly) {
var cl = this._prefixCssClass("_timeheadercol");
var cli = this._prefixCssClass("_timeheadercol_inner");
if (isGroup) {
cl = this._prefixCssClass("_timeheadergroup");
cli = this._prefixCssClass("_timeheadergroup_inner");
}
DayPilot.Util.addClass(cell, cl);
DayPilot.Util.addClass(inner, cli);
}
cell.appendChild(inner);
this._cache.timeHeader[x + "_" + y] = cell;
header.appendChild(cell);
};
this._updateRowHeights = function() {
//calendar.debug.message("updateRowHeights");
for (var i = 0; i < this.rowlist.length; i++) {
var row = this.rowlist[i];
var updated = row.getHeight() + row.marginBottom + row.marginTop;
//if (row.height !== updated || typeof calendar.onBeforeCellRender === "function") {
if (row.height !== updated) {
this._rowsDirty = true;
}
row.height = updated;
}
};
this._updateRowHeaderHeights = function() {
var header = this.divHeader;
if (!header) {
return false;
}
var len = this.rowlist.length;
var columns = this.rowHeaderCols ? this.rowHeaderCols.length : 1;
//var updated = false;
// row headers
var j = 0; // real TR index
//var max = 0;
for (var i = 0; i < len; i++) {
var row = this.rowlist[i];
if (row.hidden) {
continue;
}
var index = this._resHeaderDivBased ? i : j;
if (!header.rows[index]) {
continue;
}
for (var c = 0; c < header.rows[index].cells.length; c++) {
var headerCell = header.rows[index].cells[c];
if (this._resHeaderDivBased) {
headerCell.style.top = row.top + "px";
}
var newHeight = row.height;
if (headerCell && headerCell.firstChild && parseInt(headerCell.firstChild.style.height, 10) !== newHeight) {
headerCell.firstChild.style.height = newHeight + "px";
}
}
j++;
}
if (this._resHeaderDivBased) {
if (calendar.nav.resScrollSpace) {
calendar.nav.resScrollSpace.style.top = calendar._innerHeightTree + "px";
}
}
};
this._drawSeparator = function(index) {
var s = this.separators[index];
// fix
s.location = s.location || s.Location;
s.color = s.color || s.Color;
s.layer = s.layer || s.Layer;
s.width = s.width || s.Width;
s.opacity = s.opacity || s.Opacity;
var time = new DayPilot.Date(s.location);
var color = s.color;
var width = s.width ? s.width : 1;
var above = s.layer ? s.layer === 'AboveEvents' : false;
var opacity = s.opacity ? s.opacity : 100;
// check the start and end dates of the visible area
if (time.getTime() < this.startDate.getTime()) {
return;
}
if (time.getTime() >= this.startDate.addDays(this.days).getTime()) {
return;
}
var pixels = this.getPixels(time);
// check if it's in the hidden area, don't show in that case
if (pixels.cut) {
return;
}
if (pixels.left < 0) {
return;
}
if (pixels.left > this._cellCount() * this.cellWidth) {
return;
}
var line = document.createElement("div");
line.style.width = width + 'px';
line.style.height = calendar._innerHeightTree + 'px';
line.style.position = 'absolute';
line.style.left = (pixels.left - 1) + 'px';
line.style.top = '0px';
line.style.backgroundColor = color;
line.style.opacity = opacity / 100;
line.style.filter = "alpha(opacity=" + opacity + ")";
if (above) {
this.divSeparatorsAbove.appendChild(line);
}
else {
this.divSeparators.appendChild(line);
}
this.elements.separators.push(line);
};
this._onMaindDblClick = function(ev) {
if (calendar.timeRangeDoubleClickHandling === 'Disabled') {
return false;
}
if (DayPilotScheduler.timeRangeTimeout) {
clearTimeout(DayPilotScheduler.timeRangeTimeout);
DayPilotScheduler.timeRangeTimeout = null;
}
var range = {};
// make sure that coordinates are set
if (!calendar.coords) {
var ref = calendar._maind;
calendar.coords = DayPilot.mo3(ref, ev);
}
ev = ev || window.event;
ev.stopPropagation && ev.stopPropagation();
ev.cancelBubble = true;
// only process left and right button outside of selection
if (calendar._isWithinRange(calendar.coords)) {
var sel = calendar._getSelection(DayPilotScheduler.rangeHold);
calendar._timeRangeDoubleClickDispatch(sel.start, sel.end, sel.resource);
}
else {
DayPilotScheduler.range = calendar._rangeFromCoords();
if (DayPilotScheduler.range) {
DayPilotScheduler.rangeCalendar = calendar;
var sel = calendar._getSelection(DayPilotScheduler.range);
calendar._timeRangeDoubleClickDispatch(sel.start, sel.end, sel.resource);
}
}
DayPilotScheduler.rangeHold = DayPilotScheduler.range;
DayPilotScheduler.range = null;
};
/*
this._clearDblClickTimeout = function() {
calendar.dblclick = null;
};
*/
// handles:
// - TimeRangeSelected
this._onMaindMouseDown = function(ev) {
if (touch.start || touch.active) {
return;
}
if (DayPilotScheduler.timeRangeTimeout && false) {
clearTimeout(DayPilotScheduler.timeRangeTimeout);
DayPilotScheduler.timeRangeTimeout = null;
}
calendar._crosshairHide();
calendar._stopScroll();
// make sure that coordinates are set
if (!calendar.coords) {
var ref = calendar._maind;
calendar.coords = DayPilot.mo3(ref, ev);
}
if (DayPilotScheduler.rectangleSelect) {
return false;
}
ev = ev || window.event;
var button = DayPilot.Util.mouseButton(ev);
if (button.middle || (button.right && calendar._isWithinRange(calendar.coords))) {
return false;
}
if (calendar.timeRangeSelectedHandling === 'Disabled') {
return false;
}
var ctrl = ev.ctrlKey || ev.metaKey;
if (calendar.allowMultiRange && !ctrl) {
mr.clear();
}
var shift = ev.shiftKey;
if (calendar.multiSelectRectangle !== "Disabled" && shift) {
var rect = {};
rect.start = calendar.coords;
rect.calendar = calendar;
DayPilotScheduler.rectangleSelect = rect;
return false;
}
var i = calendar._getRow(calendar.coords.y).i;
var row = calendar.rowlist[i];
if (row.isNewRow) {
return false;
}
DayPilotScheduler.range = calendar._rangeFromCoords();
DayPilotScheduler.range.ctrl = ctrl;
DayPilotScheduler.rangeCalendar = calendar;
return false; // prevent FF3 bug (?), dragging is otherwise activated and DayPilot.mo2 gives incorrect results
};
// creates a single cell range selection at the current position (calendar.coords)
this._rangeFromCoords = function() {
var range = {};
var cx = this._getItlineCellFromPixels(calendar.coords.x).x;
range.start = {
y: calendar._getRow(calendar.coords.y).i,
x: cx
};
range.end = {
x: cx
};
if (this._isRowDisabled(calendar._getRow(calendar.coords.y).i)) {
return null;
}
//return false;
range.calendar = calendar;
//DayPilotScheduler.range = range;
calendar._drawRange(range);
return range;
};
this._doEventResizing = function() {
calendar._updateResizingShadow();
var shadow = DayPilotScheduler.resizingShadow;
var ev = DayPilotScheduler.resizing;
(function() {
var last = calendar._lastEventResizing;
// don't fire the event if there is no change
if (last && last.start.getTime() === shadow.start.getTime() && last.end.getTime() === shadow.end.getTime()) {
return;
}
var args = {};
args.start = shadow.start;
args.end = calendar._adjustEndOut(shadow.end);
args.duration = new DayPilot.Duration(args.start, args.end);
args.e = ev.event;
args.left = {};
args.left.html = args.start.toString(calendar.eventResizingStartEndFormat);
args.left.enabled = calendar.eventResizingStartEndEnabled;
args.right = {};
args.right.html = args.end.toString(calendar.eventResizingStartEndFormat);
args.right.enabled = calendar.eventResizingStartEndEnabled;
calendar._lastEventResizing = args;
if (typeof calendar.onEventResizing === 'function') {
calendar.onEventResizing(args);
}
calendar._showShadowHover(DayPilotScheduler.resizingShadow, args);
})();
};
this._onMaindMouseUp = function(ev) {
if (DayPilotScheduler.rectangleSelect) {
var ev = ev || window.event;
ev.cancelBubble = true;
ev.preventDefault && ev.preventDefault();
DayPilotScheduler.gMouseUp(ev);
return false; // trying to prevent onmaindclick
}
};
// handles:
// - EventMove (including external)
// - EventResize
// - TimeRangeSelected
//
// saves calendar.coords
this._onMaindMouseMove = function(ev) {
if (touch.active) {
return;
}
DayPilotScheduler.activeCalendar = calendar; // required for moving
ev = ev || window.event;
var mousePos = DayPilot.mc(ev);
calendar.coords = DayPilot.mo3(calendar._maind, ev);
//ev = ev || window.event;
ev.insideMainD = true;
if (window.event) {
window.event.srcElement.inside = true;
}
if (moving.start) {
if (moving.originalMouse.x !== mousePos.x || moving.originalMouse.y !== mousePos.y) {
DayPilot.Util.copyProps(moving, DayPilotScheduler);
document.body.style.cursor = 'move';
moving = {};
}
}
if (DayPilotScheduler.resizing && DayPilotScheduler.resizing.event.calendar === calendar) {
if (!DayPilotScheduler.resizingShadow) {
DayPilotScheduler.resizingShadow = calendar._createShadow(DayPilotScheduler.resizing, calendar.shadow);
}
var _step = DayPilotScheduler.resizing.event.calendar.cellWidth;
var originalWidth = DayPilotScheduler.resizing.event.part.width;
var originalLeft = DayPilotScheduler.resizing.event.part.left;
var _startOffset = 0;
var delta = (mousePos.x - DayPilotScheduler.originalMouse.x);
var newLeft, newWidth;
if (DayPilotScheduler.resizing.dpBorder === 'right') {
newLeft = originalLeft;
if (calendar.snapToGrid) {
//newWidth = Math.ceil(((originalWidth + originalLeft + delta)) / _step) * _step - originalLeft;
var itc = calendar._getItlineCellFromPixels(originalWidth + originalLeft + delta).cell;
var newRight = itc.left + itc.width;
newWidth = newRight - originalLeft;
if (newWidth < _step) {
newWidth = _step;
}
}
else {
newWidth = originalWidth + delta;
}
var max = calendar._getGridWidth();
if (originalLeft + newWidth > max) {
newWidth = max - originalLeft;
}
DayPilotScheduler.resizingShadow.style.width = (newWidth) + 'px';
}
else if (DayPilotScheduler.resizing.dpBorder === 'left') {
if (calendar.snapToGrid) {
if (delta >= originalWidth) {
delta = originalWidth;
}
newLeft = Math.floor(((originalLeft + delta) + 0) / _step) * _step;
if (newLeft < _startOffset) {
newLeft = _startOffset;
}
}
else {
newLeft = originalLeft + delta;
}
newWidth = originalWidth - (newLeft - originalLeft);
var right = originalLeft + originalWidth;
var min = _step;
if (!calendar.snapToGrid) {
min = 1;
}
else if (calendar.useEventBoxes === "Never") {
if (originalWidth < _step) {
min = originalWidth;
}
else {
min = 1;
}
}
if (newWidth < min) {
newWidth = min;
newLeft = right - newWidth;
}
DayPilotScheduler.resizingShadow.style.left = newLeft + 'px';
DayPilotScheduler.resizingShadow.style.width = (newWidth) + 'px';
}
(function checkOverlap() {
var ev = DayPilotScheduler.resizing.event;
var row = calendar.rowlist[ev.part.dayIndex];
var shadow = DayPilotScheduler.resizingShadow;
var left = newLeft;
var width = newWidth;
calendar._overlappingShadow(DayPilotScheduler.resizingShadow, row, left, width, ev.data);
})();
calendar._doEventResizing();
}
else if (DayPilotScheduler.moving && (DayPilotScheduler.moving.event.calendar === calendar || DayPilotScheduler.moving.event.calendar.dragOutAllowed)) {
if (DayPilotScheduler.movingShadow && DayPilotScheduler.movingShadow.calendar !== calendar) {
DayPilotScheduler.movingShadow.calendar = null;
DayPilot.de(DayPilotScheduler.movingShadow);
DayPilotScheduler.movingShadow = null;
}
if (!DayPilotScheduler.movingShadow) {
var mv = DayPilotScheduler.moving;
DayPilotScheduler.movingShadow = calendar._createShadow(mv, calendar.shadow);
}
calendar._expandParent();
DayPilotScheduler.moving.target = calendar; //might not be necessary, the target is in DayPilotScheduler.activeCalendar
calendar._moveShadow();
}
else if (DayPilotScheduler.range && DayPilotScheduler.range.calendar === calendar) {
var range = DayPilotScheduler.range;
range.end = {
//x: Math.floor(calendar.coords.x / calendar.cellWidth)
x: calendar._getItlineCellFromPixels(calendar.coords.x).x
};
calendar._drawRange(range);
}
else if (linking.source) {
var src = linking.source;
//linktools.clear();
//linktools.drawLinkXy(src.coords, calendar.coords, src.type + "ToStart");
linktools.drawShadow(src.coords, calendar.coords);
}
else if (DayPilotScheduler.rectangleSelect) {
rectangle.draw();
}
else if (calendar.crosshairType !== 'Disabled') { // crosshair
calendar._updateCrosshairPosition();
}
calendar._cellhover();
var insideEvent = ev.insideEvent;
if (window.event) {
insideEvent = window.event.srcElement.insideEvent;
}
// cell bubble
if (calendar.cellBubble && calendar.coords && calendar.rowlist && calendar.rowlist.length > 0 && !insideEvent) {
var x = Math.floor(calendar.coords.x / calendar.cellWidth);
var y = calendar._getRow(calendar.coords.y).i;
if (0 <= y && y < calendar.rowlist.length && 0 <= x && x < calendar.itline.length) {
var cell = {};
cell.calendar = calendar;
cell.start = calendar.itline[x].start;
cell.end = calendar.itline[x].end;
cell.resource = calendar.rowlist[y].id;
cell.toJSON = function() {
var json = {};
json.start = this.start;
json.end = this.end;
json.resource = this.resource;
return json;
};
calendar.cellBubble.showCell(cell);
}
}
if (DayPilotScheduler.drag) {
calendar._crosshairHide();
if (DayPilotScheduler.gShadow) {
document.body.removeChild(DayPilotScheduler.gShadow);
}
DayPilotScheduler.gShadow = null;
if (!DayPilotScheduler.movingShadow && calendar.coords && calendar.rowlist.length > 0) {
//if (DayPilotScheduler.movingShadow) { // can be null if the location is forbidden (first two rows in IE)
if (!DayPilotScheduler.moving) { // can be null if the location is forbidden (first two rows in IE)
DayPilotScheduler.moving = {};
var event = DayPilotScheduler.drag.event;
if (!event) {
//var now = new DayPilot.Date().getDatePart();
var now = calendar.itline[0].start;
//calendar.debug.message("external start:" + now);
var ev = { 'id': DayPilotScheduler.drag.id, 'start': now, 'end': now.addSeconds(DayPilotScheduler.drag.duration), 'text': DayPilotScheduler.drag.text };
event = new DayPilot.Event(ev);
event.calendar = calendar;
event.part.external = true;
}
DayPilotScheduler.moving.event = event;
}
//DayPilotScheduler.movingShadow = calendar.createShadow(DayPilotScheduler.drag.duration, calendar.shadow, DayPilotScheduler.drag.shadowType);
//DayPilotScheduler.movingShadow = calendar.createShadow(calendar.shadow, DayPilotScheduler.drag.shadowType);
DayPilotScheduler.movingShadow = calendar._createShadow(DayPilotScheduler.moving, DayPilotScheduler.drag.shadowType);
}
ev.cancelBubble = true;
}
// autoscroll
if (calendar.autoScroll === "Always" ||
(calendar.autoScroll === "Drag" && (DayPilotScheduler.moving || DayPilotScheduler.resizing || DayPilotScheduler.range))
) {
var scrollDiv = calendar.nav.scroll;
var coords = { x: calendar.coords.x, y: calendar.coords.y };
coords.x -= scrollDiv.scrollLeft;
coords.y -= scrollDiv.scrollTop;
var width = scrollDiv.clientWidth;
var height = scrollDiv.clientHeight;
var border = 20;
var left = coords.x < border;
var right = width - coords.x < border;
var top = coords.y < border;
var bottom = height - coords.y < border;
var x = 0;
var y = 0;
if (left) {
x = -5;
}
if (right) {
x = 5;
}
if (top) {
y = -5;
}
if (bottom) {
y = 5;
}
if (x || y) {
calendar._startScroll(x, y);
}
else {
calendar._stopScroll();
}
}
// don't cancel the event bubbling here, it will hurt position detection used in DayPilot ContextMenu and DayPilot Bubble
//ev.cancelBubble = true;
};
this._rectangle = {};
var rectangle = this._rectangle;
rectangle.start = function() {
var rect = {};
rect.start = calendar.coords;
rect.calendar = calendar;
DayPilotScheduler.rectangleSelect = rect;
};
rectangle.draw = function() {
var rect = DayPilotScheduler.rectangleSelect;
var start = DayPilotScheduler.rectangleSelect.start;
var end = calendar.coords;
rectangle.clear();
var original = {
"x": rect.x,
"y": rect.y,
"width": rect.width,
"height": rect.height
};
var left, top, width, height;
var startX, startY, endX, endY;
(function rectifyStartEnd() {
startX = Math.min(start.x, end.x);
endX = Math.max(start.x, end.x);
if (calendar.multiSelectRectangle === "Free") {
startY = Math.min(start.y, end.y);
endY = Math.max(start.y, end.y);
}
else if (calendar.multiSelectRectangle === "Row") {
startY = start.y; // the original row, end.y not used here
endY = start.y;
}
})();
if (calendar.multiSelectRectangle === "Free") {
left = startX;
top = startY;
width = endX - startX;
height = endY - startY;
}
else if (calendar.multiSelectRectangle === "Row") {
var y = calendar._getRow(startY).i;
var row = calendar.rowlist[y];
top = row.top;
height = row.height;
var startCell = calendar._getItlineCellFromPixels(startX).cell;
left = startCell.left;
var endCell = calendar._getItlineCellFromPixels(endX).cell;
width = endCell.left + endCell.width - left;
}
else {
throw "Invalid DayPilot.Scheduler.multiSelectRectangle value: " + calendar.multiSelectRectangle;
}
var div = DayPilot.Util.div(calendar.divRectangle, left, top, width, height);
div.style.boxSizing = "border-box";
div.style.backgroundColor = "#0000ff";
div.style.border = "1px solid #000033";
div.style.opacity = 0.4;
rect.x = left;
rect.y = top;
rect.width = width;
rect.height = height;
if (rect.x !== original.x || rect.y !== original.y || rect.width !== original.width || rect.height !== original.height) { // change detected
if (typeof calendar.onRectangleEventSelecting === "function") {
var args = {};
args.events = viewport.eventsInRectangle(rect.x, rect.y, rect.width, rect.height).map(function(item) {return item.event; });
calendar.onRectangleEventSelecting(args);
}
}
};
rectangle.clear = function() {
// clear
calendar.divRectangle.innerHTML = '';
calendar.elements.rectangle = [];
};
this._getCurrentCell = function() {
var x, y;
if (calendar.coords && calendar.rowlist && calendar.rowlist.length > 0 && calendar.itline && calendar.itline.length > 0) {
x = calendar._getItlineCellFromPixels(calendar.coords.x).x;
y = calendar._getRow(calendar.coords.y).i;
if (y >= calendar.rowlist.length) {
return;
}
}
else {
return null;
}
var cells = calendar.cells.findXy(x, y);
return cells[0];
};
this._cellhover = function() {
var cell = this._getCurrentCell();
if (this.hover.cell) {
if (this.hover.cell.x === cell.x && this.hover.cell.y === cell.y) {
return;
}
this._cellhoverout();
}
this.hover.cell = cell;
if (typeof this.onCellMouseOver === 'function') {
var args = {};
args.cell = cell;
this.onCellMouseOver(args);
}
};
this._cellhoverout = function() {
if (!this.hover.cell) {
return;
}
if (typeof this.onCellMouseOut === 'function') {
var args = {};
args.cell = this.hover.cell;
this.onCellMouseOut(args);
}
this.hover.cell = null;
};
this.hover = {};
this._updateCrosshairPosition = function() {
var cell = this._getCurrentCell();
if (this.hover.cell) {
if (this.hover.cell.x === cell.x && this.hover.cell.y === cell.y) {
return;
}
}
this._crosshair();
};
this._crosshairHide = function() {
this.divCrosshair.innerHTML = '';
this._crosshairVertical = null;
this._crosshairHorizontal = null;
if (this.crosshairTop && this.crosshairTop.parentNode) {
this.crosshairTop.parentNode.removeChild(this.crosshairTop);
this.crosshairTop = null;
}
if (this.crosshairLeft) {
for (var i = 0; i < this.crosshairLeft.length; i++) {
var ch = this.crosshairLeft[i];
if (ch.parentNode) {
ch.parentNode.removeChild(ch);
}
}
this.crosshairLeft = null;
}
this._crosshairLastX = -1;
this._crosshairLastY = -1;
};
this._crosshair = function() {
var x, y;
if (calendar.coords && calendar.rowlist && calendar.rowlist.length > 0) {
x = calendar._getItlineCellFromPixels(calendar.coords.x).x;
y = calendar._getRow(calendar.coords.y).i;
if (y >= calendar.rowlist.length) {
return;
}
}
else {
return;
}
var type = this.crosshairType;
var row = calendar.rowlist[y];
if (type === 'Full') {
// vertical
var itc = this.itline[x];
var left = itc.left;
var line = this._crosshairVertical;
if (!line) {
var line = document.createElement("div");
line.style.height = calendar._innerHeightTree + 'px';
line.style.position = 'absolute';
line.style.top = '0px';
line.style.backgroundColor = this.crosshairColor;
line.style.opacity = this.crosshairOpacity / 100;
line.style.filter = "alpha(opacity=" + this.crosshairOpacity + ")";
this._crosshairVertical = line;
this.divCrosshair.appendChild(line);
}
line.style.left = left + 'px';
line.style.width = itc.width + 'px';
// horizontal
var top = row.top;
var height = row.height;
//var width = this._cellCount() * this.cellWidth;
var width = this._getGridWidth();
var line = this._crosshairHorizontal;
if (!line) {
var line = document.createElement("div");
line.style.width = width + 'px';
line.style.height = height + 'px';
line.style.position = 'absolute';
line.style.top = top + 'px';
line.style.left = '0px';
line.style.backgroundColor = this.crosshairColor;
line.style.opacity = this.crosshairOpacity / 100;
line.style.filter = "alpha(opacity=" + this.crosshairOpacity + ")";
this._crosshairHorizontal = line;
this.divCrosshair.appendChild(line);
}
line.style.top = top + 'px';
line.style.height = height + 'px';
}
var thc = this._getTimeHeaderCell(this.coords.x);
if (thc && this._crosshairLastX !== thc.x) {
if (this.crosshairTop && this.crosshairTop.parentNode) {
this.crosshairTop.parentNode.removeChild(this.crosshairTop);
this.crosshairTop = null;
}
// top
var line = document.createElement("div");
line.style.width = thc.cell.width + "px";
line.style.height = resolved.headerHeight() + "px";
line.style.left = '0px';
line.style.top = '0px';
line.style.position = 'absolute';
line.style.backgroundColor = this.crosshairColor;
line.style.opacity = this.crosshairOpacity / 100;
line.style.filter = "alpha(opacity=" + this.crosshairOpacity + ")";
this.crosshairTop = line;
var north = this.divNorth;
var lastHeader = this.timeHeader ? this.timeHeader.length - 1 : 1;
if (this.nav.timeHeader) {
this._cache.timeHeader[thc.x + "_" + lastHeader].appendChild(line);
}
else {
if (north.firstChild.rows[lastHeader].cells[x]) {
north.firstChild.rows[lastHeader].cells[x].firstChild.appendChild(line);
}
}
}
if (this._crosshairLastY !== y) {
if (this.crosshairLeft) {
for (var i = 0; i < this.crosshairLeft.length; i++) {
var ch = this.crosshairLeft[i];
if (ch.parentNode) {
ch.parentNode.removeChild(ch);
}
}
this.crosshairLeft = null;
}
// left
var columns = this.rowHeaderCols ? this.rowHeaderCols.length : 1;
this.crosshairLeft = [];
if (this.divHeader.rows[y]) {
for (var i = 0; i < this.divHeader.rows[y].cells.length; i++) {
//var width = this.rowHeaderCols ? this.rowHeaderCols[i] : this.rowHeaderWidth;
var width = calendar._getOuterRowHeaderWidth();
// disabled because of Chrome performance problems (.clientWidth is expensive)
//var width = this.divHeader.rows[row.i].cells[i].clientWidth;
var line = document.createElement("div");
line.style.width = width + "px";
line.style.height = row.height + "px";
line.style.left = '0px';
line.style.top = '0px';
line.style.position = 'absolute';
line.style.backgroundColor = this.crosshairColor;
line.style.opacity = this.crosshairOpacity / 100;
line.style.filter = "alpha(opacity=" + this.crosshairOpacity + ")";
this.crosshairLeft.push(line);
this.divHeader.rows[y].cells[i].firstChild.appendChild(line);
}
}
}
if (thc) {
this._crosshairLastX = thc.x;
}
this._crosshairLastY = y;
};
this._getTimeHeaderCell = function(pixels) {
//var last = this.timeHeader[this.timeHeader.length - 1];
var last = DayPilot.list(this.timeHeader).last();
if (!last) {
return null;
}
for (var i = 0; i < last.length; i++) {
var cell = last[i];
if (pixels >= cell.left && pixels < cell.left + cell.width) {
var result = {};
result.cell = cell;
result.x = i;
return result;
}
}
return null;
};
this._onMaindRightClick = function(ev) {
ev = ev || window.event;
if (calendar.timeRangeSelectedHandling === 'Disabled') {
return false;
}
if (!calendar._isWithinRange(calendar.coords)) {
calendar._onMaindClick(ev);
}
if (calendar.contextMenuSelection) {
var selection = null;
if (calendar._isWithinRange(calendar.coords)) {
selection = calendar._getSelection(DayPilotScheduler.rangeHold);
}
else {
selection = calendar._getSelection();
}
selection.end = calendar._adjustEndOut(selection.end);
calendar.contextMenuSelection.show(selection);
}
ev.cancelBubble = true;
if (!calendar.allowDefaultContextMenu) {
return false;
}
};
this._isWithinRange = function(coords) {
var range = DayPilotScheduler.rangeHold;
if (!range || !range.start || !range.end) {
return false;
}
var row = this._getRowByIndex(range.start.y);
var leftToRight = range.start.x < range.end.x;
var rangeLeft = (leftToRight ? range.start.x : range.end.x) * this.cellWidth;
var rangeRight = (leftToRight ? range.end.x : range.start.x) * this.cellWidth + this.cellWidth;
var rangeTop = row.top;
var rangeBottom = row.bottom;
if (coords.x >= rangeLeft && coords.x <= rangeRight && coords.y >= rangeTop && coords.y <= rangeBottom) {
return true;
}
return false;
};
this._drawRange = function(range, justDraw) {
var range = range || DayPilotScheduler.range;
if (!range) {
return;
}
function draw(range) {
var startX = range.end.x > range.start.x ? range.start.x : range.end.x;
var endX = (range.end.x > range.start.x ? range.end.x : range.start.x);
var y = range.start.y;
var row = calendar.rowlist[y];
var start = calendar.itline[startX];
var end = calendar.itline[endX];
var left = start.left;
var right = end.left + end.width;
var width = right - left;
var cell = calendar.elements.range2;
if (!cell) {
cell = document.createElement("div");
cell.style.position = 'absolute';
cell.setAttribute("unselectable", "on");
if (calendar.cssOnly) {
cell.className = calendar._prefixCssClass("_shadow");
var inner = document.createElement("div");
inner.className = calendar._prefixCssClass("_shadow_inner");
cell.appendChild(inner);
}
else {
cell.style.backgroundColor = calendar.cellSelectColor;
}
calendar.divRange.appendChild(cell);
}
cell.style.left = (start.left) + "px";
cell.style.top = calendar.rowlist[y].top + "px";
cell.style.width = width + "px";
cell.style.height = (calendar.rowlist[y].height - 1) + "px";
calendar.elements.range2 = cell;
(function checkOverlap() {
var row = calendar.rowlist[y];
var shadow = cell;
var left = start.left;
calendar._overlappingShadow(cell, row, left, width, null);
})();
return cell;
}
(function () {
var startX = range.end.x > range.start.x ? range.start.x : range.end.x;
var endX = (range.end.x > range.start.x ? range.end.x : range.start.x);
var y = range.start.y;
var row = calendar.rowlist[y];
var start = calendar.itline[startX];
var end = calendar.itline[endX];
var last = calendar._lastRange;
var startDateTime = start.start.addTime(row.data.offset);
var endDateTime = end.end.addTime(row.data.offset);
// don't fire the event if there is no change
if (last && last.start.getTime() === startDateTime.getTime() && last.end.getTime() === endDateTime.getTime() && last.resource === calendar.rowlist[y].id) {
return;
}
var original = {
"start": startDateTime,
"end": calendar._adjustEndOut(endDateTime)
};
var args = {};
args.start = original.start;
args.end = original.end;
args.duration = new DayPilot.Duration(original.start, original.end);
args.resource = calendar.rowlist[y].id;
args.allowed = true;
args.left = {};
args.left.html = args.start.toString(calendar.timeRangeSelectingStartEndFormat);
args.left.enabled = calendar.timeRangeSelectingStartEndEnabled;
args.right = {};
args.right.html = args.end.toString(calendar.timeRangeSelectingStartEndFormat);
args.right.enabled = calendar.timeRangeSelectingStartEndEnabled;
calendar._lastRange = args;
if (typeof calendar.onTimeRangeSelecting === 'function' && !justDraw) {
calendar.onTimeRangeSelecting(args);
}
var copy = calendar._copyRange(range);
calendar._updateRange(copy, args.start, args.end);
var cell = draw(copy);
calendar._disabledShadow(cell, args);
range._customized = copy;
range.disabled = !args.allowed;
calendar._showShadowHover(cell, args);
args.start = original.start;
args.end = original.end;
})();
};
this._copyRange = function(range) {
return {
"start": {
"x": range.start.x,
"y": range.start.y
},
"end": {
"x": range.end.x
},
"disabled": range.disabled
}
};
this.range = {};
this.range.all = function() {
return mr.get();
};
this._multirange = {};
var mr = this._multirange;
this._multirange.list = [];
this._multirange.clear = function() {
DayPilot.de(DayPilot.list(mr.list).map(function(item) { return item.div; }));
mr.list = [];
};
this._multirange.add = function(range) {
range.div = calendar.elements.range2;
calendar.elements.range2 = null;
calendar._clearShadowHover(); // ?
mr.list.push(range);
};
this._multirange.get = function() {
return DayPilot.list(mr.list).map(function(item) { return calendar._getSelection(item);});
};
this._multirange.dispatch = function() {
if (!calendar.allowMultiRange) {
return;
}
if (DayPilotScheduler.range) { // in progress
return;
}
var last = DayPilot.list(mr.list).last();
calendar._timeRangeSelectedDispatchFromRange(last);
/*
var last = calendar._getSelection(DayPilot.list(mr.list).last());
if (!last) {
return;
}
calendar._timeRangeSelectedDispatch(last.start, last.end, last.resource);
*/
};
this._onMaindClick = function(ev) {
if (calendar.timeRangeSelectedHandling === 'Disabled') {
return false;
}
// fired on Android/Chrome on DOM change under finger
if (touch.active || touch.start) {
return;
}
ev = ev || window.event;
var button = DayPilot.Util.mouseButton(ev);
if (DayPilotScheduler.range) { // time range selecting already active
return;
}
if (DayPilotScheduler.rectangleSelect) {
return;
}
if (DayPilotScheduler.rangeHold && calendar._isWithinRange(calendar.coords) && (button.right || button.middle)) {
return;
}
if (calendar._isRowDisabled(calendar._getRow(calendar.coords.y).i)) {
return;
}
var range = {};
var cx = calendar._getItlineCellFromPixels(calendar.coords.x).x;
range.start = {
y: calendar._getRow(calendar.coords.y).i,
x: cx
};
range.end = {
x: cx
};
calendar._drawRange(range);
calendar._timeRangeSelectedDispatchFromRange(range);
/*
var sel = calendar._getSelection(range);
calendar._timeRangeSelectedDispatch(sel.start, sel.end, sel.resource);
*/
// TEST the default behavior is now Hold
DayPilotScheduler.rangeHold = range;
};
this.timeouts = {};
this.timeouts.drawEvents = null;
this.timeouts.drawCells = null;
this.timeouts.click = null;
this._onScroll = function(ev) {
calendar._clearCachedValues();
if (calendar.dynamicLoading) {
calendar._onScrollDynamic();
return;
}
var divScroll = calendar.nav.scroll;
calendar._scrollPos = divScroll.scrollLeft;
calendar._scrollTop = divScroll.scrollTop;
calendar._scrollWidth = divScroll.clientWidth;
calendar.divTimeScroll.scrollLeft = calendar._scrollPos;
calendar.divResScroll.scrollTop = calendar._scrollTop;
calendar._loadingStart();
if (calendar.timeouts.drawEvents) {
clearTimeout(calendar.timeouts.drawEvents);
calendar.timeouts.drawEvents = null;
}
if (calendar.scrollDelayEvents > 0) {
calendar.timeouts.drawEvents = setTimeout(calendar._delayedDrawEvents(), calendar.scrollDelayEvents);
}
else {
var f = calendar._delayedDrawEvents();
f();
}
if (calendar.timeouts.drawCells) {
clearTimeout(calendar.timeouts.drawCells);
calendar.timeouts.drawCells = null;
}
if (calendar.scrollDelayCells > 0) {
calendar.timeouts.drawCells = setTimeout(calendar._delayedDrawCells(), calendar.scrollDelayCells);
}
else {
var f = calendar._delayedDrawCells();
f();
}
if (calendar.timeouts.updateFloats) {
clearTimeout(calendar.timeouts.updateFloats);
calendar.timeouts.updateFloats = null;
}
if (calendar.scrollDelayFloats > 0) {
calendar.timeouts.updateFloats = setTimeout(function() { calendar._updateFloats(); }, calendar.scrollDelayFloats);
}
else {
calendar._updateFloats();
}
calendar.onScrollCalled = true;
};
/*
this._delayedRefresh = function() {
return function() {
calendar._saveState();
calendar._drawCells();
calendar.refreshTimeout = window.setTimeout(calendar._delayedDrawEvents(), 200); // chain update
};
};
*/
this._delayedDrawCells = function() {
return function() {
calendar._saveState();
calendar._drawCells();
calendar._loadingStop();
};
};
this._delayedDrawEvents = function() {
var batch = true; // turns on batch rendering
var deleteOld = calendar.dynamicEventRenderingCacheSweeping; // deletes old events (outside of the visible area)
var keepOld = calendar.dynamicEventRenderingCacheSize; // how many old events should be kept visible (cached)
return function() {
if (calendar._hiddenEvents()) {
calendar._loadingStart();
window.setTimeout(function() {
if (deleteOld) calendar._deleteOldEvents(keepOld);
window.setTimeout(function() { calendar._drawEvents(batch); }, 50);
}, 50);
}
else {
calendar._findEventsInViewPort();
}
};
};
this._clearCachedValues = function() {
this._cache.eventHeight = null;
this._cache.drawArea = null;
};
this.show = function() {
this.visible = true;
calendar.nav.top.style.display = '';
this._show();
this._resize();
calendar._onScroll();
};
this.hide = function() {
this.visible = false;
calendar.nav.top.style.display = 'none';
};
this._onScrollDynamic = function() {
var divScroll = calendar.nav.scroll;
calendar._scrollPos = divScroll.scrollLeft;
calendar._scrollTop = divScroll.scrollTop;
calendar._scrollWidth = divScroll.clientWidth;
calendar.divTimeScroll.scrollLeft = calendar._scrollPos;
calendar.divResScroll.scrollTop = calendar._scrollTop;
if (calendar.refreshTimeout) {
window.clearTimeout(calendar.refreshTimeout);
}
var delay = calendar.scrollDelayDynamic;
calendar.refreshTimeout = window.setTimeout(calendar._delayedRefreshDynamic(divScroll.scrollLeft, divScroll.scrollTop), delay);
calendar._updateFloats();
};
/*
this._findEventInList = function(e) {
var eid = e.id;
var estart = e.start.toString();
for (var j = 0; j < this.events.list.length; j++) {
var ex = this.events.list[j];
var exid = ex.id;
var exstart = ex.start.toString();
if (exid === eid && exstart === estart && ex.resource === e.resource) {
var result = {};
result.ex = ex;
result.index = j;
result.modified = !calendar._equalObjectFlat(e, ex);
return result;
}
}
return null;
};
*/
this._findEventInList = function(e) {
var eid = e.id;
var estart = new DayPilot.Date(e.start).toString();
for (var j = 0; j < this.events.list.length; j++) {
var ex = this.events.list[j];
var exid = ex.id;
if (exid === eid) {
// it's a recurring event (occurrence)
if (DayPilot.Util.isNullOrUndefined(eid) && !DayPilot.Util.isNullOrUndefined(e.recurrentMasterId)) {
var exstart = new DayPilot.Date(ex.start).toString();
if (ex.recurrentMasterId !== e.recurrentMasterId || estart !== exstart) {
continue;
}
}
var result = {};
result.ex = ex;
result.index = j;
result.modified = !calendar._equalObjectFlat(e, ex);
return result;
}
}
return null;
};
this._equalObjectFlat = function(first, second) {
for (var name in first) {
if (typeof first[name] === 'object') {
continue;
}
if (first[name] !== second[name]) {
return false;
}
}
for (var name in second) {
if (typeof second[name] === 'object') {
continue;
}
if (first[name] !== second[name]) {
return false;
}
}
return true;
};
this._loadEventsDynamic = function(supplied, finished) {
var updatedRows = [];
for (var i = 0; i < supplied.length; i++) {
var e = supplied[i];
var found = calendar._findEventInList(e);
var update = found && found.modified;
var add = !found;
if (update) {
// update it directly in list
this.events.list[found.index] = e;
// remove it from rows
var rows = calendar.events._removeFromRows(found.ex);
updatedRows = updatedRows.concat(rows);
}
else if (add) {
this.events.list.push(e);
}
if (update || add) {
updatedRows = updatedRows.concat(calendar.events._addToRows(e));
}
}
calendar._loadRows(updatedRows);
calendar._updateRowHeights();
calendar._prepareRowTops();
calendar._updateHeight();
var useRowBasedUpdate = false;
if (useRowBasedUpdate) { // doesn't draw events that were swept
calendar._updateRowsNoLoad(updatedRows, false, finished);
}
else {
calendar._deleteCells();
calendar._updateRowHeaderHeights();
calendar._drawCells();
calendar._updateEventTops();
var f = calendar._delayedDrawEvents();
f();
}
};
this._delayedRefreshDynamic = function(scrollX, scrollY) {
if (!calendar._serverBased()) {
return function() {
if (typeof calendar.onScroll === 'function') {
// make sure the background is rendered immediately
// TODO test
//calendar._drawCells();
var update = function(events) {
//var updatedRows = calendar._loadEvents(events, true);
var finished = function() {
if (calendar._api2()) {
if (typeof calendar.onAfterRender === 'function') {
var args = {};
args.isCallBack = false;
args.isScroll = true;
args.data = null;
calendar.onAfterRender(args);
}
}
};
calendar._loadEventsDynamic(events, finished);
};
var area = calendar._getArea(scrollX, scrollY);
var range = calendar._getAreaRange(area);
var res = calendar._getAreaResources(area);
var args = {};
args.viewport = {};
args.viewport.start = range.start;
args.viewport.end = range.end;
args.viewport.resources = res;
args.async = false;
args.events = [];
args.loaded = function() {
if (this.async) {
update(this.events);
}
};
calendar.onScroll(args);
if (!args.async) {
update(args.events);
}
}
};
}
else {
return function() {
calendar.scrollX = scrollX;
calendar.scrollY = scrollY;
calendar._callBack2('Scroll');
};
}
};
this._drawCellsFull = function() {
var area = this._getDrawArea();
var cellLeft = area.xStart;
var cellWidth = area.xEnd - area.xStart;
var cellTop = area.yStart;
var cellHeight = area.yEnd - area.yStart;
// initialize for client-side processing
if (!this.cellProperties) {
this.cellProperties = {};
}
for (var i = 0; i <= cellWidth; i++) {
var x = cellLeft + i;
for (var j = 0; j < cellHeight; j++) {
var y = cellTop + j;
if (!this.rowlist[y].hidden) {
this._drawCell(x, y);
}
}
this._drawLineVertical(x);
}
// full height
var rarea = this._getAreaRowsWithMargin();
for (var y = rarea.start; y < rarea.end; y++) {
if (!this.rowlist[y].hidden) {
this._drawLineHorizontal(y);
}
}
};
this._drawCells = function() {
if (calendar.progressiveRowRendering) {
this._drawResHeadersProgressive();
}
if (this.rowlist !== null && this.rowlist.length > 0) {
var sweep = this.cellSweeping;
if (sweep) {
var keepOld = this.cellSweepingCacheSize;
this._deleteOldCells(keepOld);
}
this._drawCellsFull();
this._drawTimeBreaks();
rowtools._updateHighlighting();
}
var width = this._getGridWidth();
this._maind.style.height = this._innerHeightTree + "px";
this._maind.style.width = width + "px";
if (calendar.cellWidthSpec === "Auto") {
calendar.nav.scroll.style.overflowX = "hidden";
calendar.nav.scroll.scrollLeft = 0;
}
else {
calendar.nav.scroll.style.overflowX = "auto";
}
this._rowsDirty = false;
};
this._drawTimeBreaks = function() {
//this.elements.cells = []; // just to make sure
var area = this._getDrawArea();
for (var x = area.xStart; x < area.xEnd; x++) {
var breaks = (x < this.itline.length - 1) ? this.itline[x + 1].breakBefore : false;
if (breaks) {
this._drawTimeBreak(x);
}
}
};
this._drawTimeBreak = function(x) {
var index = "x" + x;
if (this._cache.breaks[index]) {
return;
}
//var left = x * this.cellWidth + this.cellWidth - 1;
var left = this.itline[x + 1].left - 1;
var height = this._innerHeightTree;
var line = document.createElement("div");
line.style.left = left + "px";
line.style.top = "0px";
line.style.width = "1px";
line.style.height = height + "px";
line.style.fontSize = '1px';
line.style.lineHeight = '1px';
line.style.overflow = 'hidden';
line.style.position = 'absolute';
line.setAttribute("unselectable", "on");
//cell.className = this._prefixCssClass('cellbackground');
if (this.cssOnly) {
line.className = this._prefixCssClass("_matrix_vertical_break");
//line.className = this._prefixCssClass("_matrix
}
else {
line.style.backgroundColor = this.timeBreakColor;
}
this.divBreaks.appendChild(line);
this.elements.breaks.push(line);
this._cache.breaks[index] = line;
};
this._getDrawArea = function() {
if (calendar._cache.drawArea) {
return calendar._cache.drawArea;
}
if (!this.nav.scroll) {
return null;
}
// const
//var preCache = 30;
var scrollTop = calendar._scrollTop;
var area = {};
//var divScroll = calendar.divScroll;
//***
var marginX = this.dynamicEventRenderingMargin;
var marginX = this.dynamicEventRenderingMarginX != null ? this.dynamicEventRenderingMarginX : this.dynamicEventRenderingMargin;
var marginY = this.dynamicEventRenderingMarginY != null ? this.dynamicEventRenderingMarginY : this.dynamicEventRenderingMargin;
var left = calendar._scrollPos - marginX;
var right = left + calendar._scrollWidth + 2*marginX;
var start = 0;
var end = 0;
if (calendar.itline && calendar.itline.length > 0) {
start = calendar._getItlineCellFromPixels(left).x;
end = calendar._getItlineCellFromPixels(right, true).x;
var totalWidth = this._cellCount();
end = Math.min(end, totalWidth); // make sure it's within the boundaries
start = Math.max(start, 0); // check the left side
}
var top = scrollTop - marginY;
var bottom = scrollTop + this.nav.scroll.offsetHeight + 2*marginY;
var cellTop = this._getRow(top).i;
var cellBottom = this._getRow(bottom).i;
if (cellBottom < this.rowlist.length) {
cellBottom++;
}
area.xStart = start;
area.xEnd = end;
area.yStart = cellTop;
area.yEnd = cellBottom;
area.pixels = {};
area.pixels.left = this.nav.scroll.scrollLeft;
area.pixels.right = this.nav.scroll.scrollLeft + this.nav.scroll.clientWidth;
area.pixels.top = this.nav.scroll.scrollTop;
area.pixels.bottom = this.nav.scroll.scrollTop + this.nav.scroll.clientHeight;
area.pixels.width = this.nav.scroll.scrollWidth;
calendar._cache.drawArea = area;
return area;
};
this._getGridWidth = function() {
var result = 0;
if (this.viewType === "Days") {
result = 24*60/this.cellDuration*this.cellWidth;
}
else {
var last = this.itline[this.itline.length - 1];
if (!last) {
result = 0;
}
else {
result = last.left + last.width;
}
}
if (result < 0 || isNaN(result)) {
result = 0;
}
return result;
};
this._drawLineHorizontal = function(y) {
var index = "y" + y;
if (this._cache.linesHorizontal[index]) {
//calendar.debug.message("skiping horiz line: " + index);
return;
}
var top = this.rowlist[y].top + this.rowlist[y].height - 1;
//var width = this._cellCount() * this.cellWidth;
var width = this._getGridWidth();
var line = document.createElement("div");
line.style.left = "0px";
line.style.top = top + "px";
line.style.width = width + "px";
line.style.height = "1px";
line.style.fontSize = '1px';
line.style.lineHeight = '1px';
line.style.overflow = 'hidden';
line.style.position = 'absolute';
if (!this.cssOnly) {
line.style.backgroundColor = this.cellBorderColor;
}
line.setAttribute("unselectable", "on");
if (this.cssOnly) {
line.className = this._prefixCssClass("_matrix_horizontal_line");
}
this.divLines.appendChild(line);
//this.elements.linesHorizontal.push(line);
this._cache.linesHorizontal[index] = line;
};
this._drawLineVertical = function(x) {
var itc = this.itline[x];
if (!itc) {
return;
}
var index = "x" + x;
if (this._cache.linesVertical[index]) {
return;
}
//var left = (x + 1) * this.cellWidth - 1;
var left = itc.left + itc.width - 1;
var line = document.createElement("div");
line.style.left = left + "px";
line.style.top = "0px";
line.style.width = "1px";
line.style.height = calendar._innerHeightTree + "px";
line.style.fontSize = '1px';
line.style.lineHeight = '1px';
line.style.overflow = 'hidden';
line.style.position = 'absolute';
if (!this.cssOnly) {
line.style.backgroundColor = this.cellBorderColor;
}
line.setAttribute("unselectable", "on");
if (this.cssOnly) {
line.className = this._prefixCssClass("_matrix_vertical_line");
}
this.divLines.appendChild(line);
this.elements.linesVertical.push(line);
this._cache.linesVertical[index] = line;
};
this._toggle = function(index) {
var row = this.rowlist[index];
var expanded = !row.expanded;
row.expanded = expanded;
if (row.resource) {
row.resource.expanded = expanded;
}
var rows = this._updateChildren(index, row.expanded);
if (!expanded) {
for (var i = 0; i < rows.length; i++) {
var ri = rows[i];
this._deleteEventsInRow(ri);
}
}
this._prepareRowTops();
// the height needs to be updated before drawing cells
this._drawResHeader();
//this._drawResHeadersProgressive(); // not sure, should be fired from drawCells
this._updateHeight();
this._clearCachedValues();
if (expanded) {
for (var i = 0; i < rows.length; i++) {
var ri = rows[i];
this._drawEventsInRow(ri);
}
this._findEventsInViewPort();
}
this._updateEventTops();
linktools.load();
//this.nav.scroll.style.display = 'none';
this._deleteCells(); // don't confuse the cache
this._drawCells();
//this.nav.scroll.style.display = '';
this._saveState();
var r = this._createRowObject(row, index);
if (expanded) {
this._resourceExpandDispatch(r);
}
else {
this._resourceCollapseDispatch(r);
}
this._clearCachedValues();
};
this._loadNode = function(i) {
var params = {};
params.index = i;
if (typeof this.onLoadNode === 'function') {
var args = {};
var resource = this.rowlist[i].resource;
args.resource = resource;
args.async = false;
args.loaded = function() {
if (this.async) {
resource.dynamicChildren = false;
resource.expanded = true;
calendar.update();
}
};
this.onLoadNode(args);
if (!args.async) {
resource.dynamicChildren = false;
resource.expanded = true;
this.update();
}
}
else {
this._callBack2('LoadNode', params);
}
};
this._updateChildren = function(i, topExpanded) {
var row = this.rowlist[i];
var changed = [];
//var node = this.tree[i];
if (row.children === null || row.children.length === 0) {
return changed;
}
for (var k = 0; k < row.children.length; k++) {
var index = row.children[k];
this.rowlist[index].hidden = topExpanded ? !row.expanded : true; // show/hide but don't change Expanded state
if (topExpanded === !this.rowlist[index].hidden) {
changed.push(index);
}
var uchildren = this._updateChildren(index, topExpanded);
if (uchildren.length > 0) {
changed = changed.concat(uchildren);
}
}
return changed;
};
this._startScroll = function(stepX, stepY) {
//var step = 10;
this._stopScroll();
this._scrollabit(stepX, stepY);
};
this._scrollabitX = function(step) {
if (!step) {
return false;
}
var total = this.nav.scroll.scrollWidth;
var start = this.nav.scroll.scrollLeft;
var width = this.nav.scroll.clientWidth;
var right = start + width;
if (step < 0 && start <= 0) {
return false;
}
if (step > 0 && right >= total) {
return false;
}
this.nav.scroll.scrollLeft += step;
// this is not necessary, it's linked using nav.scroll.onscroll
//this.divTimeScroll.scrollLeft = this.nav.scroll.scrollLeft;
return true;
};
this._scrollabitY = function(step) {
if (!step) {
return false;
}
var total = this.nav.scroll.scrollHeight;
var start = this.nav.scroll.scrollTop;
var height = this.nav.scroll.clientHeight;
var bottom = start + height;
if (step < 0 && start <= 0) {
return false;
}
if (step > 0 && bottom >= total) {
return false;
}
this.nav.scroll.scrollTop += step;
// this is not necessary, it's linked using nav.scroll.onscroll
//this.divTimeScroll.scrollTop = this.nav.scroll.scrollTop;
return true;
};
this._scrollabit = function(stepX, stepY) {
var moved = this._scrollabitX(stepX) || this._scrollabitY(stepY);
if (!moved) {
return;
}
var delayed = function(stepX, stepY) {
return function() {
calendar._scrollabit(stepX, stepY);
};
};
this.scrolling = window.setTimeout(delayed(stepX, stepY), 100);
};
this._stopScroll = function() {
if (this.scrolling) {
window.clearTimeout(this.scrolling);
this.scrolling = null;
}
};
this._prepareRowTops = function() {
var top = 0;
for (var i = 0; i < this.rowlist.length; i++) {
var row = this.rowlist[i];
if (!row.hidden) {
row.top = top;
top += row.height;
}
}
this._innerHeightTree = top;
//return top; // now it's the bottom of the last visible row
};
this._deleteCells = function() {
this.elements.cells = [];
this.elements.linesVertical = [];
//this.elements.linesHorizontal = [];
this.elements.breaks = [];
this._cache.cells = [];
this._cache.linesVertical = {};
this._cache.linesHorizontal = {};
this._cache.breaks = [];
this.divCells.innerHTML = '';
this.divLines.innerHTML = '';
this.divBreaks.innerHTML = '';
};
this._deleteCellsInRow = function(y) {
var list = DayPilot.list();
for (var name in calendar._cache.cells) {
list.push(calendar._cache.cells[name]);
}
list.filter(function(item) {
return item && item.coords && item.coords.y === y;
}).each(function(item) {
calendar._deleteCell(item);
});
};
this._cellsRendered = 0;
this._cellProps = ['html', 'cssClass', 'backColor', 'backImage', 'backRepeat', 'business'];
this._drawCell = function(x, y) {
if (!this._initialized) {
return;
}
var itc = this.itline[x];
if (!itc) {
return;
}
var index = x + '_' + y;
if (this._cache.cells[index]) {
return;
}
//calendar.debug.message("drawing cell " + x + "/" + y);
var p = this._getCellProperties(x, y);
if (typeof this.onBeforeCellRender === 'function') {
var row = calendar.rowlist[y];
var resource = row.id;
var rowOffset = row.start.getTime() - this._visibleStart().getTime();
var start = itc.start.addTime(rowOffset);
var end = itc.end.addTime(rowOffset);
var cell = calendar.cells.findXy(x, y)[0];
var args = {};
args.cell = cell;
args.getPixels = function(date) {
var date = new DayPilot.Date(date);
var totalpix = calendar.getPixels(date).left;
return totalpix - itc.left;
};
this.onBeforeCellRender(args);
// backwards compatibility
DayPilot.Util.copyProps(args.cell, args.cell.properties, calendar._cellProps);
}
// don't draw cells with no/default properties
if (!this.drawBlankCells) {
var isDefault = false;
if (this.cssOnly && this._isRowParent(y)) {
isDefault = false;
}
else if (!this._hasProps(p, calendar._cellProps)) {
isDefault = true;
}
if (isDefault) {
return;
}
}
var cell = document.createElement("div");
cell.style.left = (itc.left) + "px";
cell.style.top = this.rowlist[y].top + "px";
cell.style.width = (itc.width) + "px";
cell.style.height = (this.rowlist[y].height) + "px";
cell.style.position = 'absolute';
if (p && p.backColor) {
cell.style.backgroundColor = p.backColor;
}
cell.setAttribute("unselectable", "on");
cell.className = this.cssOnly ? this._prefixCssClass('_cell') : this._prefixCssClass('cellbackground');
if (this.collisionStart && this.collisionEnd
&& itc.start.getTime() >= this.collisionStart.getTime()
&& itc.end.getTime() <= this.collisionEnd.getTime()) {
cell.className += " " + this._prefixCssClass('_collision_cell');
}
cell.coords = {};
cell.coords.x = x;
cell.coords.y = y;
if (this.cssOnly && this._isRowParent(y)) {
DayPilot.Util.addClass(cell, this._prefixCssClass("_cellparent"));
}
if (p) {
if (p.cssClass) {
if (this.cssOnly) {
DayPilot.Util.addClass(cell, p.cssClass);
}
else {
DayPilot.Util.addClass(cell, calendar._prefixCssClass(p.cssClass));
}
}
if (p.html) {
cell.innerHTML = p.html;
}
if (p.backImage) {
cell.style.backgroundImage = "url(\"" + p.backImage + "\")";
}
if (p.backRepeat) {
cell.style.backgroundRepeat = p.backRepeat;
}
if (p.business) {
DayPilot.Util.addClass(cell, calendar._prefixCssClass("_cell_business"));
}
}
// TEST
cell.onclick = this._onMaindClick;
cell.onmouseup = this._onMaindMouseUp;
this.divCells.appendChild(cell);
this.elements.cells.push(cell);
this._cache.cells[index] = cell;
//this._cellsRendered += 1;
};
this._hasProps = function(object, props) {
if (props) {
for (var i = 0; i < props.length; i++) {
if (object[props[i]]) {
return true;
}
}
}
else {
for (var name in object) {
if (object[name]) {
return true;
}
}
}
return false;
};
this.clearSelection = function() {
this._deleteRange();
mr.clear();
};
this.cleanSelection = this.clearSelection;
this._deleteRange = function() {
// IE doesn't like the div empty
this.divRange.innerHTML = '<div style="position:absolute; left:0px; top:0px; width:0px; height:0px;"></div>';
this.elements.range = [];
this.elements.range2 = null;
this._clearShadowHover();
DayPilotScheduler.rangeHold = null;
};
this._resolved = {};
var resolved = this._resolved;
resolved.locale = function() {
return DayPilot.Locale.find(calendar.locale);
};
resolved.timeFormat = function() {
if (calendar.timeFormat !== 'Auto') {
return calendar.timeFormat;
}
return resolved.locale().timeFormat;
};
resolved.weekStarts = function() {
if (calendar.weekStarts === 'Auto') {
var locale = resolved.locale();
if (locale) {
return locale.weekStarts;
}
else {
return 0; // Sunday
}
}
else {
return calendar.weekStarts;
}
};
resolved.rounded = function() {
return calendar.eventCorners === 'Rounded';
};
resolved.layout = function() {
var isIE6 = /MSIE 6/i.test(navigator.userAgent);
if (calendar.layout === 'Auto') {
if (isIE6) {
return 'TableBased';
}
else {
return 'DivBased';
}
}
return calendar.layout;
};
resolved.notifyType = function() {
var type;
if (calendar.notifyCommit === 'Immediate') {
type = "Notify";
}
else if (calendar.notifyCommit === 'Queue') {
type = "Queue";
}
else {
throw "Invalid notifyCommit value: " + calendar.notifyCommit;
}
return type;
};
resolved.isResourcesView = function() {
return calendar.viewType !== 'Days';
};
resolved.useBox = function(durationTicks) {
if (calendar.useEventBoxes === 'Always') {
return true;
}
if (calendar.useEventBoxes === 'Never') {
return false;
}
return durationTicks < calendar.cellDuration * 60 * 1000;
};
resolved.eventHeight = function() {
if (calendar._cache.eventHeight) {
return calendar._cache.eventHeight;
}
var height = calendar._getDimensionsFromCss("_event_height").height;
if (!height) {
height = calendar.eventHeight;
}
calendar._cache.eventHeight = height;
return height;
};
resolved.headerHeight = function() {
if (calendar._cache.headerHeight) {
return calendar._cache.headerHeight;
}
var height = calendar._getDimensionsFromCss("_header_height").height;
if (!height) {
height = calendar.headerHeight;
}
calendar._cache.headerHeight = height;
return height;
};
resolved.splitterWidth = function() {
if (calendar.rowHeaderScrolling) {
return calendar.rowHeaderSplitterWidth;
}
return 1;
};
this._getColor = function(x, y) {
var index = x + '_' + y;
if (this.cellProperties && this.cellProperties[index]) {
return this.cellProperties[index].backColor;
}
return null;
};
this._getCellProperties = function(x, y) {
var index = x + '_' + y;
if (!this.cellProperties) {
this.cellProperties = {};
}
if (this.cellProperties[index]) {
return this.cellProperties[index];
}
if (this._cellPropertiesLazyLoading) {
this.cellProperties[index] = calendar._getExpandedCell(x, y);
}
if (!this.cellProperties[index]) {
var row = calendar.rowlist[y];
var resource = row.id;
//var rowOffset = row.start.getTime() - this.startDate.getTime();
var rowOffset = row.start.getTime() - calendar._visibleStart().getTime();
var itc = calendar.itline[x];
var start = itc.start.addTime(rowOffset);
var end = itc.end.addTime(rowOffset);
var ibj = {};
ibj.start = start;
ibj.end = end;
ibj.resource = resource;
var cell = {};
cell.business = calendar.isBusiness(ibj);
if (!this.cssOnly) {
cell.backColor = cell.business ? this.cellBackColor : this.cellBackColorNonBusiness;
}
this.cellProperties[index] = cell;
}
return this.cellProperties[index];
};
this._copyCellProperties = function(source, x, y) {
var index = x + '_' + y;
this.cellProperties[index] = {};
DayPilot.Util.copyProps(source, this.cellProperties[index], calendar._cellProps);
//DayPilot.Util.copyProps(source, this.cellProperties[index]);
return this.cellProperties[index];
};
this._getExpandedCell = function(x, y) {
if (!this.cellConfig) {
return null;
}
var config = this.cellConfig;
var cell = this.cellProperties[x + "_" + y];
if (!cell && config.vertical) {
cell = this.cellProperties[x + "_0"];
}
if (!cell && config.horizontal) {
cell = this.cellProperties["0_" + y];
}
if (!cell && config["default"]) {
cell = config["default"];
}
var copy = {};
DayPilot.Util.copyProps(cell, copy, calendar._cellProps);
return copy;
};
this._expandCellProperties = function() {
if (this._cellPropertiesLazyLoading) {
return;
}
if (!this.cellConfig) {
return;
}
var config = this.cellConfig;
if (config.vertical) {
for (var x = 0; x < config.x; x++) {
var def = this.cellProperties[x + "_0"];
if (!def) {
continue;
}
for (var y = 1; y < config.y; y++) {
this._copyCellProperties(def, x, y);
}
}
}
if (config.horizontal) {
for (var y = 0; y < config.y; y++) {
var def = this.cellProperties["0_" + y];
if (!def) {
continue;
}
for (var x = 1; x < config.x; x++) {
this._copyCellProperties(def, x, y);
//this.cellProperties[x + "_" + y] = def;
}
}
}
if (config["default"]) {
var def = config["default"];
for (var y = 0; y < config.y; y++) {
for (var x = 0; x < config.x; x++) {
if (!this.cellProperties[x + "_" + y]) {
this._copyCellProperties(def, x, y);
// this.cellProperties[x + "_" + y] = def;
}
}
}
}
};
this.isBusiness = function(cell) {
/*
switch (this.scale) {
case "Year":
return true;
case "Month":
return true;
case "Week":
return true;
case "Day":
break;
case "Hour":
break;
case "Minute":
break;
case "CellDuration":
break;
case "Manual":
break;
}
*/
var start = cell.start;
var end = cell.end;
var cellDuration = (end.getTime() - start.getTime()) / (1000 * 60); // minutes
if (cellDuration <= 1440) { // for one day per cell and lower only
if (cell.start.dayOfWeek() === 0 || cell.start.dayOfWeek() === 6) {
return false;
}
}
if (cellDuration < 720) {
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;
}
/*
if (cell.start.getHours() < this.businessBeginsHour || cell.start.getHours() >= this.businessEndsHour) {
return false;
}
else {
return true;
}*/
}
return true;
};
this._show = function() {
if (this.nav.top.style.visibility === 'hidden') {
this.nav.top.style.visibility = 'visible';
}
};
this._visible = function() {
var el = calendar.nav.top;
return el.offsetWidth > 0 && el.offsetHeight > 0;
};
this._waitForVisibility = function() {
var visible = calendar._visible;
if (!visible()) {
calendar.debug.message("Not visible during init, starting visibilityInterval");
calendar._visibilityInterval = setInterval(function() {
if (visible()) {
calendar.debug.message("Made visible, calling .show()");
calendar.show();
calendar._autoRowHeaderWidth();
clearInterval(calendar._visibilityInterval);
}
}, 100);
}
};
// sets the total height
this._setHeight = function(pixels) {
if (this.heightSpec !== "Parent100Pct") {
this.heightSpec = "Fixed";
}
this.height = pixels - (this._getTotalHeaderHeight() + 2);
this._updateHeight();
};
this.setHeight = this._setHeight;
this._findRowByResourceId = function(id) {
for (var i = 0; i < this.rowlist.length; i++) {
if (this.rowlist[i].id === id) {
return this.rowlist[i];
}
}
return null;
};
this._loadTop = function() {
//this.nav.top = document.getElementById(id);
if (this.id && this.id.tagName) {
this.nav.top = this.id;
}
else if (typeof this.id === "string") {
this.nav.top = document.getElementById(this.id);
if (!this.nav.top) {
throw "DayPilot.Scheduler: The placeholder element not found: '" + id + "'.";
}
}
else {
throw "DayPilot.Scheduler() constructor requires the target element or its ID as a parameter";
}
};
this._shortInit = function() {
//this._loadTop();
this._prepareVariables();
this._loadResources();
//this._initPrepareDiv();
this._resize();
this._registerGlobalHandlers();
this._registerDispose();
DayPilotScheduler.register(this);
this._fireAfterRenderDetached(this.afterRenderData, false);
this._registerOnScroll();
this._waitForVisibility();
this._startAutoRefresh();
this._callBack2('Init');
};
this.init = function() {
this._initUpdateBased();
//this._initOriginal();
};
this._initUpdateBased = function() {
this._loadTop();
if (this.nav.top.dp) {
return;
}
this._initPrepareDiv();
var loadFromServer = this._isShortInit();
if (loadFromServer) {
this._shortInit();
this._initialized = true;
this._clearCachedValues();
return;
}
this._registerGlobalHandlers();
this._registerDispose();
DayPilotScheduler.register(this);
this._registerOnScroll();
this._update();
if (calendar.scrollToDate) {
calendar.scrollTo(calendar.scrollToDate);
}
else {
calendar.setScroll(calendar.scrollX, calendar.scrollY);
}
var setScrollY = function() {
if (calendar.scrollY) {
calendar.setScroll(calendar.scrollX, calendar.scrollY);
}
};
window.setTimeout(setScrollY, 200);
if (this.messageHTML) {
window.setTimeout(function() { calendar.message(calendar.messageHTML); }, 100);
}
this._waitForVisibility();
this._startAutoRefresh();
this._initialized = true;
this._clearCachedValues();
this._fireAfterRenderDetached(this.afterRenderData, false);
this.debug.message("Init complete.");
this._postInit();
};
this._initTemp = function() {
this._loadTop();
if (this.nav.top.dp) {
return;
}
var loadFromServer = this._isShortInit();
//var eventsAvailable = this.events.list !== null;
if (loadFromServer) {
this._shortInit();
this._initialized = true;
this._clearCachedValues();
return;
}
// frame
this._prepareVariables();
this._initPrepareDiv();
this._loadingStart();
// draw res header, required for width
this._loadResources();
this._loadEvents();
this._prepareRowTops();
this._drawResHeader();
// cells and time headers, may be dependent on scroll area width
this._prepareItline();
this._expandCellProperties();
this._drawTimeHeader();
this._updateHeight();
this._drawSeparators();
this._loadSelectedRows(this.selectedRows);
//this._resize();
//this._show();
this._registerGlobalHandlers();
this._registerDispose();
DayPilotScheduler.register(this);
//this.afterRender(null, false);
this._registerOnScroll();
this._loadingStop();
if (calendar.scrollToDate) {
calendar.scrollTo(calendar.scrollToDate);
}
else {
calendar.setScroll(calendar.scrollX, calendar.scrollY);
}
if (!calendar.onScrollCalled) {
calendar._onScroll(); // renders cells
}
var setScrollY = function() {
if (calendar.scrollY) {
calendar.setScroll(calendar.scrollX, calendar.scrollY);
}
};
window.setTimeout(setScrollY, 200);
if (this.messageHTML) {
var showMessage = function(msg) {
return function() {
calendar.message(msg);
};
};
window.setTimeout(showMessage(this.messageHTML), 100);
//this.message(this.messageHTML, 5000);
}
this._waitForVisibility();
this._startAutoRefresh();
this._initialized = true;
this._clearCachedValues();
this._fireAfterRenderDetached(this.afterRenderData, false);
this.debug.message("Init complete.");
this._postInit();
};
this._initOriginal = function() {
this._loadTop();
if (this.nav.top.dp) {
return;
}
var loadFromServer = this._isShortInit();
//var eventsAvailable = this.events.list !== null;
if (loadFromServer) {
this._shortInit();
this._initialized = true;
this._clearCachedValues();
return;
}
this._prepareVariables();
this._prepareItline();
this._loadResources();
this._expandCellProperties();
this._initPrepareDiv();
// resize can't be here because of autocellwidth mode, not all variables are ready
this._calculateCellWidth();
this._drawTimeHeader();
this._loadingStart();
this._loadEvents();
this._prepareRowTops();
this._drawResHeader();
this._updateHeight();
this._drawSeparators();
this._loadSelectedRows(this.selectedRows);
this._resize();
//this._show();
this._registerGlobalHandlers();
this._registerDispose();
DayPilotScheduler.register(this);
//this.afterRender(null, false);
this._registerOnScroll();
this._loadingStop();
if (calendar.scrollToDate) {
calendar.scrollTo(calendar.scrollToDate);
}
else {
calendar.setScroll(calendar.scrollX, calendar.scrollY);
}
if (!calendar.onScrollCalled) {
calendar._onScroll(); // renders cells
}
var setScrollY = function() {
if (calendar.scrollY) {
calendar.setScroll(calendar.scrollX, calendar.scrollY);
}
};
window.setTimeout(setScrollY, 200);
if (this.messageHTML) {
var showMessage = function(msg) {
return function() {
calendar.message(msg);
};
};
window.setTimeout(showMessage(this.messageHTML), 100);
//this.message(this.messageHTML, 5000);
}
this._waitForVisibility();
this._startAutoRefresh();
this._initialized = true;
this._clearCachedValues();
this._fireAfterRenderDetached(this.afterRenderData, false);
this.debug.message("Init complete.");
this._postInit();
};
this._specialHandling = null;
this._loadOptions = function(options) {
var specialHandling = {
"events": {
"preInit": function() {
var events = this.data;
if (!events) {
return;
}
if (DayPilot.isArray(events.list)) {
calendar.events.list = events.list;
}
else {
calendar.events.list = events;
}
},
"postInit": function() {
}
},
"scrollTo": {
"preInit": function() {
},
"postInit": function() {
if (this.data) {
calendar.scrollTo(this.data);
}
}
}
};
this._specialHandling = specialHandling;
for (var name in options) {
if (specialHandling[name]) {
var item = specialHandling[name];
item.data = options[name];
if (item.preInit) {
item.preInit();
}
}
else {
calendar[name] = options[name];
}
}
};
this._postInit = function() {
var specialHandling = this._specialHandling;
for (var name in specialHandling) {
var item = specialHandling[name];
if (item.postInit) {
item.postInit();
}
}
};
this.temp = {};
this.temp.getPosition = function() {
var x = Math.floor(calendar.coords.x / calendar.cellWidth);
var y = calendar._getRow(calendar.coords.y).i;
if (y < calendar.rowlist.length) {
var cell = {};
cell.start = calendar.itline[x].start;
cell.end = calendar.itline[x].end;
cell.resource = calendar.rowlist[y].id;
return cell;
}
else {
return null;
}
};
// communication between components
this.internal = {};
// ASP.NET
this.internal.initialized = function() {
return calendar._initialized;
};
// DayPilot.Action
this.internal.invokeEvent = this._invokeEvent;
// DayPilot.Menu
this.internal.eventMenuClick = this._eventMenuClick;
this.internal.timeRangeMenuClick = this._timeRangeMenuClick;
this.internal.resourceHeaderMenuClick = this._rowMenuClick;
this.internal.linkMenuClick = this._linkMenuClick;
// DayPilot.Bubble
this.internal.bubbleCallBack = this._bubbleCallBack;
this.internal.findEventDiv = this._findEventDiv;
this.internal.rowtools = this._rowtools;
// DayPilot.Gantt
this.internal.getNodeChildren = this._getNodeChildren;
this.internal.callback = function() {
calendar._callBack2.apply(calendar, arguments);
};
this.internal.createRowObject = this._createRowObject;
// DayPilot.Event
this.internal.adjustEndIn = calendar._adjustEndIn;
this.internal.adjustEndNormalize = calendar._adjustEndNormalize;
this.Init = this.init;
this._loadOptions(options);
};
DayPilot.Row = function(row, calendar) {
if (!row) {
throw "Now row object supplied when creating DayPilot.Row";
}
if (!calendar) {
throw "No parent control supplied when creating DayPilot.Row";
}
var index = DayPilot.indexOf(calendar.rowlist, row);
var r = this;
r.isRow = true;
r.menuType = 'resource';
r.start = row.start;
r.name = row.name;
r.value = row.id;
r.id = row.id;
r.tags = row.tags;
r.index = index;
r.calendar = calendar;
r._row = row;
r.$ = {};
r.$.row = row;
r.toJSON = function(key) {
var json = {};
json.start = this.start;
json.name = this.name;
json.value = this.value;
json.id = this.id;
json.index = this.index;
return json;
};
r.events = {};
r.events.all = function() {
var list = [];
for (var i = 0; i < r._row.events.length; i++) {
list.push(r._row.events[i]);
}
return DayPilot.list(list);
};
r.events.totalDuration = function() {
var ticks = 0;
r.events.all().each(function(item) {
ticks += item.part.end.getTime() - item.part.start.getTime();
});
return new DayPilot.Duration(ticks);
};
r.groups = {};
r.groups.collapseAll = function() {
for (var i = 0; i < r._row.blocks.length; i++) {
var block = r._row.blocks[i];
var group = new EventGroup(block);
group._collapseDontRedrawRow();
}
calendar._updateRowHeights();
calendar._updateRowsNoLoad(r.index);
calendar._updateHeight();
};
r.groups.expandAll = function() {
for (var i = 0; i < r._row.blocks.length; i++) {
var block = r._row.blocks[i];
var group = new EventGroup(block);
group._expandDontRedrawRow();
}
calendar._updateRowHeights();
calendar._updateRowsNoLoad(r.index);
calendar._updateHeight();
};
r.groups.expanded = function() {
var list = [];
for (var i = 0; i < r._row.blocks.length; i++) {
var block = r._row.blocks[i];
if (block.expanded && block.lines.length > calendar.groupConcurrentEventsLimit) {
list.push(new EventGroup(block));
}
}
return DayPilot.list(list);
};
r.groups.collapsed = function() {
var list = [];
for (var i = 0; i < r._row.blocks.length; i++) {
var block = r._row.blocks[i];
if (!block.expanded) {
list.push(new EventGroup(block));
}
}
return DayPilot.list(list);
};
r.groups.all = function() {
var list = [];
for (var i = 0; i < r._row.blocks.length; i++) {
var block = r._row.blocks[i];
list.push(new EventGroup(block));
}
return DayPilot.list(list);
};
r.events.collapseGroups = r.groups.collapseAll;
r.events.expandGroups = r.groups.expandAll;
r.column = function(i) {
return new RowHeaderColumn(r, i);
};
r.toggle = function() {
calendar._toggle(r.index);
};
var EventGroup = function(block) {
var findDiv = function(block) {
for (var i = 0; i < calendar.elements.events.length; i++) {
var div = calendar.elements.events[i];
if (div.event === block) {
return div;
}
}
return null;
};
this._expandDontRedrawRow = function() {
block.expanded = true;
var div = findDiv(block);
if (div) {
calendar._deleteBlock(div);
var elindex = DayPilot.indexOf(calendar.elements.events, div);
if (elindex !== -1) {
calendar.elements.events.splice(elindex, 1);
}
}
};
this.expand = function() {
this._expandDontRedrawRow();
calendar._updateRowHeights();
calendar._updateRowsNoLoad(block.row.index);
calendar._updateHeight();
};
this._collapseDontRedrawRow = function() {
if (block.lines.length > calendar.groupConcurrentEventsLimit) {
block.expanded = false;
}
};
this.collapse = function() {
this._collapseDontRedrawRow();
calendar._updateRowHeights();
calendar._updateRowsNoLoad(block.row.index);
calendar._updateHeight();
};
};
var RowHeaderColumn = function(row, i) {
this.html = function(html) {
var table = row.calendar.divHeader;
var cell = table.rows[row.index].cells[i];
var text = cell.textDiv;
if (typeof html === "undefined") {
return text.innerHTML;
}
else {
text.innerHTML = html;
}
};
};
};
// internal moving
DayPilotScheduler.moving = null;
// internal resizing
DayPilotScheduler.originalMouse = null;
DayPilotScheduler.resizing = null;
DayPilotScheduler.globalHandlers = false;
DayPilotScheduler.timeRangeTimeout = null;
// selecting
DayPilotScheduler.selectedCells = null;
DayPilotScheduler.dragStart = function(element, duration, id, text, type) {
DayPilot.us(element);
var drag = DayPilotScheduler.drag = {};
drag.element = element;
drag.duration = duration;
drag.text = text;
drag.id = id;
drag.shadowType = type ? type : 'Fill'; // default value
return false;
};
/*
* options: {
* element: dom element,
* duration: duration in minutes,
* text: event text,
* id: id
* }
*/
DayPilot.Scheduler.makeDraggable = function(options) {
var element = options.element;
var removeElement = options.keepElement ? null : element;
DayPilot.us(element); // make it unselectable
DayPilot.re(element, "mousedown", function(ev) {
DayPilotScheduler.dragStart(removeElement, options.duration, options.id, options.text);
var element = (ev.target || ev.srcElement);
if(element.tagName) {
var tagname = element.tagName.toLowerCase();
if(tagname === "textarea" || tagname === "select" || tagname === "input") {
return false;
}
}
ev.preventDefault && ev.preventDefault();
return false;
});
element.ontouchstart = function(ev) {
var holdfor = 0;
window.setTimeout(function() {
var drag = DayPilotScheduler.drag = {};
drag.element = removeElement;
// TODO create drag.event = new DayPilot.Event() here
drag.id = options.id;
drag.text = options.text || "";
drag.duration = options.duration || 60;
drag.shadowType = "Fill";
DayPilotScheduler.gTouchMove(ev);
ev.preventDefault();
}, holdfor);
ev.preventDefault();
};
};
DayPilotScheduler.dragStop = function() {
if (DayPilotScheduler.gShadow) {
document.body.removeChild(DayPilotScheduler.gShadow);
DayPilotScheduler.gShadow = null;
}
DayPilotScheduler.drag = null;
};
DayPilotScheduler.register = function(calendar) {
if (!DayPilotScheduler.registered) {
DayPilotScheduler.registered = [];
}
for (var i = 0; i < DayPilotScheduler.registered.length; i++) {
if (DayPilotScheduler.registered[i] === calendar) {
return;
}
}
DayPilotScheduler.registered.push(calendar);
};
DayPilotScheduler.unregister = function(calendar) {
var a = DayPilotScheduler.registered;
if (a) {
var i = DayPilot.indexOf(a, calendar);
if (i !== -1) {
a.splice(i, 1);
}
if (a.length === 0) {
a = null;
}
}
if (!a) {
DayPilot.ue(document, 'mousemove', DayPilotScheduler.gMouseMove);
DayPilot.ue(document, 'mouseup', DayPilotScheduler.gMouseUp);
DayPilot.ue(document, 'keyup', DayPilotScheduler.gKeyUp);
DayPilot.ue(document, 'touchmove', DayPilotScheduler.gTouchMove);
DayPilot.ue(document, 'touchend', DayPilotScheduler.gTouchEnd);
//DayPilot.ue(window, 'unload', DayPilotScheduler.gUnload);
DayPilotScheduler.globalHandlers = false;
}
};
DayPilotScheduler.gTouchMove = function(ev) {
if (DayPilotScheduler.drag) {
ev.preventDefault();
var x = ev.touches[0].pageX;
var y = ev.touches[0].pageY;
var mousePos = {};
mousePos.x = x;
mousePos.y = y;
var calendar = (function() {
var clientX = ev.touches[0].clientX;
var clientY = ev.touches[0].clientY;
var el = document.elementFromPoint(clientX, clientY);
while (el && el.parentNode) {
el = el.parentNode;
if (el.daypilotMainD) {
return el.calendar;
}
}
return false;
})();
if (calendar) {
// hide the global shadow
if (DayPilotScheduler.gShadow) {
document.body.removeChild(DayPilotScheduler.gShadow);
}
DayPilotScheduler.gShadow = null;
//var div = ??;
//DayPilotScheduler.moving = div;
//DayPilotScheduler.movingShadow = calendar._createShadow(div, calendar.shadow);
calendar.coords = calendar._touch.relativeCoords(ev);
if (!DayPilotScheduler.movingShadow && calendar.rowlist.length > 0) {
if (!DayPilotScheduler.moving) { // can be null if the location is forbidden (first two rows in IE)
DayPilotScheduler.moving = {};
var event = DayPilotScheduler.drag.event;
if (!event) {
//var now = new DayPilot.Date().getDatePart();
var now = calendar.itline[0].start;
//calendar.debug.message("external start/touch:" + now);
var ev = { 'id': DayPilotScheduler.drag.id, 'start': now, 'end': now.addSeconds(DayPilotScheduler.drag.duration), 'text': DayPilotScheduler.drag.text };
event = new DayPilot.Event(ev);
event.calendar = calendar;
event.part.external = true;
}
DayPilotScheduler.moving.event = event;
}
DayPilotScheduler.movingShadow = calendar._createShadow(DayPilotScheduler.moving, DayPilotScheduler.drag.shadowType);
}
if (DayPilotScheduler.moving) {
calendar._touch.updateMoving();
}
}
else {
// hide the local shadow
DayPilot.de(DayPilotScheduler.movingShadow);
var movingSaveForLater = DayPilotScheduler.moving;
DayPilotScheduler.moving = null;
DayPilotScheduler.movingShadow = null;
if (!DayPilotScheduler.gShadow) {
DayPilotScheduler.gShadow = DayPilotScheduler.createGShadow(DayPilotScheduler.drag.shadowType);
DayPilotScheduler.gShadow.source = movingSaveForLater;
}
var shadow = DayPilotScheduler.gShadow;
shadow.style.left = mousePos.x + 'px';
shadow.style.top = mousePos.y + 'px';
/*
DayPilotScheduler.moving = null;
// TODO delete moving shadow
DayPilotScheduler.movingShadow = null;
shadow.innerHTML = "x:" + x;
*/
}
}
};
DayPilotScheduler.gTouchEnd = function(ev) {
DayPilotScheduler.gMouseUp(ev);
};
DayPilotScheduler.gMouseMove = function(ev) {
if (typeof (DayPilotScheduler) === 'undefined') {
return;
}
ev = ev || window.event;
// quick and dirty inside detection
// hack, but faster then recursing through the parents
if (ev.insideMainD) { // FF
return;
}
else if (ev.srcElement) { // IE
if (ev.srcElement.inside) {
return;
}
}
/*
if (typeof(DayPilotBubble) != 'undefined') {
DayPilotBubble.cancelTimeout();
if (DayPilotBubble.active) {
DayPilotBubble.active.delayedHide();
}
}
*/
var mousePos = DayPilot.mc(ev);
if (DayPilotScheduler.drag) {
document.body.style.cursor = 'move';
if (!DayPilotScheduler.gShadow) {
DayPilotScheduler.gShadow = DayPilotScheduler.createGShadow(DayPilotScheduler.drag.shadowType);
}
var shadow = DayPilotScheduler.gShadow;
shadow.style.left = mousePos.x + 'px';
shadow.style.top = mousePos.y + 'px';
// it's being moved outside, delete the inside shadow
DayPilotScheduler.moving = null;
if (DayPilotScheduler.movingShadow) {
var cal = DayPilotScheduler.movingShadow.calendar;
cal._clearShadowHover();
DayPilotScheduler.movingShadow.calendar = null;
DayPilot.de(DayPilotScheduler.movingShadow);
DayPilotScheduler.movingShadow = null;
}
}
else if (DayPilotScheduler.moving && DayPilotScheduler.moving.event.calendar.dragOutAllowed && !DayPilotScheduler.drag) {
var cal = DayPilotScheduler.moving.event.calendar; // source
var ev = DayPilotScheduler.moving.event;
// clear target
DayPilotScheduler.moving.target = null;
document.body.style.cursor = 'move';
if (!DayPilotScheduler.gShadow) {
DayPilotScheduler.gShadow = DayPilotScheduler.createGShadow(cal.shadow);
DayPilotScheduler.gShadow.source = DayPilotScheduler.moving;
}
var shadow = DayPilotScheduler.gShadow;
shadow.style.left = mousePos.x + 'px';
shadow.style.top = mousePos.y + 'px';
// it's being moved outside, delete the inside shadow
DayPilotScheduler.drag = {};
var drag = DayPilotScheduler.drag;
drag.element = null;
drag.duration = (ev.rawend().getTime() - ev.start().getTime()) / 1000;
drag.text = ev.text();
drag.id = ev.value();
drag.shadowType = cal.shadow;
drag.event = ev;
//DayPilotScheduler.moving = null;
cal._clearShadowHover();
DayPilot.de(DayPilotScheduler.movingShadow);
DayPilotScheduler.movingShadow.calendar = null;
DayPilotScheduler.movingShadow = null;
}
for (var i = 0; i < DayPilotScheduler.registered.length; i++) {
if (DayPilotScheduler.registered[i]._out) {
DayPilotScheduler.registered[i]._out();
}
}
};
DayPilotScheduler.gUnload = function(ev) {
if (!DayPilotScheduler.registered) {
return;
}
for (var i = 0; i < DayPilotScheduler.registered.length; i++) {
var c = DayPilotScheduler.registered[i];
//c.dispose();
DayPilotScheduler.unregister(c);
}
};
DayPilotScheduler.gMouseDown = function(ev) {
if (DayPilotScheduler.editing) {
DayPilotScheduler.editing.blur();
}
};
DayPilotScheduler.gKeyUp = function(ev) {
var ev = ev || window.event;
var key = ev.keyCode;
if (key === 17) {
if (DayPilotScheduler.rangeCalendar) {
var calendar = DayPilotScheduler.rangeCalendar;
calendar._multirange.dispatch();
}
/*
DayPilot.list(DayPilotScheduler.registered).each(function(item) {
item._multirange.dispatch();
});*/
}
};
DayPilotScheduler.gMouseUp = function(ev) {
if (DayPilotScheduler.resizing) {
if (!DayPilotScheduler.resizingShadow) {
document.body.style.cursor = '';
DayPilotScheduler.resizing = null;
return;
}
var e = DayPilotScheduler.resizing.event;
var calendar = e.calendar;
calendar._updateResizingShadow();
var newStart = DayPilotScheduler.resizingShadow.start;
var newEnd = DayPilotScheduler.resizingShadow.end;
var overlapping = DayPilotScheduler.resizingShadow.overlapping;
// stop resizing on the client
DayPilot.de(DayPilotScheduler.resizingShadow);
DayPilotScheduler.resizing = null;
DayPilotScheduler.resizingShadow = null;
calendar._clearShadowHover();
calendar._multiresize.clear();
document.body.style.cursor = '';
if (overlapping) {
return;
}
// action here
calendar._eventResizeDispatch(e, newStart, newEnd);
}
else if (DayPilotScheduler.moving) {
var cleanup = function() {
if (DayPilotScheduler.movingShadow) {
DayPilot.de(DayPilotScheduler.movingShadow);
DayPilotScheduler.movingShadow.calendar = null;
}
document.body.style.cursor = '';
DayPilotScheduler.moving = null;
DayPilotScheduler.drag = null;
};
if (!DayPilotScheduler.movingShadow) {
cleanup();
return;
}
var e = DayPilotScheduler.moving.event;
//var calendar = e.calendar; // doesn't work for drag&drop between two schedulers, this is the source
var calendar = DayPilotScheduler.moving.target;
if (!calendar) {
cleanup();
return;
}
DayPilot.Util.removeClass(DayPilotScheduler.moving, calendar._prefixCssClass("_event_moving_source"));
if (!DayPilotScheduler.movingShadow.row) {
cleanup();
return;
}
clearTimeout(calendar._autoexpand.timeout);
var newStart = DayPilotScheduler.movingShadow.start;
var newEnd = DayPilotScheduler.movingShadow.end;
var newResource = (calendar.viewType !== 'Days') ? DayPilotScheduler.movingShadow.row.id : null;
//var external = DayPilotScheduler.drag ? true : false;
var external = (DayPilotScheduler.drag ? true : false) && e.part.external;
var line = DayPilotScheduler.movingShadow.line;
//var left = DayPilotScheduler.movingShadow.offsetLeft;
var overlapping = DayPilotScheduler.movingShadow.overlapping;
var forbidden = !DayPilotScheduler.movingShadow.allowed;
// clear the moving state
DayPilot.de(DayPilotScheduler.movingShadow);
calendar._clearShadowHover();
if (DayPilotScheduler.drag) {
if (!calendar.todo) {
calendar.todo = {};
}
calendar.todo.del = DayPilotScheduler.drag.element;
DayPilotScheduler.drag = null;
}
DayPilotScheduler.movingShadow.calendar = null;
document.body.style.cursor = '';
DayPilotScheduler.moving = null;
DayPilotScheduler.movingShadow = null;
calendar._multimove.clear();
if (overlapping || forbidden || calendar._multimove.forbidden || calendar._multimove.invalid) {
return;
}
var ev = ev || window.event;
calendar._eventMoveDispatch(e, newStart, newEnd, newResource, external, ev, line);
//calendar._multimove.clear();
}
else if (DayPilotScheduler.range) {
ev = ev || window.event;
var button = DayPilot.Util.mouseButton(ev);
var range = DayPilotScheduler.range;
var calendar = range.calendar;
var ctrl = ev.ctrlKey || ev.metaKey;
if (calendar.allowMultiRange) {
if (!calendar.elements.range2.overlapping) {
calendar._multirange.add(range);
}
else {
DayPilot.de(calendar.elements.range2);
calendar.elements.range2 = null;
calendar._clearShadowHover();
}
DayPilotScheduler.range = null;
if (!ctrl) {
calendar._multirange.dispatch();
}
return;
}
if (DayPilotScheduler.timeRangeTimeout) {
clearTimeout(DayPilotScheduler.timeRangeTimeout);
DayPilotScheduler.timeRangeTimeout = null;
// disabled because it fired timeRangeDoubleClick twice
//calendar._onMaindDblClick(ev);
return;
}
DayPilotScheduler.rangeHold = range;
// must be cleared before dispatching
DayPilotScheduler.range = null;
var delayed = function(range) {
return function() {
DayPilotScheduler.timeRangeTimeout = null;
var shadow = calendar.elements.range2;
if (shadow && shadow.overlapping) {
calendar.clearSelection();
return;
}
calendar._timeRangeSelectedDispatchFromRange(range);
//calendar._timeRangeSelectedDispatch(sel.start, sel.end, sel.resource);
if (calendar.timeRangeSelectedHandling !== "Hold" && calendar.timeRangeSelectedHandling !== "HoldForever") {
doNothing();
//calendar.deleteRange();
}
else {
DayPilotScheduler.rangeHold = range;
}
};
};
//calendar.debug.message("gMouseUp");
//var sel = calendar._getSelection(range);
var rc = calendar._copyRange(range); // might not be necessary
if (!button.left) { // only left-click
DayPilotScheduler.timeRangeTimeout = null;
return;
}
if (calendar.timeRangeDoubleClickHandling === 'Disabled') {
delayed(rc)();
var ev = ev || window.event;
ev.cancelBubble = true;
return false; // trying to prevent onmaindclick
}
else {
DayPilotScheduler.timeRangeTimeout = setTimeout(delayed(rc), calendar.doubleClickTimeout); // 300 ms
}
}
else if (rowmoving.row) {
var calendar = rowmoving.calendar;
if (calendar) {
calendar._rowMoveDispatch();
}/*
else {
calendar._rowtools.resetMoving();
}*/
}
else if (linking.source) {
var calendar = linking.calendar;
calendar._linktools.clearShadow();
calendar._linktools.hideLinkpoints();
linking.source = null;
linking.calendar = null;
}
else if (DayPilotScheduler.splitting) {
var splitting = DayPilotScheduler.splitting;
splitting.cleanup();
DayPilotScheduler.splitting = null;
}
else if (DayPilotScheduler.rectangleSelect) {
var rect = DayPilotScheduler.rectangleSelect;
var calendar = rect.calendar;
var x = rect.x;
var y = rect.y;
var width = rect.width;
var height = rect.height;
var append = false;
var events = calendar._viewport.eventsInRectangle(x, y, width, height).map(function(item) {return item.event;});
if (typeof calendar.onRectangleEventSelect === "function") {
var args = {};
args.events = events;
args.append = false;
args.preventDefault = function() {
this.preventDefault.value = true;
};
calendar.onRectangleEventSelect(args);
if (args.preventDefault.value) {
calendar._rectangle.clear();
DayPilotScheduler.rectangleSelect = null;
return;
}
append = args.append;
}
if (!append) {
calendar.multiselect.clear(true);
}
events.each(function(e) {
calendar.multiselect.add(e, true);
});
calendar.multiselect.redraw();
setTimeout(function() { // needs to survive until onmaindclick is called
calendar._rectangle.clear();
DayPilotScheduler.rectangleSelect = null;
},0);
if (typeof calendar.onRectangleEventSelected === "function") {
var args = {};
args.events = events;
calendar.onRectangleEventSelected(args);
}
}
// clean up external drag helpers
if (DayPilotScheduler.drag) {
delete DayPilotScheduler.drag.event.part.external;
DayPilotScheduler.drag = null;
document.body.style.cursor = '';
}
if (DayPilotScheduler.gShadow) {
if (DayPilotScheduler.gShadow.source) {
var calendar = DayPilotScheduler.gShadow.source.event.calendar;
DayPilot.Util.removeClass(DayPilotScheduler.gShadow.source, calendar._prefixCssClass("_event_moving_source"));
}
document.body.removeChild(DayPilotScheduler.gShadow);
DayPilotScheduler.gShadow = null;
}
DayPilotScheduler.moveOffsetX = null; // clean for next external drag
DayPilotScheduler.moveDragStart = null;
};
// global shadow, external drag&drop
DayPilotScheduler.createGShadow = function(type) {
var shadow = document.createElement('div');
shadow.setAttribute('unselectable', 'on');
shadow.style.position = 'absolute';
shadow.style.width = '100px';
shadow.style.height = '20px';
shadow.style.border = '2px dotted #666666';
shadow.style.zIndex = 101;
shadow.style.pointerEvents = "none";
if (type === 'Fill') { // transparent shadow
shadow.style.backgroundColor = "#aaaaaa";
shadow.style.opacity = 0.5;
shadow.style.filter = "alpha(opacity=50)";
shadow.style.border = '2px solid #aaaaaa';
}
document.body.appendChild(shadow);
return shadow;
};
var rowmoving = {};
DayPilot.Global.rowmoving = rowmoving;
var linking = {};
DayPilot.Global.linking = linking;
// publish the API
// (backwards compatibility)
DayPilot.SchedulerVisible.dragStart = DayPilotScheduler.dragStart;
DayPilot.SchedulerVisible.dragStop = DayPilotScheduler.dragStop;
DayPilot.SchedulerVisible.Scheduler = DayPilotScheduler.Scheduler;
DayPilot.SchedulerVisible.globalHandlers = DayPilotScheduler.globalHandlers;
// jQuery plugin
if (typeof jQuery !== 'undefined') {
(function($) {
$.fn.daypilotScheduler = function(options) {
var first = null;
var j = this.each(function() {
if (this.daypilot) { // already initialized
return;
};
var daypilot = new DayPilot.Scheduler(this.id, options);
daypilot.init();
this.daypilot = daypilot;
if (!first) {
first = daypilot;
}
});
if (this.length === 1) {
return first;
}
else {
return j;
}
};
})(jQuery);
}
// AngularJS plugin
(function registerAngularModule() {
var app = DayPilot.am();
if (!app) {
return;
}
app.directive("daypilotScheduler", function() {
return {
"restrict": "E",
"template": "<div id='{{id}}'></div>",
"compile": function compile(element, attrs) {
element.replaceWith(this["template"].replace("{{id}}", attrs["id"]));
return function link(scope, element, attrs) {
var calendar = new DayPilot.Scheduler(element[0]);
calendar._angular.scope = scope;
calendar.init();
var oattr = attrs["id"];
if (oattr) {
scope[oattr] = calendar;
}
var watch = scope["$watch"];
watch.call(scope, attrs["daypilotConfig"], function (value, oldVal) {
for (var name in value) {
calendar[name] = value[name];
}
calendar.update();
}, true);
watch.call(scope, attrs["daypilotEvents"], function(value) {
//var calendar = element.data("calendar");
calendar.events.list = value;
calendar._update({"eventsOnly": true});
}, true);
};
}
};
});
})();
if (typeof Sys !== 'undefined' && Sys.Application && Sys.Application.notifyScriptLoaded) {
Sys.Application.notifyScriptLoaded();
}
})();