+++ /dev/null
-/*!
- * Ext JS Library 3.3.1
- * Copyright(c) 2006-2010 Sencha Inc.
- * licensing@sencha.com
- * http://www.sencha.com/license
- */
-Ext.ns('Ext.calendar');
-
- (function() {
- Ext.apply(Ext.calendar, {
- Date: {
- diffDays: function(start, end) {
- day = 1000 * 60 * 60 * 24;
- diff = end.clearTime(true).getTime() - start.clearTime(true).getTime();
- return Math.ceil(diff / day);
- },
-
- copyTime: function(fromDt, toDt) {
- var dt = toDt.clone();
- dt.setHours(
- fromDt.getHours(),
- fromDt.getMinutes(),
- fromDt.getSeconds(),
- fromDt.getMilliseconds());
-
- return dt;
- },
-
- compare: function(dt1, dt2, precise) {
- if (precise !== true) {
- dt1 = dt1.clone();
- dt1.setMilliseconds(0);
- dt2 = dt2.clone();
- dt2.setMilliseconds(0);
- }
- return dt2.getTime() - dt1.getTime();
- },
-
- // private helper fn
- maxOrMin: function(max) {
- var dt = (max ? 0: Number.MAX_VALUE),
- i = 0,
- args = arguments[1],
- ln = args.length;
- for (; i < ln; i++) {
- dt = Math[max ? 'max': 'min'](dt, args[i].getTime());
- }
- return new Date(dt);
- },
-
- max: function() {
- return this.maxOrMin.apply(this, [true, arguments]);
- },
-
- min: function() {
- return this.maxOrMin.apply(this, [false, arguments]);
- }
- }
- });
-})();/**
- * @class Ext.calendar.DayHeaderTemplate
- * @extends Ext.XTemplate
- * <p>This is the template used to render the all-day event container used in {@link Ext.calendar.DayView DayView} and
- * {@link Ext.calendar.WeekView WeekView}. Internally the majority of the layout logic is deferred to an instance of
- * {@link Ext.calendar.BoxLayoutTemplate}.</p>
- * <p>This template is automatically bound to the underlying event store by the
- * calendar components and expects records of type {@link Ext.calendar.EventRecord}.</p>
- * <p>Note that this template would not normally be used directly. Instead you would use the {@link Ext.calendar.DayViewTemplate}
- * that internally creates an instance of this template along with a {@link Ext.calendar.DayBodyTemplate}.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.DayHeaderTemplate = function(config){
-
- Ext.apply(this, config);
-
- this.allDayTpl = new Ext.calendar.BoxLayoutTemplate(config);
- this.allDayTpl.compile();
-
- Ext.calendar.DayHeaderTemplate.superclass.constructor.call(this,
- '<div class="ext-cal-hd-ct">',
- '<table class="ext-cal-hd-days-tbl" cellspacing="0" cellpadding="0">',
- '<tbody>',
- '<tr>',
- '<td class="ext-cal-gutter"></td>',
- '<td class="ext-cal-hd-days-td"><div class="ext-cal-hd-ad-inner">{allDayTpl}</div></td>',
- '<td class="ext-cal-gutter-rt"></td>',
- '</tr>',
- '</tobdy>',
- '</table>',
- '</div>'
- );
-};
-
-Ext.extend(Ext.calendar.DayHeaderTemplate, Ext.XTemplate, {
- applyTemplate : function(o){
- return Ext.calendar.DayHeaderTemplate.superclass.applyTemplate.call(this, {
- allDayTpl: this.allDayTpl.apply(o)
- });
- }
-});
-
-Ext.calendar.DayHeaderTemplate.prototype.apply = Ext.calendar.DayHeaderTemplate.prototype.applyTemplate;
-/**
- * @class Ext.calendar.DayBodyTemplate
- * @extends Ext.XTemplate
- * <p>This is the template used to render the scrolling body container used in {@link Ext.calendar.DayView DayView} and
- * {@link Ext.calendar.WeekView WeekView}. This template is automatically bound to the underlying event store by the
- * calendar components and expects records of type {@link Ext.calendar.EventRecord}.</p>
- * <p>Note that this template would not normally be used directly. Instead you would use the {@link Ext.calendar.DayViewTemplate}
- * that internally creates an instance of this template along with a {@link Ext.calendar.DayHeaderTemplate}.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.DayBodyTemplate = function(config){
-
- Ext.apply(this, config);
-
- Ext.calendar.DayBodyTemplate.superclass.constructor.call(this,
- '<table class="ext-cal-bg-tbl" cellspacing="0" cellpadding="0">',
- '<tbody>',
- '<tr height="1">',
- '<td class="ext-cal-gutter"></td>',
- '<td colspan="{dayCount}">',
- '<div class="ext-cal-bg-rows">',
- '<div class="ext-cal-bg-rows-inner">',
- '<tpl for="times">',
- '<div class="ext-cal-bg-row">',
- '<div class="ext-cal-bg-row-div ext-row-{[xindex]}"></div>',
- '</div>',
- '</tpl>',
- '</div>',
- '</div>',
- '</td>',
- '</tr>',
- '<tr>',
- '<td class="ext-cal-day-times">',
- '<tpl for="times">',
- '<div class="ext-cal-bg-row">',
- '<div class="ext-cal-day-time-inner">{.}</div>',
- '</div>',
- '</tpl>',
- '</td>',
- '<tpl for="days">',
- '<td class="ext-cal-day-col">',
- '<div class="ext-cal-day-col-inner">',
- '<div id="{[this.id]}-day-col-{.:date("Ymd")}" class="ext-cal-day-col-gutter"></div>',
- '</div>',
- '</td>',
- '</tpl>',
- '</tr>',
- '</tbody>',
- '</table>'
- );
-};
-
-Ext.extend(Ext.calendar.DayBodyTemplate, Ext.XTemplate, {
- // private
- applyTemplate : function(o){
- this.today = new Date().clearTime();
- this.dayCount = this.dayCount || 1;
-
- var i = 0, days = [],
- dt = o.viewStart.clone(),
- times;
-
- for(; i<this.dayCount; i++){
- days[i] = dt.add(Date.DAY, i);
- }
-
- times = [];
- dt = new Date().clearTime();
- for(i=0; i<24; i++){
- times.push(dt.format('ga'));
- dt = dt.add(Date.HOUR, 1);
- }
-
- return Ext.calendar.DayBodyTemplate.superclass.applyTemplate.call(this, {
- days: days,
- dayCount: days.length,
- times: times
- });
- }
-});
-
-Ext.calendar.DayBodyTemplate.prototype.apply = Ext.calendar.DayBodyTemplate.prototype.applyTemplate;
-/**
- * @class Ext.calendar.DayViewTemplate
- * @extends Ext.XTemplate
- * <p>This is the template used to render the all-day event container used in {@link Ext.calendar.DayView DayView} and
- * {@link Ext.calendar.WeekView WeekView}. Internally this class simply defers to instances of {@link Ext.calerndar.DayHeaderTemplate}
- * and {@link Ext.calerndar.DayBodyTemplate} to perform the actual rendering logic, but it also provides the overall calendar view
- * container that contains them both. As such this is the template that should be used when rendering day or week views.</p>
- * <p>This template is automatically bound to the underlying event store by the
- * calendar components and expects records of type {@link Ext.calendar.EventRecord}.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.DayViewTemplate = function(config){
-
- Ext.apply(this, config);
-
- this.headerTpl = new Ext.calendar.DayHeaderTemplate(config);
- this.headerTpl.compile();
-
- this.bodyTpl = new Ext.calendar.DayBodyTemplate(config);
- this.bodyTpl.compile();
-
- Ext.calendar.DayViewTemplate.superclass.constructor.call(this,
- '<div class="ext-cal-inner-ct">',
- '{headerTpl}',
- '{bodyTpl}',
- '</div>'
- );
-};
-
-Ext.extend(Ext.calendar.DayViewTemplate, Ext.XTemplate, {
- // private
- applyTemplate : function(o){
- return Ext.calendar.DayViewTemplate.superclass.applyTemplate.call(this, {
- headerTpl: this.headerTpl.apply(o),
- bodyTpl: this.bodyTpl.apply(o)
- });
- }
-});
-
-Ext.calendar.DayViewTemplate.prototype.apply = Ext.calendar.DayViewTemplate.prototype.applyTemplate;
-/**
- * @class Ext.calendar.BoxLayoutTemplate
- * @extends Ext.XTemplate
- * <p>This is the template used to render calendar views based on small day boxes within a non-scrolling container (currently
- * the {@link Ext.calendar.MonthView MonthView} and the all-day headers for {@link Ext.calendar.DayView DayView} and
- * {@link Ext.calendar.WeekView WeekView}. This template is automatically bound to the underlying event store by the
- * calendar components and expects records of type {@link Ext.calendar.EventRecord}.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.BoxLayoutTemplate = function(config){
-
- Ext.apply(this, config);
-
- var weekLinkTpl = this.showWeekLinks ? '<div id="{weekLinkId}" class="ext-cal-week-link">{weekNum}</div>' : '';
-
- Ext.calendar.BoxLayoutTemplate.superclass.constructor.call(this,
- '<tpl for="weeks">',
- '<div id="{[this.id]}-wk-{[xindex-1]}" class="ext-cal-wk-ct" style="top:{[this.getRowTop(xindex, xcount)]}%; height:{[this.getRowHeight(xcount)]}%;">',
- weekLinkTpl,
- '<table class="ext-cal-bg-tbl" cellpadding="0" cellspacing="0">',
- '<tbody>',
- '<tr>',
- '<tpl for=".">',
- '<td id="{[this.id]}-day-{date:date("Ymd")}" class="{cellCls}"> </td>',
- '</tpl>',
- '</tr>',
- '</tbody>',
- '</table>',
- '<table class="ext-cal-evt-tbl" cellpadding="0" cellspacing="0">',
- '<tbody>',
- '<tr>',
- '<tpl for=".">',
- '<td id="{[this.id]}-ev-day-{date:date("Ymd")}" class="{titleCls}"><div>{title}</div></td>',
- '</tpl>',
- '</tr>',
- '</tbody>',
- '</table>',
- '</div>',
- '</tpl>', {
- getRowTop: function(i, ln){
- return ((i-1)*(100/ln));
- },
- getRowHeight: function(ln){
- return 100/ln;
- }
- }
- );
-};
-
-Ext.extend(Ext.calendar.BoxLayoutTemplate, Ext.XTemplate, {
- // private
- applyTemplate : function(o){
-
- Ext.apply(this, o);
-
- var w = 0, title = '', first = true, isToday = false, showMonth = false, prevMonth = false, nextMonth = false,
- weeks = [[]],
- today = new Date().clearTime(),
- dt = this.viewStart.clone(),
- thisMonth = this.startDate.getMonth();
-
- for(; w < this.weekCount || this.weekCount == -1; w++){
- if(dt > this.viewEnd){
- break;
- }
- weeks[w] = [];
-
- for(var d = 0; d < this.dayCount; d++){
- isToday = dt.getTime() === today.getTime();
- showMonth = first || (dt.getDate() == 1);
- prevMonth = (dt.getMonth() < thisMonth) && this.weekCount == -1;
- nextMonth = (dt.getMonth() > thisMonth) && this.weekCount == -1;
-
- if(dt.getDay() == 1){
- // The ISO week format 'W' is relative to a Monday week start. If we
- // make this check on Sunday the week number will be off.
- weeks[w].weekNum = this.showWeekNumbers ? dt.format('W') : ' ';
- weeks[w].weekLinkId = 'ext-cal-week-'+dt.format('Ymd');
- }
-
- if(showMonth){
- if(isToday){
- title = this.getTodayText();
- }
- else{
- title = dt.format(this.dayCount == 1 ? 'l, F j, Y' : (first ? 'M j, Y' : 'M j'));
- }
- }
- else{
- var dayFmt = (w == 0 && this.showHeader !== true) ? 'D j' : 'j';
- title = isToday ? this.getTodayText() : dt.format(dayFmt);
- }
-
- weeks[w].push({
- title: title,
- date: dt.clone(),
- titleCls: 'ext-cal-dtitle ' + (isToday ? ' ext-cal-dtitle-today' : '') +
- (w==0 ? ' ext-cal-dtitle-first' : '') +
- (prevMonth ? ' ext-cal-dtitle-prev' : '') +
- (nextMonth ? ' ext-cal-dtitle-next' : ''),
- cellCls: 'ext-cal-day ' + (isToday ? ' ext-cal-day-today' : '') +
- (d==0 ? ' ext-cal-day-first' : '') +
- (prevMonth ? ' ext-cal-day-prev' : '') +
- (nextMonth ? ' ext-cal-day-next' : '')
- });
- dt = dt.add(Date.DAY, 1);
- first = false;
- }
- }
-
- return Ext.calendar.BoxLayoutTemplate.superclass.applyTemplate.call(this, {
- weeks: weeks
- });
- },
-
- // private
- getTodayText : function(){
- var dt = new Date().format('l, F j, Y'),
- todayText = this.showTodayText !== false ? this.todayText : '',
- timeText = this.showTime !== false ? ' <span id="'+this.id+'-clock" class="ext-cal-dtitle-time">' +
- new Date().format('g:i a') + '</span>' : '',
- separator = todayText.length > 0 || timeText.length > 0 ? ' — ' : '';
-
- if(this.dayCount == 1){
- return dt + separator + todayText + timeText;
- }
- fmt = this.weekCount == 1 ? 'D j' : 'j';
- return todayText.length > 0 ? todayText + timeText : new Date().format(fmt) + timeText;
- }
-});
-
-Ext.calendar.BoxLayoutTemplate.prototype.apply = Ext.calendar.BoxLayoutTemplate.prototype.applyTemplate;
-/**\r
- * @class Ext.calendar.MonthViewTemplate\r
- * @extends Ext.XTemplate\r
- * <p>This is the template used to render the {@link Ext.calendar.MonthView MonthView}. Internally this class defers to an\r
- * instance of {@link Ext.calerndar.BoxLayoutTemplate} to handle the inner layout rendering and adds containing elements around\r
- * that to form the month view.</p> \r
- * <p>This template is automatically bound to the underlying event store by the \r
- * calendar components and expects records of type {@link Ext.calendar.EventRecord}.</p>\r
- * @constructor\r
- * @param {Object} config The config object\r
- */\r
-Ext.calendar.MonthViewTemplate = function(config){\r
- \r
- Ext.apply(this, config);\r
- \r
- this.weekTpl = new Ext.calendar.BoxLayoutTemplate(config);\r
- this.weekTpl.compile();\r
- \r
- var weekLinkTpl = this.showWeekLinks ? '<div class="ext-cal-week-link-hd"> </div>' : '';\r
- \r
- Ext.calendar.MonthViewTemplate.superclass.constructor.call(this,\r
- '<div class="ext-cal-inner-ct {extraClasses}">',\r
- '<div class="ext-cal-hd-ct ext-cal-month-hd">',\r
- weekLinkTpl,\r
- '<table class="ext-cal-hd-days-tbl" cellpadding="0" cellspacing="0">',\r
- '<tbody>',\r
- '<tr>',\r
- '<tpl for="days">',\r
- '<th class="ext-cal-hd-day{[xindex==1 ? " ext-cal-day-first" : ""]}" title="{.:date("l, F j, Y")}">{.:date("D")}</th>',\r
- '</tpl>',\r
- '</tr>',\r
- '</tbody>',\r
- '</table>',\r
- '</div>',\r
- '<div class="ext-cal-body-ct">{weeks}</div>',\r
- '</div>'\r
- );\r
-};\r
-\r
-Ext.extend(Ext.calendar.MonthViewTemplate, Ext.XTemplate, {\r
- // private\r
- applyTemplate : function(o){\r
- var days = [],\r
- weeks = this.weekTpl.apply(o),\r
- dt = o.viewStart;\r
- \r
- for(var i = 0; i < 7; i++){\r
- days.push(dt.add(Date.DAY, i));\r
- }\r
- \r
- var extraClasses = this.showHeader === true ? '' : 'ext-cal-noheader';\r
- if(this.showWeekLinks){\r
- extraClasses += ' ext-cal-week-links';\r
- }\r
- \r
- return Ext.calendar.MonthViewTemplate.superclass.applyTemplate.call(this, {\r
- days: days,\r
- weeks: weeks,\r
- extraClasses: extraClasses \r
- });\r
- }\r
-});\r
-\r
-Ext.calendar.MonthViewTemplate.prototype.apply = Ext.calendar.MonthViewTemplate.prototype.applyTemplate;\r
-/**
- * @class Ext.dd.ScrollManager
- * <p>Provides automatic scrolling of overflow regions in the page during drag operations.</p>
- * <p>The ScrollManager configs will be used as the defaults for any scroll container registered with it,
- * but you can also override most of the configs per scroll container by adding a
- * <tt>ddScrollConfig</tt> object to the target element that contains these properties: {@link #hthresh},
- * {@link #vthresh}, {@link #increment} and {@link #frequency}. Example usage:
- * <pre><code>
-var el = Ext.get('scroll-ct');
-el.ddScrollConfig = {
- vthresh: 50,
- hthresh: -1,
- frequency: 100,
- increment: 200
-};
-Ext.dd.ScrollManager.register(el);
-</code></pre>
- * <b>Note: This class uses "Point Mode" and is untested in "Intersect Mode".</b>
- * @singleton
- */
-Ext.dd.ScrollManager = function() {
- var ddm = Ext.dd.DragDropMgr,
- els = {},
- dragEl = null,
- proc = {},
- onStop = function(e) {
- dragEl = null;
- clearProc();
- },
- triggerRefresh = function() {
- if (ddm.dragCurrent) {
- ddm.refreshCache(ddm.dragCurrent.groups);
- }
- },
- doScroll = function() {
- if (ddm.dragCurrent) {
- var dds = Ext.dd.ScrollManager,
- inc = proc.el.ddScrollConfig ? proc.el.ddScrollConfig.increment: dds.increment;
- if (!dds.animate) {
- if (proc.el.scroll(proc.dir, inc)) {
- triggerRefresh();
- }
- } else {
- proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
- }
- }
- },
- clearProc = function() {
- if (proc.id) {
- clearInterval(proc.id);
- }
- proc.id = 0;
- proc.el = null;
- proc.dir = "";
- },
- startProc = function(el, dir) {
- clearProc();
- proc.el = el;
- proc.dir = dir;
- var freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ?
- el.ddScrollConfig.frequency: Ext.dd.ScrollManager.frequency,
- group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup: undefined;
-
- if (group === undefined || ddm.dragCurrent.ddGroup == group) {
- proc.id = setInterval(doScroll, freq);
- }
- },
- onFire = function(e, isDrop) {
- if (isDrop || !ddm.dragCurrent) {
- return;
- }
- var dds = Ext.dd.ScrollManager;
- if (!dragEl || dragEl != ddm.dragCurrent) {
- dragEl = ddm.dragCurrent;
- // refresh regions on drag start
- dds.refreshCache();
- }
-
- var xy = Ext.lib.Event.getXY(e),
- pt = new Ext.lib.Point(xy[0], xy[1]),
- id,
- el,
- r,
- c;
- for (id in els) {
- if (els.hasOwnProperty(id)) {
- el = els[id];
- r = el._region;
- c = el.ddScrollConfig ? el.ddScrollConfig: dds;
- if (r && r.contains(pt) && el.isScrollable()) {
- if (r.bottom - pt.y <= c.vthresh) {
- if (proc.el != el) {
- startProc(el, "down");
- }
- return;
- } else if (r.right - pt.x <= c.hthresh) {
- if (proc.el != el) {
- startProc(el, "left");
- }
- return;
- } else if (pt.y - r.top <= c.vthresh) {
- if (proc.el != el) {
- startProc(el, "up");
- }
- return;
- } else if (pt.x - r.left <= c.hthresh) {
- if (proc.el != el) {
- startProc(el, "right");
- }
- return;
- }
- }
- }
- }
- clearProc();
- };
-
- ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
- ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
-
- return {
- /**
- * Registers new overflow element(s) to auto scroll
- * @param {Mixed/Array} el The id of or the element to be scrolled or an array of either
- */
- register: function(el) {
- if (Ext.isArray(el)) {
- var i = 0,
- len = el.length;
- for (; i < len; i++) {
- this.register(el[i]);
- }
- } else {
- el = Ext.get(el);
- els[el.id] = el;
- }
- },
-
- /**
- * Unregisters overflow element(s) so they are no longer scrolled
- * @param {Mixed/Array} el The id of or the element to be removed or an array of either
- */
- unregister: function(el) {
- if (Ext.isArray(el)) {
- var i = 0,
- len = el.length;
- for (; i < len; i++) {
- this.unregister(el[i]);
- }
- } else {
- el = Ext.get(el);
- delete els[el.id];
- }
- },
-
- /**
- * The number of pixels from the top or bottom edge of a container the pointer needs to be to
- * trigger scrolling (defaults to 25)
- * @type Number
- */
- vthresh: 25,
- /**
- * The number of pixels from the right or left edge of a container the pointer needs to be to
- * trigger scrolling (defaults to 25)
- * @type Number
- */
- hthresh: 25,
-
- /**
- * The number of pixels to scroll in each scroll increment (defaults to 50)
- * @type Number
- */
- increment: 100,
-
- /**
- * The frequency of scrolls in milliseconds (defaults to 500)
- * @type Number
- */
- frequency: 500,
-
- /**
- * True to animate the scroll (defaults to true)
- * @type Boolean
- */
- animate: true,
-
- /**
- * The animation duration in seconds -
- * MUST BE less than Ext.dd.ScrollManager.frequency! (defaults to .4)
- * @type Number
- */
- animDuration: 0.4,
-
- /**
- * Manually trigger a cache refresh.
- */
- refreshCache: function() {
- var id;
- for (id in els) {
- if (els.hasOwnProperty(id)) {
- if (typeof els[id] == 'object') {
- // for people extending the object prototype
- els[id]._region = els[id].getRegion();
- }
- }
- }
- }
- };
-}();/*
- * @class Ext.calendar.StatusProxy
- * A specialized drag proxy that supports a drop status icon, {@link Ext.Layer} styles and auto-repair. It also
- * contains a calendar-specific drag status message containing details about the dragged event's target drop date range.
- * This is the default drag proxy used by all calendar views.
- * @constructor
- * @param {Object} config
- */
-Ext.calendar.StatusProxy = function(config) {
- Ext.apply(this, config);
- this.id = this.id || Ext.id();
- this.el = new Ext.Layer({
- dh: {
- id: this.id,
- cls: 'ext-dd-drag-proxy x-dd-drag-proxy ' + this.dropNotAllowed,
- cn: [
- {
- cls: 'x-dd-drop-icon'
- },
- {
- cls: 'ext-dd-ghost-ct',
- cn: [
- {
- cls: 'x-dd-drag-ghost'
- },
- {
- cls: 'ext-dd-msg'
- }
- ]
- }
- ]
- },
- shadow: !config || config.shadow !== false
- });
- this.ghost = Ext.get(this.el.dom.childNodes[1].childNodes[0]);
- this.message = Ext.get(this.el.dom.childNodes[1].childNodes[1]);
- this.dropStatus = this.dropNotAllowed;
-};
-
-Ext.extend(Ext.calendar.StatusProxy, Ext.dd.StatusProxy, {
- /**
- * @cfg {String} moveEventCls
- * The CSS class to apply to the status element when an event is being dragged (defaults to 'ext-cal-dd-move').
- */
- moveEventCls: 'ext-cal-dd-move',
- /**
- * @cfg {String} addEventCls
- * The CSS class to apply to the status element when drop is not allowed (defaults to 'ext-cal-dd-add').
- */
- addEventCls: 'ext-cal-dd-add',
-
- // inherit docs
- update: function(html) {
- if (typeof html == 'string') {
- this.ghost.update(html);
- } else {
- this.ghost.update('');
- html.style.margin = '0';
- this.ghost.dom.appendChild(html);
- }
- var el = this.ghost.dom.firstChild;
- if (el) {
- Ext.fly(el).setStyle('float', 'none').setHeight('auto');
- Ext.getDom(el).id += '-ddproxy';
- }
- },
-
- /**
- * Update the calendar-specific drag status message without altering the ghost element.
- * @param {String} msg The new status message
- */
- updateMsg: function(msg) {
- this.message.update(msg);
- }
-});/*
- * Internal drag zone implementation for the calendar components. This provides base functionality
- * and is primarily for the month view -- DayViewDD adds day/week view-specific functionality.
- */
-Ext.calendar.DragZone = Ext.extend(Ext.dd.DragZone, {
- ddGroup: 'CalendarDD',
- eventSelector: '.ext-cal-evt',
-
- constructor: function(el, config) {
- if (!Ext.calendar._statusProxyInstance) {
- Ext.calendar._statusProxyInstance = new Ext.calendar.StatusProxy();
- }
- this.proxy = Ext.calendar._statusProxyInstance;
- Ext.calendar.DragZone.superclass.constructor.call(this, el, config);
- },
-
- getDragData: function(e) {
- // Check whether we are dragging on an event first
- var t = e.getTarget(this.eventSelector, 3);
- if (t) {
- var rec = this.view.getEventRecordFromEl(t);
- return {
- type: 'eventdrag',
- ddel: t,
- eventStart: rec.data[Ext.calendar.EventMappings.StartDate.name],
- eventEnd: rec.data[Ext.calendar.EventMappings.EndDate.name],
- proxy: this.proxy
- };
- }
-
- // If not dragging an event then we are dragging on
- // the calendar to add a new event
- t = this.view.getDayAt(e.getPageX(), e.getPageY());
- if (t.el) {
- return {
- type: 'caldrag',
- start: t.date,
- proxy: this.proxy
- };
- }
- return null;
- },
-
- onInitDrag: function(x, y) {
- if (this.dragData.ddel) {
- var ghost = this.dragData.ddel.cloneNode(true),
- child = Ext.fly(ghost).child('dl');
-
- Ext.fly(ghost).setWidth('auto');
-
- if (child) {
- // for IE/Opera
- child.setHeight('auto');
- }
- this.proxy.update(ghost);
- this.onStartDrag(x, y);
- }
- else if (this.dragData.start) {
- this.onStartDrag(x, y);
- }
- this.view.onInitDrag();
- return true;
- },
-
- afterRepair: function() {
- if (Ext.enableFx && this.dragData.ddel) {
- Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || 'c3daf9');
- }
- this.dragging = false;
- },
-
- getRepairXY: function(e) {
- if (this.dragData.ddel) {
- return Ext.Element.fly(this.dragData.ddel).getXY();
- }
- },
-
- afterInvalidDrop: function(e, id) {
- Ext.select('.ext-dd-shim').hide();
- }
-});
-
-/*
- * Internal drop zone implementation for the calendar components. This provides base functionality
- * and is primarily for the month view -- DayViewDD adds day/week view-specific functionality.
- */
-Ext.calendar.DropZone = Ext.extend(Ext.dd.DropZone, {
- ddGroup: 'CalendarDD',
- eventSelector: '.ext-cal-evt',
-
- // private
- shims: [],
-
- getTargetFromEvent: function(e) {
- var dragOffset = this.dragOffset || 0,
- y = e.getPageY() - dragOffset,
- d = this.view.getDayAt(e.getPageX(), y);
-
- return d.el ? d: null;
- },
-
- onNodeOver: function(n, dd, e, data) {
- var D = Ext.calendar.Date,
- start = data.type == 'eventdrag' ? n.date: D.min(data.start, n.date),
- end = data.type == 'eventdrag' ? n.date.add(Date.DAY, D.diffDays(data.eventStart, data.eventEnd)) :
- D.max(data.start, n.date);
-
- if (!this.dragStartDate || !this.dragEndDate || (D.diffDays(start, this.dragStartDate) != 0) || (D.diffDays(end, this.dragEndDate) != 0)) {
- this.dragStartDate = start;
- this.dragEndDate = end.clearTime().add(Date.DAY, 1).add(Date.MILLI, -1);
- this.shim(start, end);
-
- var range = start.format('n/j');
- if (D.diffDays(start, end) > 0) {
- range += '-' + end.format('n/j');
- }
- var msg = String.format(data.type == 'eventdrag' ? this.moveText: this.createText, range);
- data.proxy.updateMsg(msg);
- }
- return this.dropAllowed;
- },
-
- shim: function(start, end) {
- this.currWeek = -1;
- var dt = start.clone(),
- i = 0,
- shim,
- box,
- cnt = Ext.calendar.Date.diffDays(dt, end) + 1;
-
- Ext.each(this.shims,
- function(shim) {
- if (shim) {
- shim.isActive = false;
- }
- }
- );
-
- while (i++<cnt) {
- var dayEl = this.view.getDayEl(dt);
-
- // if the date is not in the current view ignore it (this
- // can happen when an event is dragged to the end of the
- // month so that it ends outside the view)
- if (dayEl) {
- var wk = this.view.getWeekIndex(dt);
- shim = this.shims[wk];
-
- if (!shim) {
- shim = this.createShim();
- this.shims[wk] = shim;
- }
- if (wk != this.currWeek) {
- shim.boxInfo = dayEl.getBox();
- this.currWeek = wk;
- }
- else {
- box = dayEl.getBox();
- shim.boxInfo.right = box.right;
- shim.boxInfo.width = box.right - shim.boxInfo.x;
- }
- shim.isActive = true;
- }
- dt = dt.add(Date.DAY, 1);
- }
-
- Ext.each(this.shims,
- function(shim) {
- if (shim) {
- if (shim.isActive) {
- shim.show();
- shim.setBox(shim.boxInfo);
- }
- else if (shim.isVisible()) {
- shim.hide();
- }
- }
- });
- },
-
- createShim: function() {
- if (!this.shimCt) {
- this.shimCt = Ext.get('ext-dd-shim-ct');
- if (!this.shimCt) {
- this.shimCt = document.createElement('div');
- this.shimCt.id = 'ext-dd-shim-ct';
- Ext.getBody().appendChild(this.shimCt);
- }
- }
- var el = document.createElement('div');
- el.className = 'ext-dd-shim';
- this.shimCt.appendChild(el);
-
- return new Ext.Layer({
- shadow: false,
- useDisplay: true,
- constrain: false
- },
- el);
- },
-
- clearShims: function() {
- Ext.each(this.shims,
- function(shim) {
- if (shim) {
- shim.hide();
- }
- });
- },
-
- onContainerOver: function(dd, e, data) {
- return this.dropAllowed;
- },
-
- onCalendarDragComplete: function() {
- delete this.dragStartDate;
- delete this.dragEndDate;
- this.clearShims();
- },
-
- onNodeDrop: function(n, dd, e, data) {
- if (n && data) {
- if (data.type == 'eventdrag') {
- var rec = this.view.getEventRecordFromEl(data.ddel),
- dt = Ext.calendar.Date.copyTime(rec.data[Ext.calendar.EventMappings.StartDate.name], n.date);
-
- this.view.onEventDrop(rec, dt);
- this.onCalendarDragComplete();
- return true;
- }
- if (data.type == 'caldrag') {
- this.view.onCalendarEndDrag(this.dragStartDate, this.dragEndDate,
- this.onCalendarDragComplete.createDelegate(this));
- //shims are NOT cleared here -- they stay visible until the handling
- //code calls the onCalendarDragComplete callback which hides them.
- return true;
- }
- }
- this.onCalendarDragComplete();
- return false;
- },
-
- onContainerDrop: function(dd, e, data) {
- this.onCalendarDragComplete();
- return false;
- },
-
- destroy: function() {
- Ext.calendar.DropZone.superclass.destroy.call(this);
- Ext.destroy(this.shimCt);
- }
-});
-
-/*
- * Internal drag zone implementation for the calendar day and week views.
- */
-Ext.calendar.DayViewDragZone = Ext.extend(Ext.calendar.DragZone, {
- ddGroup: 'DayViewDD',
- resizeSelector: '.ext-evt-rsz',
-
- getDragData: function(e) {
- var t = e.getTarget(this.resizeSelector, 2, true),
- p,
- rec;
- if (t) {
- p = t.parent(this.eventSelector);
- rec = this.view.getEventRecordFromEl(p);
-
- return {
- type: 'eventresize',
- ddel: p.dom,
- eventStart: rec.data[Ext.calendar.EventMappings.StartDate.name],
- eventEnd: rec.data[Ext.calendar.EventMappings.EndDate.name],
- proxy: this.proxy
- };
- }
- t = e.getTarget(this.eventSelector, 3);
- if (t) {
- rec = this.view.getEventRecordFromEl(t);
- return {
- type: 'eventdrag',
- ddel: t,
- eventStart: rec.data[Ext.calendar.EventMappings.StartDate.name],
- eventEnd: rec.data[Ext.calendar.EventMappings.EndDate.name],
- proxy: this.proxy
- };
- }
-
- // If not dragging/resizing an event then we are dragging on
- // the calendar to add a new event
- t = this.view.getDayAt(e.getPageX(), e.getPageY());
- if (t.el) {
- return {
- type: 'caldrag',
- dayInfo: t,
- proxy: this.proxy
- };
- }
- return null;
- }
-});
-
-/*
- * Internal drop zone implementation for the calendar day and week views.
- */
-Ext.calendar.DayViewDropZone = Ext.extend(Ext.calendar.DropZone, {
- ddGroup: 'DayViewDD',
-
- onNodeOver: function(n, dd, e, data) {
- var dt,
- box,
- endDt,
- text = this.createText,
- curr,
- start,
- end,
- evtEl,
- dayCol;
- if (data.type == 'caldrag') {
- if (!this.dragStartMarker) {
- // Since the container can scroll, this gets a little tricky.
- // There is no el in the DOM that we can measure by default since
- // the box is simply calculated from the original drag start (as opposed
- // to dragging or resizing the event where the orig event box is present).
- // To work around this we add a placeholder el into the DOM and give it
- // the original starting time's box so that we can grab its updated
- // box measurements as the underlying container scrolls up or down.
- // This placeholder is removed in onNodeDrop.
- this.dragStartMarker = n.el.parent().createChild({
- style: 'position:absolute;'
- });
- this.dragStartMarker.setBox(n.timeBox);
- this.dragCreateDt = n.date;
- }
- box = this.dragStartMarker.getBox();
- box.height = Math.ceil(Math.abs(e.xy[1] - box.y) / n.timeBox.height) * n.timeBox.height;
-
- if (e.xy[1] < box.y) {
- box.height += n.timeBox.height;
- box.y = box.y - box.height + n.timeBox.height;
- endDt = this.dragCreateDt.add(Date.MINUTE, 30);
- }
- else {
- n.date = n.date.add(Date.MINUTE, 30);
- }
- this.shim(this.dragCreateDt, box);
-
- curr = Ext.calendar.Date.copyTime(n.date, this.dragCreateDt);
- this.dragStartDate = Ext.calendar.Date.min(this.dragCreateDt, curr);
- this.dragEndDate = endDt || Ext.calendar.Date.max(this.dragCreateDt, curr);
-
- dt = this.dragStartDate.format('g:ia-') + this.dragEndDate.format('g:ia');
- }
- else {
- evtEl = Ext.get(data.ddel);
- dayCol = evtEl.parent().parent();
- box = evtEl.getBox();
-
- box.width = dayCol.getWidth();
-
- if (data.type == 'eventdrag') {
- if (this.dragOffset === undefined) {
- this.dragOffset = n.timeBox.y - box.y;
- box.y = n.timeBox.y - this.dragOffset;
- }
- else {
- box.y = n.timeBox.y;
- }
- dt = n.date.format('n/j g:ia');
- box.x = n.el.getLeft();
-
- this.shim(n.date, box);
- text = this.moveText;
- }
- if (data.type == 'eventresize') {
- if (!this.resizeDt) {
- this.resizeDt = n.date;
- }
- box.x = dayCol.getLeft();
- box.height = Math.ceil(Math.abs(e.xy[1] - box.y) / n.timeBox.height) * n.timeBox.height;
- if (e.xy[1] < box.y) {
- box.y -= box.height;
- }
- else {
- n.date = n.date.add(Date.MINUTE, 30);
- }
- this.shim(this.resizeDt, box);
-
- curr = Ext.calendar.Date.copyTime(n.date, this.resizeDt);
- start = Ext.calendar.Date.min(data.eventStart, curr);
- end = Ext.calendar.Date.max(data.eventStart, curr);
-
- data.resizeDates = {
- StartDate: start,
- EndDate: end
- };
- dt = start.format('g:ia-') + end.format('g:ia');
- text = this.resizeText;
- }
- }
-
- data.proxy.updateMsg(String.format(text, dt));
- return this.dropAllowed;
- },
-
- shim: function(dt, box) {
- Ext.each(this.shims,
- function(shim) {
- if (shim) {
- shim.isActive = false;
- shim.hide();
- }
- });
-
- var shim = this.shims[0];
- if (!shim) {
- shim = this.createShim();
- this.shims[0] = shim;
- }
-
- shim.isActive = true;
- shim.show();
- shim.setBox(box);
- },
-
- onNodeDrop: function(n, dd, e, data) {
- var rec;
- if (n && data) {
- if (data.type == 'eventdrag') {
- rec = this.view.getEventRecordFromEl(data.ddel);
- this.view.onEventDrop(rec, n.date);
- this.onCalendarDragComplete();
- delete this.dragOffset;
- return true;
- }
- if (data.type == 'eventresize') {
- rec = this.view.getEventRecordFromEl(data.ddel);
- this.view.onEventResize(rec, data.resizeDates);
- this.onCalendarDragComplete();
- delete this.resizeDt;
- return true;
- }
- if (data.type == 'caldrag') {
- Ext.destroy(this.dragStartMarker);
- delete this.dragStartMarker;
- delete this.dragCreateDt;
- this.view.onCalendarEndDrag(this.dragStartDate, this.dragEndDate,
- this.onCalendarDragComplete.createDelegate(this));
- //shims are NOT cleared here -- they stay visible until the handling
- //code calls the onCalendarDragComplete callback which hides them.
- return true;
- }
- }
- this.onCalendarDragComplete();
- return false;
- }
-});
-/**
- * @class Ext.calendar.EventMappings
- * @extends Object
- * A simple object that provides the field definitions for EventRecords so that they can be easily overridden.
- */
-Ext.calendar.EventMappings = {
- EventId: {
- name: 'EventId',
- mapping: 'id',
- type: 'int'
- },
- CalendarId: {
- name: 'CalendarId',
- mapping: 'cid',
- type: 'int'
- },
- Title: {
- name: 'Title',
- mapping: 'title',
- type: 'string'
- },
- StartDate: {
- name: 'StartDate',
- mapping: 'start',
- type: 'date',
- dateFormat: 'c'
- },
- EndDate: {
- name: 'EndDate',
- mapping: 'end',
- type: 'date',
- dateFormat: 'c'
- },
- Location: {
- name: 'Location',
- mapping: 'loc',
- type: 'string'
- },
- Notes: {
- name: 'Notes',
- mapping: 'notes',
- type: 'string'
- },
- Url: {
- name: 'Url',
- mapping: 'url',
- type: 'string'
- },
- IsAllDay: {
- name: 'IsAllDay',
- mapping: 'ad',
- type: 'boolean'
- },
- Reminder: {
- name: 'Reminder',
- mapping: 'rem',
- type: 'string'
- },
- IsNew: {
- name: 'IsNew',
- mapping: 'n',
- type: 'boolean'
- }
-};
-
-/**
- * @class Ext.calendar.EventRecord
- * @extends Ext.data.Record
- * <p>This is the {@link Ext.data.Record Record} specification for calendar event data used by the
- * {@link Ext.calendar.CalendarPanel CalendarPanel}'s underlying store. It can be overridden as
- * necessary to customize the fields supported by events, although the existing column names should
- * not be altered. If your model fields are named differently you should update the <b>mapping</b>
- * configs accordingly.</p>
- * <p>The only required fields when creating a new event record instance are StartDate and
- * EndDate. All other fields are either optional are will be defaulted if blank.</p>
- * <p>Here is a basic example for how to create a new record of this type:<pre><code>
-rec = new Ext.calendar.EventRecord({
- StartDate: '2101-01-12 12:00:00',
- EndDate: '2101-01-12 13:30:00',
- Title: 'My cool event',
- Notes: 'Some notes'
-});
-</code></pre>
- * If you have overridden any of the record's data mappings via the Ext.calendar.EventMappings object
- * you may need to set the values using this alternate syntax to ensure that the fields match up correctly:<pre><code>
-var M = Ext.calendar.EventMappings;
-
-rec = new Ext.calendar.EventRecord();
-rec.data[M.StartDate.name] = '2101-01-12 12:00:00';
-rec.data[M.EndDate.name] = '2101-01-12 13:30:00';
-rec.data[M.Title.name] = 'My cool event';
-rec.data[M.Notes.name] = 'Some notes';
-</code></pre>
- * @constructor
- * @param {Object} data (Optional) An object, the properties of which provide values for the new Record's
- * fields. If not specified the {@link Ext.data.Field#defaultValue defaultValue}
- * for each field will be assigned.
- * @param {Object} id (Optional) The id of the Record. The id is used by the
- * {@link Ext.data.Store} object which owns the Record to index its collection
- * of Records (therefore this id should be unique within each store). If an
- * id is not specified a {@link #phantom}
- * Record will be created with an {@link #Record.id automatically generated id}.
- */
- (function() {
- var M = Ext.calendar.EventMappings;
-
- Ext.calendar.EventRecord = Ext.data.Record.create([
- M.EventId,
- M.CalendarId,
- M.Title,
- M.StartDate,
- M.EndDate,
- M.Location,
- M.Notes,
- M.Url,
- M.IsAllDay,
- M.Reminder,
- M.IsNew
- ]);
-
- /**
- * Reconfigures the default record definition based on the current Ext.calendar.EventMappings object
- */
- Ext.calendar.EventRecord.reconfigure = function() {
- Ext.calendar.EventRecord = Ext.data.Record.create([
- M.EventId,
- M.CalendarId,
- M.Title,
- M.StartDate,
- M.EndDate,
- M.Location,
- M.Notes,
- M.Url,
- M.IsAllDay,
- M.Reminder,
- M.IsNew
- ]);
- };
-})();
-/*\r
- * This is the view used internally by the panel that displays overflow events in the\r
- * month view. Anytime a day cell cannot display all of its events, it automatically displays\r
- * a link at the bottom to view all events for that day. When clicked, a panel pops up that\r
- * uses this view to display the events for that day.\r
- */\r
-Ext.calendar.MonthDayDetailView = Ext.extend(Ext.BoxComponent, {\r
- initComponent: function() {\r
- Ext.calendar.CalendarView.superclass.initComponent.call(this);\r
-\r
- this.addEvents({\r
- eventsrendered: true\r
- });\r
-\r
- if (!this.el) {\r
- this.el = document.createElement('div');\r
- }\r
- },\r
-\r
- afterRender: function() {\r
- this.tpl = this.getTemplate();\r
-\r
- Ext.calendar.MonthDayDetailView.superclass.afterRender.call(this);\r
-\r
- this.el.on({\r
- 'click': this.view.onClick,\r
- 'mouseover': this.view.onMouseOver,\r
- 'mouseout': this.view.onMouseOut,\r
- scope: this.view\r
- });\r
- },\r
-\r
- getTemplate: function() {\r
- if (!this.tpl) {\r
- this.tpl = new Ext.XTemplate(\r
- '<div class="ext-cal-mdv x-unselectable">',\r
- '<table class="ext-cal-mvd-tbl" cellpadding="0" cellspacing="0">',\r
- '<tbody>',\r
- '<tpl for=".">',\r
- '<tr><td class="ext-cal-ev">{markup}</td></tr>',\r
- '</tpl>',\r
- '</tbody>',\r
- '</table>',\r
- '</div>'\r
- );\r
- }\r
- this.tpl.compile();\r
- return this.tpl;\r
- },\r
-\r
- update: function(dt) {\r
- this.date = dt;\r
- this.refresh();\r
- },\r
-\r
- refresh: function() {\r
- if (!this.rendered) {\r
- return;\r
- }\r
- var eventTpl = this.view.getEventTemplate(),\r
-\r
- templateData = [];\r
-\r
- evts = this.store.queryBy(function(rec) {\r
- var thisDt = this.date.clearTime(true).getTime(),\r
- recStart = rec.data[Ext.calendar.EventMappings.StartDate.name].clearTime(true).getTime(),\r
- startsOnDate = (thisDt == recStart),\r
- spansDate = false;\r
-\r
- if (!startsOnDate) {\r
- var recEnd = rec.data[Ext.calendar.EventMappings.EndDate.name].clearTime(true).getTime();\r
- spansDate = recStart < thisDt && recEnd >= thisDt;\r
- }\r
- return startsOnDate || spansDate;\r
- },\r
- this);\r
-\r
- evts.each(function(evt) {\r
- var item = evt.data,\r
- M = Ext.calendar.EventMappings;\r
-\r
- item._renderAsAllDay = item[M.IsAllDay.name] || Ext.calendar.Date.diffDays(item[M.StartDate.name], item[M.EndDate.name]) > 0;\r
- item.spanLeft = Ext.calendar.Date.diffDays(item[M.StartDate.name], this.date) > 0;\r
- item.spanRight = Ext.calendar.Date.diffDays(this.date, item[M.EndDate.name]) > 0;\r
- item.spanCls = (item.spanLeft ? (item.spanRight ? 'ext-cal-ev-spanboth':\r
- 'ext-cal-ev-spanleft') : (item.spanRight ? 'ext-cal-ev-spanright': ''));\r
-\r
- templateData.push({\r
- markup: eventTpl.apply(this.getTemplateEventData(item))\r
- });\r
- },\r
- this);\r
-\r
- this.tpl.overwrite(this.el, templateData);\r
- this.fireEvent('eventsrendered', this, this.date, evts.getCount());\r
- },\r
-\r
- getTemplateEventData: function(evt) {\r
- var data = this.view.getTemplateEventData(evt);\r
- data._elId = 'dtl-' + data._elId;\r
- return data;\r
- }\r
-});\r
-\r
-Ext.reg('monthdaydetailview', Ext.calendar.MonthDayDetailView);\r
-/**
- * @class Ext.calendar.CalendarPicker
- * @extends Ext.form.ComboBox
- * <p>A custom combo used for choosing from the list of available calendars to assign an event to.</p>
- * <p>This is pretty much a standard combo that is simply pre-configured for the options needed by the
- * calendar components. The default configs are as follows:<pre><code>
- fieldLabel: 'Calendar',
- valueField: 'CalendarId',
- displayField: 'Title',
- triggerAction: 'all',
- mode: 'local',
- forceSelection: true,
- width: 200
-</code></pre>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.CalendarPicker = Ext.extend(Ext.form.ComboBox, {
- fieldLabel: 'Calendar',
- valueField: 'CalendarId',
- displayField: 'Title',
- triggerAction: 'all',
- mode: 'local',
- forceSelection: true,
- width: 200,
-
- // private
- initComponent: function() {
- Ext.calendar.CalendarPicker.superclass.initComponent.call(this);
- this.tpl = this.tpl ||
- '<tpl for="."><div class="x-combo-list-item ext-color-{' + this.valueField +
- '}"><div class="ext-cal-picker-icon"> </div>{' + this.displayField + '}</div></tpl>';
- },
-
- // private
- afterRender: function() {
- Ext.calendar.CalendarPicker.superclass.afterRender.call(this);
-
- this.wrap = this.el.up('.x-form-field-wrap');
- this.wrap.addClass('ext-calendar-picker');
-
- this.icon = Ext.DomHelper.append(this.wrap, {
- tag: 'div',
- cls: 'ext-cal-picker-icon ext-cal-picker-mainicon'
- });
- },
-
- // inherited docs
- setValue: function(value) {
- this.wrap.removeClass('ext-color-' + this.getValue());
- if (!value && this.store !== undefined) {
- // always default to a valid calendar
- value = this.store.getAt(0).data.CalendarId;
- }
- Ext.calendar.CalendarPicker.superclass.setValue.call(this, value);
- this.wrap.addClass('ext-color-' + value);
- }
-});
-
-Ext.reg('calendarpicker', Ext.calendar.CalendarPicker);
-/*
- * This is an internal helper class for the calendar views and should not be overridden.
- * It is responsible for the base event rendering logic underlying all of the calendar views.
- */
-Ext.calendar.WeekEventRenderer = function() {
-
- var getEventRow = function(id, week, index) {
- var indexOffset = 1,
- //skip row with date #'s
- evtRow,
- wkRow = Ext.get(id + '-wk-' + week);
- if (wkRow) {
- var table = wkRow.child('.ext-cal-evt-tbl', true);
- evtRow = table.tBodies[0].childNodes[index + indexOffset];
- if (!evtRow) {
- evtRow = Ext.DomHelper.append(table.tBodies[0], '<tr></tr>');
- }
- }
- return Ext.get(evtRow);
- };
-
- return {
- render: function(o) {
- var w = 0,
- grid = o.eventGrid,
- dt = o.viewStart.clone(),
- eventTpl = o.tpl,
- max = o.maxEventsPerDay != undefined ? o.maxEventsPerDay: 999,
- weekCount = o.weekCount < 1 ? 6: o.weekCount,
- dayCount = o.weekCount == 1 ? o.dayCount: 7,
- cellCfg;
-
- for (; w < weekCount; w++) {
- if (!grid[w] || grid[w].length == 0) {
- // no events or span cells for the entire week
- if (weekCount == 1) {
- row = getEventRow(o.id, w, 0);
- cellCfg = {
- tag: 'td',
- cls: 'ext-cal-ev',
- id: o.id + '-empty-0-day-' + dt.format('Ymd'),
- html: ' '
- };
- if (dayCount > 1) {
- cellCfg.colspan = dayCount;
- }
- Ext.DomHelper.append(row, cellCfg);
- }
- dt = dt.add(Date.DAY, 7);
- } else {
- var row,
- d = 0,
- wk = grid[w],
- startOfWeek = dt.clone(),
- endOfWeek = startOfWeek.add(Date.DAY, dayCount).add(Date.MILLI, -1);
-
- for (; d < dayCount; d++) {
- if (wk[d]) {
- var ev = emptyCells = skipped = 0,
- day = wk[d],
- ct = day.length,
- evt;
-
- for (; ev < ct; ev++) {
- if (!day[ev]) {
- emptyCells++;
- continue;
- }
- if (emptyCells > 0 && ev - emptyCells < max) {
- row = getEventRow(o.id, w, ev - emptyCells);
- cellCfg = {
- tag: 'td',
- cls: 'ext-cal-ev',
- id: o.id + '-empty-' + ct + '-day-' + dt.format('Ymd')
- };
- if (emptyCells > 1 && max - ev > emptyCells) {
- cellCfg.rowspan = Math.min(emptyCells, max - ev);
- }
- Ext.DomHelper.append(row, cellCfg);
- emptyCells = 0;
- }
-
- if (ev >= max) {
- skipped++;
- continue;
- }
- evt = day[ev];
-
- if (!evt.isSpan || evt.isSpanStart) {
- //skip non-starting span cells
- var item = evt.data || evt.event.data;
- item._weekIndex = w;
- item._renderAsAllDay = item[Ext.calendar.EventMappings.IsAllDay.name] || evt.isSpanStart;
- item.spanLeft = item[Ext.calendar.EventMappings.StartDate.name].getTime() < startOfWeek.getTime();
- item.spanRight = item[Ext.calendar.EventMappings.EndDate.name].getTime() > endOfWeek.getTime();
- item.spanCls = (item.spanLeft ? (item.spanRight ? 'ext-cal-ev-spanboth':
- 'ext-cal-ev-spanleft') : (item.spanRight ? 'ext-cal-ev-spanright': ''));
-
- row = getEventRow(o.id, w, ev);
- cellCfg = {
- tag: 'td',
- cls: 'ext-cal-ev',
- cn: eventTpl.apply(o.templateDataFn(item))
- };
- var diff = Ext.calendar.Date.diffDays(dt, item[Ext.calendar.EventMappings.EndDate.name]) + 1,
- cspan = Math.min(diff, dayCount - d);
-
- if (cspan > 1) {
- cellCfg.colspan = cspan;
- }
- Ext.DomHelper.append(row, cellCfg);
- }
- }
- if (ev > max) {
- row = getEventRow(o.id, w, max);
- Ext.DomHelper.append(row, {
- tag: 'td',
- cls: 'ext-cal-ev-more',
- id: 'ext-cal-ev-more-' + dt.format('Ymd'),
- cn: {
- tag: 'a',
- html: '+' + skipped + ' more...'
- }
- });
- }
- if (ct < o.evtMaxCount[w]) {
- row = getEventRow(o.id, w, ct);
- if (row) {
- cellCfg = {
- tag: 'td',
- cls: 'ext-cal-ev',
- id: o.id + '-empty-' + (ct + 1) + '-day-' + dt.format('Ymd')
- };
- var rowspan = o.evtMaxCount[w] - ct;
- if (rowspan > 1) {
- cellCfg.rowspan = rowspan;
- }
- Ext.DomHelper.append(row, cellCfg);
- }
- }
- } else {
- row = getEventRow(o.id, w, 0);
- if (row) {
- cellCfg = {
- tag: 'td',
- cls: 'ext-cal-ev',
- id: o.id + '-empty-day-' + dt.format('Ymd')
- };
- if (o.evtMaxCount[w] > 1) {
- cellCfg.rowSpan = o.evtMaxCount[w];
- }
- Ext.DomHelper.append(row, cellCfg);
- }
- }
- dt = dt.add(Date.DAY, 1);
- }
- }
- }
- }
- };
-}();
-/**\r
- * @class Ext.calendar.CalendarView\r
- * @extends Ext.BoxComponent\r
- * <p>This is an abstract class that serves as the base for other calendar views. This class is not\r
- * intended to be directly instantiated.</p>\r
- * <p>When extending this class to create a custom calendar view, you must provide an implementation\r
- * for the <code>renderItems</code> method, as there is no default implementation for rendering events\r
- * The rendering logic is totally dependent on how the UI structures its data, which\r
- * is determined by the underlying UI template (this base class does not have a template).</p>\r
- * @constructor\r
- * @param {Object} config The config object\r
- */\r
-Ext.calendar.CalendarView = Ext.extend(Ext.BoxComponent, {\r
- /**\r
- * @cfg {Number} startDay\r
- * The 0-based index for the day on which the calendar week begins (0=Sunday, which is the default)\r
- */\r
- startDay: 0,\r
- /**\r
- * @cfg {Boolean} spansHavePriority\r
- * Allows switching between two different modes of rendering events that span multiple days. When true,\r
- * span events are always sorted first, possibly at the expense of start dates being out of order (e.g., \r
- * a span event that starts at 11am one day and spans into the next day would display before a non-spanning \r
- * event that starts at 10am, even though they would not be in date order). This can lead to more compact\r
- * layouts when there are many overlapping events. If false (the default), events will always sort by start date\r
- * first which can result in a less compact, but chronologically consistent layout.\r
- */\r
- spansHavePriority: false,\r
- /**\r
- * @cfg {Boolean} trackMouseOver\r
- * Whether or not the view tracks and responds to the browser mouseover event on contained elements (defaults to\r
- * true). If you don't need mouseover event highlighting you can disable this.\r
- */\r
- trackMouseOver: true,\r
- /**\r
- * @cfg {Boolean} enableFx\r
- * Determines whether or not visual effects for CRUD actions are enabled (defaults to true). If this is false\r
- * it will override any values for {@link #enableAddFx}, {@link #enableUpdateFx} or {@link enableRemoveFx} and\r
- * all animations will be disabled.\r
- */\r
- enableFx: true,\r
- /**\r
- * @cfg {Boolean} enableAddFx\r
- * True to enable a visual effect on adding a new event (the default), false to disable it. Note that if \r
- * {@link #enableFx} is false it will override this value. The specific effect that runs is defined in the\r
- * {@link #doAddFx} method.\r
- */\r
- enableAddFx: true,\r
- /**\r
- * @cfg {Boolean} enableUpdateFx\r
- * True to enable a visual effect on updating an event, false to disable it (the default). Note that if \r
- * {@link #enableFx} is false it will override this value. The specific effect that runs is defined in the\r
- * {@link #doUpdateFx} method.\r
- */\r
- enableUpdateFx: false,\r
- /**\r
- * @cfg {Boolean} enableRemoveFx\r
- * True to enable a visual effect on removing an event (the default), false to disable it. Note that if \r
- * {@link #enableFx} is false it will override this value. The specific effect that runs is defined in the\r
- * {@link #doRemoveFx} method.\r
- */\r
- enableRemoveFx: true,\r
- /**\r
- * @cfg {Boolean} enableDD\r
- * True to enable drag and drop in the calendar view (the default), false to disable it\r
- */\r
- enableDD: true,\r
- /**\r
- * @cfg {Boolean} monitorResize\r
- * True to monitor the browser's resize event (the default), false to ignore it. If the calendar view is rendered\r
- * into a fixed-size container this can be set to false. However, if the view can change dimensions (e.g., it's in \r
- * fit layout in a viewport or some other resizable container) it is very important that this config is true so that\r
- * any resize event propagates properly to all subcomponents and layouts get recalculated properly.\r
- */\r
- monitorResize: true,\r
- /**\r
- * @cfg {String} ddCreateEventText\r
- * The text to display inside the drag proxy while dragging over the calendar to create a new event (defaults to \r
- * 'Create event for {0}' where {0} is a date range supplied by the view)\r
- */\r
- ddCreateEventText: 'Create event for {0}',\r
- /**\r
- * @cfg {String} ddMoveEventText\r
- * The text to display inside the drag proxy while dragging an event to reposition it (defaults to \r
- * 'Move event to {0}' where {0} is the updated event start date/time supplied by the view)\r
- */\r
- ddMoveEventText: 'Move event to {0}',\r
- /**\r
- * @cfg {String} ddResizeEventText\r
- * The string displayed to the user in the drag proxy while dragging the resize handle of an event (defaults to \r
- * 'Update event to {0}' where {0} is the updated event start-end range supplied by the view). Note that \r
- * this text is only used in views\r
- * that allow resizing of events.\r
- */\r
- ddResizeEventText: 'Update event to {0}',\r
-\r
- //private properties -- do not override:\r
- weekCount: 1,\r
- dayCount: 1,\r
- eventSelector: '.ext-cal-evt',\r
- eventOverClass: 'ext-evt-over',\r
- eventElIdDelimiter: '-evt-',\r
- dayElIdDelimiter: '-day-',\r
-\r
- /**\r
- * Returns a string of HTML template markup to be used as the body portion of the event template created\r
- * by {@link #getEventTemplate}. This provdes the flexibility to customize what's in the body without\r
- * having to override the entire XTemplate. This string can include any valid {@link Ext.Template} code, and\r
- * any data tokens accessible to the containing event template can be referenced in this string.\r
- * @return {String} The body template string\r
- */\r
- getEventBodyMarkup: Ext.emptyFn,\r
- // must be implemented by a subclass\r
- /**\r
- * <p>Returns the XTemplate that is bound to the calendar's event store (it expects records of type\r
- * {@link Ext.calendar.EventRecord}) to populate the calendar views with events. Internally this method\r
- * by default generates different markup for browsers that support CSS border radius and those that don't.\r
- * This method can be overridden as needed to customize the markup generated.</p>\r
- * <p>Note that this method calls {@link #getEventBodyMarkup} to retrieve the body markup for events separately\r
- * from the surrounding container markup. This provdes the flexibility to customize what's in the body without\r
- * having to override the entire XTemplate. If you do override this method, you should make sure that your \r
- * overridden version also does the same.</p>\r
- * @return {Ext.XTemplate} The event XTemplate\r
- */\r
- getEventTemplate: Ext.emptyFn,\r
- // must be implemented by a subclass\r
- // private\r
- initComponent: function() {\r
- this.setStartDate(this.startDate || new Date());\r
-\r
- Ext.calendar.CalendarView.superclass.initComponent.call(this);\r
-\r
- this.addEvents({\r
- /**\r
- * @event eventsrendered\r
- * Fires after events are finished rendering in the view\r
- * @param {Ext.calendar.CalendarView} this \r
- */\r
- eventsrendered: true,\r
- /**\r
- * @event eventclick\r
- * Fires after the user clicks on an event element\r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was clicked on\r
- * @param {HTMLNode} el The DOM node that was clicked on\r
- */\r
- eventclick: true,\r
- /**\r
- * @event eventover\r
- * Fires anytime the mouse is over an event element\r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that the cursor is over\r
- * @param {HTMLNode} el The DOM node that is being moused over\r
- */\r
- eventover: true,\r
- /**\r
- * @event eventout\r
- * Fires anytime the mouse exits an event element\r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that the cursor exited\r
- * @param {HTMLNode} el The DOM node that was exited\r
- */\r
- eventout: true,\r
- /**\r
- * @event datechange\r
- * Fires after the start date of the view changes\r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Date} startDate The start date of the view (as explained in {@link #getStartDate}\r
- * @param {Date} viewStart The first displayed date in the view\r
- * @param {Date} viewEnd The last displayed date in the view\r
- */\r
- datechange: true,\r
- /**\r
- * @event rangeselect\r
- * Fires after the user drags on the calendar to select a range of dates/times in which to create an event\r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Object} dates An object containing the start (StartDate property) and end (EndDate property) dates selected\r
- * @param {Function} callback A callback function that MUST be called after the event handling is complete so that\r
- * the view is properly cleaned up (shim elements are persisted in the view while the user is prompted to handle the\r
- * range selection). The callback is already created in the proper scope, so it simply needs to be executed as a standard\r
- * function call (e.g., callback()).\r
- */\r
- rangeselect: true,\r
- /**\r
- * @event eventmove\r
- * Fires after an event element is dragged by the user and dropped in a new position\r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was moved with\r
- * updated start and end dates\r
- */\r
- eventmove: true,\r
- /**\r
- * @event initdrag\r
- * Fires when a drag operation is initiated in the view\r
- * @param {Ext.calendar.CalendarView} this\r
- */\r
- initdrag: true,\r
- /**\r
- * @event dayover\r
- * Fires while the mouse is over a day element \r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Date} dt The date that is being moused over\r
- * @param {Ext.Element} el The day Element that is being moused over\r
- */\r
- dayover: true,\r
- /**\r
- * @event dayout\r
- * Fires when the mouse exits a day element \r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Date} dt The date that is exited\r
- * @param {Ext.Element} el The day Element that is exited\r
- */\r
- dayout: true\r
- /*\r
- * @event eventdelete\r
- * Fires after an event element is deleted by the user. Not currently implemented directly at the view level -- currently \r
- * deletes only happen from one of the forms.\r
- * @param {Ext.calendar.CalendarView} this\r
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was deleted\r
- */\r
- //eventdelete: true\r
- });\r
- },\r
-\r
- // private\r
- afterRender: function() {\r
- Ext.calendar.CalendarView.superclass.afterRender.call(this);\r
-\r
- this.renderTemplate();\r
-\r
- if (this.store) {\r
- this.setStore(this.store, true);\r
- }\r
-\r
- this.el.on({\r
- 'mouseover': this.onMouseOver,\r
- 'mouseout': this.onMouseOut,\r
- 'click': this.onClick,\r
- 'resize': this.onResize,\r
- scope: this\r
- });\r
-\r
- this.el.unselectable();\r
-\r
- if (this.enableDD && this.initDD) {\r
- this.initDD();\r
- }\r
-\r
- this.on('eventsrendered', this.forceSize);\r
- this.forceSize.defer(100, this);\r
-\r
- },\r
-\r
- // private\r
- forceSize: function() {\r
- if (this.el && this.el.child) {\r
- var hd = this.el.child('.ext-cal-hd-ct'),\r
- bd = this.el.child('.ext-cal-body-ct');\r
-\r
- if (bd == null || hd == null) return;\r
-\r
- var headerHeight = hd.getHeight(),\r
- sz = this.el.parent().getSize();\r
-\r
- bd.setHeight(sz.height - headerHeight);\r
- }\r
- },\r
-\r
- refresh: function() {\r
- this.prepareData();\r
- this.renderTemplate();\r
- this.renderItems();\r
- },\r
-\r
- getWeekCount: function() {\r
- var days = Ext.calendar.Date.diffDays(this.viewStart, this.viewEnd);\r
- return Math.ceil(days / this.dayCount);\r
- },\r
-\r
- // private\r
- prepareData: function() {\r
- var lastInMonth = this.startDate.getLastDateOfMonth(),\r
- w = 0,\r
- row = 0,\r
- dt = this.viewStart.clone(),\r
- weeks = this.weekCount < 1 ? 6: this.weekCount;\r
-\r
- this.eventGrid = [[]];\r
- this.allDayGrid = [[]];\r
- this.evtMaxCount = [];\r
-\r
- var evtsInView = this.store.queryBy(function(rec) {\r
- return this.isEventVisible(rec.data);\r
- },\r
- this);\r
-\r
- for (; w < weeks; w++) {\r
- this.evtMaxCount[w] = 0;\r
- if (this.weekCount == -1 && dt > lastInMonth) {\r
- //current week is fully in next month so skip\r
- break;\r
- }\r
- this.eventGrid[w] = this.eventGrid[w] || [];\r
- this.allDayGrid[w] = this.allDayGrid[w] || [];\r
-\r
- for (d = 0; d < this.dayCount; d++) {\r
- if (evtsInView.getCount() > 0) {\r
- var evts = evtsInView.filterBy(function(rec) {\r
- var startsOnDate = (dt.getTime() == rec.data[Ext.calendar.EventMappings.StartDate.name].clearTime(true).getTime());\r
- var spansFromPrevView = (w == 0 && d == 0 && (dt > rec.data[Ext.calendar.EventMappings.StartDate.name]));\r
- return startsOnDate || spansFromPrevView;\r
- },\r
- this);\r
-\r
- this.sortEventRecordsForDay(evts);\r
- this.prepareEventGrid(evts, w, d);\r
- }\r
- dt = dt.add(Date.DAY, 1);\r
- }\r
- }\r
- this.currentWeekCount = w;\r
- },\r
-\r
- // private\r
- prepareEventGrid: function(evts, w, d) {\r
- var row = 0,\r
- dt = this.viewStart.clone(),\r
- max = this.maxEventsPerDay ? this.maxEventsPerDay: 999;\r
-\r
- evts.each(function(evt) {\r
- var M = Ext.calendar.EventMappings,\r
- days = Ext.calendar.Date.diffDays(\r
- Ext.calendar.Date.max(this.viewStart, evt.data[M.StartDate.name]),\r
- Ext.calendar.Date.min(this.viewEnd, evt.data[M.EndDate.name])) + 1;\r
-\r
- if (days > 1 || Ext.calendar.Date.diffDays(evt.data[M.StartDate.name], evt.data[M.EndDate.name]) > 1) {\r
- this.prepareEventGridSpans(evt, this.eventGrid, w, d, days);\r
- this.prepareEventGridSpans(evt, this.allDayGrid, w, d, days, true);\r
- } else {\r
- row = this.findEmptyRowIndex(w, d);\r
- this.eventGrid[w][d] = this.eventGrid[w][d] || [];\r
- this.eventGrid[w][d][row] = evt;\r
-\r
- if (evt.data[M.IsAllDay.name]) {\r
- row = this.findEmptyRowIndex(w, d, true);\r
- this.allDayGrid[w][d] = this.allDayGrid[w][d] || [];\r
- this.allDayGrid[w][d][row] = evt;\r
- }\r
- }\r
-\r
- if (this.evtMaxCount[w] < this.eventGrid[w][d].length) {\r
- this.evtMaxCount[w] = Math.min(max + 1, this.eventGrid[w][d].length);\r
- }\r
- return true;\r
- },\r
- this);\r
- },\r
-\r
- // private\r
- prepareEventGridSpans: function(evt, grid, w, d, days, allday) {\r
- // this event spans multiple days/weeks, so we have to preprocess\r
- // the events and store special span events as placeholders so that\r
- // the render routine can build the necessary TD spans correctly.\r
- var w1 = w,\r
- d1 = d,\r
- row = this.findEmptyRowIndex(w, d, allday),\r
- dt = this.viewStart.clone();\r
-\r
- var start = {\r
- event: evt,\r
- isSpan: true,\r
- isSpanStart: true,\r
- spanLeft: false,\r
- spanRight: (d == 6)\r
- };\r
- grid[w][d] = grid[w][d] || [];\r
- grid[w][d][row] = start;\r
-\r
- while (--days) {\r
- dt = dt.add(Date.DAY, 1);\r
- if (dt > this.viewEnd) {\r
- break;\r
- }\r
- if (++d1 > 6) {\r
- // reset counters to the next week\r
- d1 = 0;\r
- w1++;\r
- row = this.findEmptyRowIndex(w1, 0);\r
- }\r
- grid[w1] = grid[w1] || [];\r
- grid[w1][d1] = grid[w1][d1] || [];\r
-\r
- grid[w1][d1][row] = {\r
- event: evt,\r
- isSpan: true,\r
- isSpanStart: (d1 == 0),\r
- spanLeft: (w1 > w) && (d1 % 7 == 0),\r
- spanRight: (d1 == 6) && (days > 1)\r
- };\r
- }\r
- },\r
-\r
- // private\r
- findEmptyRowIndex: function(w, d, allday) {\r
- var grid = allday ? this.allDayGrid: this.eventGrid,\r
- day = grid[w] ? grid[w][d] || [] : [],\r
- i = 0,\r
- ln = day.length;\r
-\r
- for (; i < ln; i++) {\r
- if (day[i] == null) {\r
- return i;\r
- }\r
- }\r
- return ln;\r
- },\r
-\r
- // private\r
- renderTemplate: function() {\r
- if (this.tpl) {\r
- this.tpl.overwrite(this.el, this.getParams());\r
- this.lastRenderStart = this.viewStart.clone();\r
- this.lastRenderEnd = this.viewEnd.clone();\r
- }\r
- },\r
-\r
- disableStoreEvents: function() {\r
- this.monitorStoreEvents = false;\r
- },\r
-\r
- enableStoreEvents: function(refresh) {\r
- this.monitorStoreEvents = true;\r
- if (refresh === true) {\r
- this.refresh();\r
- }\r
- },\r
-\r
- // private\r
- onResize: function() {\r
- this.refresh();\r
- },\r
-\r
- // private\r
- onInitDrag: function() {\r
- this.fireEvent('initdrag', this);\r
- },\r
-\r
- // private\r
- onEventDrop: function(rec, dt) {\r
- if (Ext.calendar.Date.compare(rec.data[Ext.calendar.EventMappings.StartDate.name], dt) === 0) {\r
- // no changes\r
- return;\r
- }\r
- var diff = dt.getTime() - rec.data[Ext.calendar.EventMappings.StartDate.name].getTime();\r
- rec.set(Ext.calendar.EventMappings.StartDate.name, dt);\r
- rec.set(Ext.calendar.EventMappings.EndDate.name, rec.data[Ext.calendar.EventMappings.EndDate.name].add(Date.MILLI, diff));\r
-\r
- this.fireEvent('eventmove', this, rec);\r
- },\r
-\r
- // private\r
- onCalendarEndDrag: function(start, end, onComplete) {\r
- // set this flag for other event handlers that might conflict while we're waiting\r
- this.dragPending = true;\r
-\r
- // have to wait for the user to save or cancel before finalizing the dd interation\r
- var o = {};\r
- o[Ext.calendar.EventMappings.StartDate.name] = start;\r
- o[Ext.calendar.EventMappings.EndDate.name] = end;\r
-\r
- this.fireEvent('rangeselect', this, o, this.onCalendarEndDragComplete.createDelegate(this, [onComplete]));\r
- },\r
-\r
- // private\r
- onCalendarEndDragComplete: function(onComplete) {\r
- // callback for the drop zone to clean up\r
- onComplete();\r
- // clear flag for other events to resume normally\r
- this.dragPending = false;\r
- },\r
-\r
- // private\r
- onUpdate: function(ds, rec, operation) {\r
- if (this.monitorStoreEvents === false) {\r
- return;\r
- }\r
- if (operation == Ext.data.Record.COMMIT) {\r
- this.refresh();\r
- if (this.enableFx && this.enableUpdateFx) {\r
- this.doUpdateFx(this.getEventEls(rec.data[Ext.calendar.EventMappings.EventId.name]), {\r
- scope: this\r
- });\r
- }\r
- }\r
- },\r
-\r
-\r
- doUpdateFx: function(els, o) {\r
- this.highlightEvent(els, null, o);\r
- },\r
-\r
- // private\r
- onAdd: function(ds, records, index) {\r
- if (this.monitorStoreEvents === false) {\r
- return;\r
- }\r
- var rec = records[0];\r
- this.tempEventId = rec.id;\r
- this.refresh();\r
-\r
- if (this.enableFx && this.enableAddFx) {\r
- this.doAddFx(this.getEventEls(rec.data[Ext.calendar.EventMappings.EventId.name]), {\r
- scope: this\r
- });\r
- };\r
- },\r
-\r
- doAddFx: function(els, o) {\r
- els.fadeIn(Ext.apply(o, {\r
- duration: 2\r
- }));\r
- },\r
-\r
- // private\r
- onRemove: function(ds, rec) {\r
- if (this.monitorStoreEvents === false) {\r
- return;\r
- }\r
- if (this.enableFx && this.enableRemoveFx) {\r
- this.doRemoveFx(this.getEventEls(rec.data[Ext.calendar.EventMappings.EventId.name]), {\r
- remove: true,\r
- scope: this,\r
- callback: this.refresh\r
- });\r
- }\r
- else {\r
- this.getEventEls(rec.data[Ext.calendar.EventMappings.EventId.name]).remove();\r
- this.refresh();\r
- }\r
- },\r
-\r
- doRemoveFx: function(els, o) {\r
- els.fadeOut(o);\r
- },\r
-\r
- /**\r
- * Visually highlights an event using {@link Ext.Fx#highlight} config options.\r
- * If {@link #highlightEventActions} is false this method will have no effect.\r
- * @param {Ext.CompositeElement} els The element(s) to highlight\r
- * @param {Object} color (optional) The highlight color. Should be a 6 char hex \r
- * color without the leading # (defaults to yellow: 'ffff9c')\r
- * @param {Object} o (optional) Object literal with any of the {@link Ext.Fx} config \r
- * options. See {@link Ext.Fx#highlight} for usage examples.\r
- */\r
- highlightEvent: function(els, color, o) {\r
- if (this.enableFx) {\r
- var c;\r
- ! (Ext.isIE || Ext.isOpera) ?\r
- els.highlight(color, o) :\r
- // Fun IE/Opera handling:\r
- els.each(function(el) {\r
- el.highlight(color, Ext.applyIf({\r
- attr: 'color'\r
- },\r
- o));\r
- c = el.child('.ext-cal-evm');\r
- if (c) {\r
- c.highlight(color, o);\r
- }\r
- },\r
- this);\r
- }\r
- },\r
-\r
- /**\r
- * Retrieve an Event object's id from its corresponding node in the DOM.\r
- * @param {String/Element/HTMLElement} el An {@link Ext.Element}, DOM node or id\r
- */\r
- getEventIdFromEl: function(el) {\r
- el = Ext.get(el);\r
- var id = el.id.split(this.eventElIdDelimiter)[1];\r
- if (id.indexOf('-') > -1) {\r
- //This id has the index of the week it is rendered in as the suffix.\r
- //This allows events that span across weeks to still have reproducibly-unique DOM ids.\r
- id = id.split('-')[0];\r
- }\r
- return id;\r
- },\r
-\r
- // private\r
- getEventId: function(eventId) {\r
- if (eventId === undefined && this.tempEventId) {\r
- eventId = this.tempEventId;\r
- }\r
- return eventId;\r
- },\r
-\r
- /**\r
- * \r
- * @param {String} eventId\r
- * @param {Boolean} forSelect\r
- * @return {String} The selector class\r
- */\r
- getEventSelectorCls: function(eventId, forSelect) {\r
- var prefix = forSelect ? '.': '';\r
- return prefix + this.id + this.eventElIdDelimiter + this.getEventId(eventId);\r
- },\r
-\r
- /**\r
- * \r
- * @param {String} eventId\r
- * @return {Ext.CompositeElement} The matching CompositeElement of nodes\r
- * that comprise the rendered event. Any event that spans across a view \r
- * boundary will contain more than one internal Element.\r
- */\r
- getEventEls: function(eventId) {\r
- var els = Ext.select(this.getEventSelectorCls(this.getEventId(eventId), true), false, this.el.id);\r
- return new Ext.CompositeElement(els);\r
- },\r
-\r
- /**\r
- * Returns true if the view is currently displaying today's date, else false.\r
- * @return {Boolean} True or false\r
- */\r
- isToday: function() {\r
- var today = new Date().clearTime().getTime();\r
- return this.viewStart.getTime() <= today && this.viewEnd.getTime() >= today;\r
- },\r
-\r
- // private\r
- onDataChanged: function(store) {\r
- this.refresh();\r
- },\r
-\r
- // private\r
- isEventVisible: function(evt) {\r
- var start = this.viewStart.getTime(),\r
- end = this.viewEnd.getTime(),\r
- M = Ext.calendar.EventMappings,\r
- evStart = (evt.data ? evt.data[M.StartDate.name] : evt[M.StartDate.name]).getTime(),\r
- evEnd = (evt.data ? evt.data[M.EndDate.name] : evt[M.EndDate.name]).add(Date.SECOND, -1).getTime(),\r
-\r
- startsInRange = (evStart >= start && evStart <= end),\r
- endsInRange = (evEnd >= start && evEnd <= end),\r
- spansRange = (evStart < start && evEnd > end);\r
-\r
- return (startsInRange || endsInRange || spansRange);\r
- },\r
-\r
- // private\r
- isOverlapping: function(evt1, evt2) {\r
- var ev1 = evt1.data ? evt1.data: evt1,\r
- ev2 = evt2.data ? evt2.data: evt2,\r
- M = Ext.calendar.EventMappings,\r
- start1 = ev1[M.StartDate.name].getTime(),\r
- end1 = ev1[M.EndDate.name].add(Date.SECOND, -1).getTime(),\r
- start2 = ev2[M.StartDate.name].getTime(),\r
- end2 = ev2[M.EndDate.name].add(Date.SECOND, -1).getTime();\r
-\r
- if (end1 < start1) {\r
- end1 = start1;\r
- }\r
- if (end2 < start2) {\r
- end2 = start2;\r
- }\r
-\r
- var ev1startsInEv2 = (start1 >= start2 && start1 <= end2),\r
- ev1EndsInEv2 = (end1 >= start2 && end1 <= end2),\r
- ev1SpansEv2 = (start1 < start2 && end1 > end2);\r
-\r
- return (ev1startsInEv2 || ev1EndsInEv2 || ev1SpansEv2);\r
- },\r
-\r
- getDayEl: function(dt) {\r
- return Ext.get(this.getDayId(dt));\r
- },\r
-\r
- getDayId: function(dt) {\r
- if (Ext.isDate(dt)) {\r
- dt = dt.format('Ymd');\r
- }\r
- return this.id + this.dayElIdDelimiter + dt;\r
- },\r
-\r
- /**\r
- * Returns the start date of the view, as set by {@link #setStartDate}. Note that this may not \r
- * be the first date displayed in the rendered calendar -- to get the start and end dates displayed\r
- * to the user use {@link #getViewBounds}.\r
- * @return {Date} The start date\r
- */\r
- getStartDate: function() {\r
- return this.startDate;\r
- },\r
-\r
- /**\r
- * Sets the start date used to calculate the view boundaries to display. The displayed view will be the \r
- * earliest and latest dates that match the view requirements and contain the date passed to this function.\r
- * @param {Date} dt The date used to calculate the new view boundaries\r
- */\r
- setStartDate: function(start, refresh) {\r
- this.startDate = start.clearTime();\r
- this.setViewBounds(start);\r
- this.store.load({\r
- params: {\r
- start: this.viewStart.format('m-d-Y'),\r
- end: this.viewEnd.format('m-d-Y')\r
- }\r
- });\r
- if (refresh === true) {\r
- this.refresh();\r
- }\r
- this.fireEvent('datechange', this, this.startDate, this.viewStart, this.viewEnd);\r
- },\r
-\r
- // private\r
- setViewBounds: function(startDate) {\r
- var start = startDate || this.startDate,\r
- offset = start.getDay() - this.startDay;\r
-\r
- switch (this.weekCount) {\r
- case 0:\r
- case 1:\r
- this.viewStart = this.dayCount < 7 ? start: start.add(Date.DAY, -offset).clearTime(true);\r
- this.viewEnd = this.viewStart.add(Date.DAY, this.dayCount || 7).add(Date.SECOND, -1);\r
- return;\r
-\r
- case - 1:\r
- // auto by month\r
- start = start.getFirstDateOfMonth();\r
- offset = start.getDay() - this.startDay;\r
- if (offset < 0) {\r
- offset += 7;\r
- }\r
- this.viewStart = start.add(Date.DAY, -offset).clearTime(true);\r
-\r
- // start from current month start, not view start:\r
- var end = start.add(Date.MONTH, 1).add(Date.SECOND, -1);\r
- // fill out to the end of the week:\r
- this.viewEnd = end.add(Date.DAY, 6 - end.getDay());\r
- return;\r
-\r
- default:\r
- this.viewStart = start.add(Date.DAY, -offset).clearTime(true);\r
- this.viewEnd = this.viewStart.add(Date.DAY, this.weekCount * 7).add(Date.SECOND, -1);\r
- }\r
- },\r
-\r
- // private\r
- getViewBounds: function() {\r
- return {\r
- start: this.viewStart,\r
- end: this.viewEnd\r
- };\r
- },\r
-\r
- /* private\r
- * Sort events for a single day for display in the calendar. This sorts allday\r
- * events first, then non-allday events are sorted either based on event start\r
- * priority or span priority based on the value of {@link #spansHavePriority} \r
- * (defaults to event start priority).\r
- * @param {MixedCollection} evts A {@link Ext.util.MixedCollection MixedCollection} \r
- * of {@link #Ext.calendar.EventRecord EventRecord} objects\r
- */\r
- sortEventRecordsForDay: function(evts) {\r
- if (evts.length < 2) {\r
- return;\r
- }\r
- evts.sort('ASC',\r
- function(evtA, evtB) {\r
- var a = evtA.data,\r
- b = evtB.data,\r
- M = Ext.calendar.EventMappings;\r
-\r
- // Always sort all day events before anything else\r
- if (a[M.IsAllDay.name]) {\r
- return - 1;\r
- }\r
- else if (b[M.IsAllDay.name]) {\r
- return 1;\r
- }\r
- if (this.spansHavePriority) {\r
- // This logic always weights span events higher than non-span events\r
- // (at the possible expense of start time order). This seems to\r
- // be the approach used by Google calendar and can lead to a more\r
- // visually appealing layout in complex cases, but event order is\r
- // not guaranteed to be consistent.\r
- var diff = Ext.calendar.Date.diffDays;\r
- if (diff(a[M.StartDate.name], a[M.EndDate.name]) > 0) {\r
- if (diff(b[M.StartDate.name], b[M.EndDate.name]) > 0) {\r
- // Both events are multi-day\r
- if (a[M.StartDate.name].getTime() == b[M.StartDate.name].getTime()) {\r
- // If both events start at the same time, sort the one\r
- // that ends later (potentially longer span bar) first\r
- return b[M.EndDate.name].getTime() - a[M.EndDate.name].getTime();\r
- }\r
- return a[M.StartDate.name].getTime() - b[M.StartDate.name].getTime();\r
- }\r
- return - 1;\r
- }\r
- else if (diff(b[M.StartDate.name], b[M.EndDate.name]) > 0) {\r
- return 1;\r
- }\r
- return a[M.StartDate.name].getTime() - b[M.StartDate.name].getTime();\r
- }\r
- else {\r
- // Doing this allows span and non-span events to intermingle but\r
- // remain sorted sequentially by start time. This seems more proper\r
- // but can make for a less visually-compact layout when there are\r
- // many such events mixed together closely on the calendar.\r
- return a[M.StartDate.name].getTime() - b[M.StartDate.name].getTime();\r
- }\r
- }.createDelegate(this));\r
- },\r
-\r
- /**\r
- * Updates the view to contain the passed date\r
- * @param {Date} dt The date to display\r
- */\r
- moveTo: function(dt, noRefresh) {\r
- if (Ext.isDate(dt)) {\r
- this.setStartDate(dt);\r
- if (noRefresh !== false) {\r
- this.refresh();\r
- }\r
- return this.startDate;\r
- }\r
- return dt;\r
- },\r
-\r
- /**\r
- * Updates the view to the next consecutive date(s)\r
- */\r
- moveNext: function(noRefresh) {\r
- return this.moveTo(this.viewEnd.add(Date.DAY, 1));\r
- },\r
-\r
- /**\r
- * Updates the view to the previous consecutive date(s)\r
- */\r
- movePrev: function(noRefresh) {\r
- var days = Ext.calendar.Date.diffDays(this.viewStart, this.viewEnd) + 1;\r
- return this.moveDays( - days, noRefresh);\r
- },\r
-\r
- /**\r
- * Shifts the view by the passed number of months relative to the currently set date\r
- * @param {Number} value The number of months (positive or negative) by which to shift the view\r
- */\r
- moveMonths: function(value, noRefresh) {\r
- return this.moveTo(this.startDate.add(Date.MONTH, value), noRefresh);\r
- },\r
-\r
- /**\r
- * Shifts the view by the passed number of weeks relative to the currently set date\r
- * @param {Number} value The number of weeks (positive or negative) by which to shift the view\r
- */\r
- moveWeeks: function(value, noRefresh) {\r
- return this.moveTo(this.startDate.add(Date.DAY, value * 7), noRefresh);\r
- },\r
-\r
- /**\r
- * Shifts the view by the passed number of days relative to the currently set date\r
- * @param {Number} value The number of days (positive or negative) by which to shift the view\r
- */\r
- moveDays: function(value, noRefresh) {\r
- return this.moveTo(this.startDate.add(Date.DAY, value), noRefresh);\r
- },\r
-\r
- /**\r
- * Updates the view to show today\r
- */\r
- moveToday: function(noRefresh) {\r
- return this.moveTo(new Date(), noRefresh);\r
- },\r
-\r
- /**\r
- * Sets the event store used by the calendar to display {@link Ext.calendar.EventRecord events}.\r
- * @param {Ext.data.Store} store\r
- */\r
- setStore: function(store, initial) {\r
- if (!initial && this.store) {\r
- this.store.un("datachanged", this.onDataChanged, this);\r
- this.store.un("add", this.onAdd, this);\r
- this.store.un("remove", this.onRemove, this);\r
- this.store.un("update", this.onUpdate, this);\r
- this.store.un("clear", this.refresh, this);\r
- }\r
- if (store) {\r
- store.on("datachanged", this.onDataChanged, this);\r
- store.on("add", this.onAdd, this);\r
- store.on("remove", this.onRemove, this);\r
- store.on("update", this.onUpdate, this);\r
- store.on("clear", this.refresh, this);\r
- }\r
- this.store = store;\r
- if (store && store.getCount() > 0) {\r
- this.refresh();\r
- }\r
- },\r
-\r
- getEventRecord: function(id) {\r
- var idx = this.store.find(Ext.calendar.EventMappings.EventId.name, id);\r
- return this.store.getAt(idx);\r
- },\r
-\r
- getEventRecordFromEl: function(el) {\r
- return this.getEventRecord(this.getEventIdFromEl(el));\r
- },\r
-\r
- // private\r
- getParams: function() {\r
- return {\r
- viewStart: this.viewStart,\r
- viewEnd: this.viewEnd,\r
- startDate: this.startDate,\r
- dayCount: this.dayCount,\r
- weekCount: this.weekCount,\r
- title: this.getTitle()\r
- };\r
- },\r
-\r
- getTitle: function() {\r
- return this.startDate.format('F Y');\r
- },\r
-\r
- /*\r
- * Shared click handling. Each specific view also provides view-specific\r
- * click handling that calls this first. This method returns true if it\r
- * can handle the click (and so the subclass should ignore it) else false.\r
- */\r
- onClick: function(e, t) {\r
- var el = e.getTarget(this.eventSelector, 5);\r
- if (el) {\r
- var id = this.getEventIdFromEl(el);\r
- this.fireEvent('eventclick', this, this.getEventRecord(id), el);\r
- return true;\r
- }\r
- },\r
-\r
- // private\r
- onMouseOver: function(e, t) {\r
- if (this.trackMouseOver !== false && (this.dragZone == undefined || !this.dragZone.dragging)) {\r
- if (!this.handleEventMouseEvent(e, t, 'over')) {\r
- this.handleDayMouseEvent(e, t, 'over');\r
- }\r
- }\r
- },\r
-\r
- // private\r
- onMouseOut: function(e, t) {\r
- if (this.trackMouseOver !== false && (this.dragZone == undefined || !this.dragZone.dragging)) {\r
- if (!this.handleEventMouseEvent(e, t, 'out')) {\r
- this.handleDayMouseEvent(e, t, 'out');\r
- }\r
- }\r
- },\r
-\r
- // private\r
- handleEventMouseEvent: function(e, t, type) {\r
- var el = e.getTarget(this.eventSelector, 5, true),\r
- rel,\r
- els,\r
- evtId;\r
- if (el) {\r
- rel = Ext.get(e.getRelatedTarget());\r
- if (el == rel || el.contains(rel)) {\r
- return true;\r
- }\r
-\r
- evtId = this.getEventIdFromEl(el);\r
-\r
- if (this.eventOverClass != '') {\r
- els = this.getEventEls(evtId);\r
- els[type == 'over' ? 'addClass': 'removeClass'](this.eventOverClass);\r
- }\r
- this.fireEvent('event' + type, this, this.getEventRecord(evtId), el);\r
- return true;\r
- }\r
- return false;\r
- },\r
-\r
- // private\r
- getDateFromId: function(id, delim) {\r
- var parts = id.split(delim);\r
- return parts[parts.length - 1];\r
- },\r
-\r
- // private\r
- handleDayMouseEvent: function(e, t, type) {\r
- t = e.getTarget('td', 3);\r
- if (t) {\r
- if (t.id && t.id.indexOf(this.dayElIdDelimiter) > -1) {\r
- var dt = this.getDateFromId(t.id, this.dayElIdDelimiter),\r
- rel = Ext.get(e.getRelatedTarget()),\r
- relTD,\r
- relDate;\r
-\r
- if (rel) {\r
- relTD = rel.is('td') ? rel: rel.up('td', 3);\r
- relDate = relTD && relTD.id ? this.getDateFromId(relTD.id, this.dayElIdDelimiter) : '';\r
- }\r
- if (!rel || dt != relDate) {\r
- var el = this.getDayEl(dt);\r
- if (el && this.dayOverClass != '') {\r
- el[type == 'over' ? 'addClass': 'removeClass'](this.dayOverClass);\r
- }\r
- this.fireEvent('day' + type, this, Date.parseDate(dt, "Ymd"), el);\r
- }\r
- }\r
- }\r
- },\r
-\r
- // private\r
- renderItems: function() {\r
- throw 'This method must be implemented by a subclass';\r
- }\r
-});\r
-/**\r
- * @class Ext.calendar.MonthView\r
- * @extends Ext.calendar.CalendarView\r
- * <p>Displays a calendar view by month. This class does not usually need ot be used directly as you can\r
- * use a {@link Ext.calendar.CalendarPanel CalendarPanel} to manage multiple calendar views at once including\r
- * the month view.</p>\r
- * @constructor\r
- * @param {Object} config The config object\r
- */\r
-Ext.calendar.MonthView = Ext.extend(Ext.calendar.CalendarView, {\r
- /**\r
- * @cfg {Boolean} showTime\r
- * True to display the current time in today's box in the calendar, false to not display it (defautls to true)\r
- */\r
- showTime: true,\r
- /**\r
- * @cfg {Boolean} showTodayText\r
- * True to display the {@link #todayText} string in today's box in the calendar, false to not display it (defautls to true)\r
- */\r
- showTodayText: true,\r
- /**\r
- * @cfg {String} todayText\r
- * The text to display in the current day's box in the calendar when {@link #showTodayText} is true (defaults to 'Today')\r
- */\r
- todayText: 'Today',\r
- /**\r
- * @cfg {Boolean} showHeader\r
- * True to display a header beneath the navigation bar containing the week names above each week's column, false not to \r
- * show it and instead display the week names in the first row of days in the calendar (defaults to false).\r
- */\r
- showHeader: false,\r
- /**\r
- * @cfg {Boolean} showWeekLinks\r
- * True to display an extra column before the first day in the calendar that links to the {@link Ext.calendar.WeekView view}\r
- * for each individual week, false to not show it (defaults to false). If true, the week links can also contain the week \r
- * number depending on the value of {@link #showWeekNumbers}.\r
- */\r
- showWeekLinks: false,\r
- /**\r
- * @cfg {Boolean} showWeekNumbers\r
- * True to show the week number for each week in the calendar in the week link column, false to show nothing (defaults to false).\r
- * Note that if {@link #showWeekLinks} is false this config will have no affect even if true.\r
- */\r
- showWeekNumbers: false,\r
- /**\r
- * @cfg {String} weekLinkOverClass\r
- * The CSS class name applied when the mouse moves over a week link element (only applies when {@link #showWeekLinks} is true,\r
- * defaults to 'ext-week-link-over').\r
- */\r
- weekLinkOverClass: 'ext-week-link-over',\r
-\r
- //private properties -- do not override:\r
- daySelector: '.ext-cal-day',\r
- moreSelector: '.ext-cal-ev-more',\r
- weekLinkSelector: '.ext-cal-week-link',\r
- weekCount: -1,\r
- // defaults to auto by month\r
- dayCount: 7,\r
- moreElIdDelimiter: '-more-',\r
- weekLinkIdDelimiter: 'ext-cal-week-',\r
-\r
- // private\r
- initComponent: function() {\r
- Ext.calendar.MonthView.superclass.initComponent.call(this);\r
- this.addEvents({\r
- /**\r
- * @event dayclick\r
- * Fires after the user clicks within the view container and not on an event element\r
- * @param {Ext.calendar.MonthView} this\r
- * @param {Date} dt The date/time that was clicked on\r
- * @param {Boolean} allday True if the day clicked on represents an all-day box, else false. Clicks within the \r
- * MonthView always return true for this param.\r
- * @param {Ext.Element} el The Element that was clicked on\r
- */\r
- dayclick: true,\r
- /**\r
- * @event weekclick\r
- * Fires after the user clicks within a week link (when {@link #showWeekLinks is true)\r
- * @param {Ext.calendar.MonthView} this\r
- * @param {Date} dt The start date of the week that was clicked on\r
- */\r
- weekclick: true,\r
- // inherited docs\r
- dayover: true,\r
- // inherited docs\r
- dayout: true\r
- });\r
- },\r
-\r
- // private\r
- initDD: function() {\r
- var cfg = {\r
- view: this,\r
- createText: this.ddCreateEventText,\r
- moveText: this.ddMoveEventText,\r
- ddGroup: 'MonthViewDD'\r
- };\r
-\r
- this.dragZone = new Ext.calendar.DragZone(this.el, cfg);\r
- this.dropZone = new Ext.calendar.DropZone(this.el, cfg);\r
- },\r
-\r
- // private\r
- onDestroy: function() {\r
- Ext.destroy(this.ddSelector);\r
- Ext.destroy(this.dragZone);\r
- Ext.destroy(this.dropZone);\r
- Ext.calendar.MonthView.superclass.onDestroy.call(this);\r
- },\r
-\r
- // private\r
- afterRender: function() {\r
- if (!this.tpl) {\r
- this.tpl = new Ext.calendar.MonthViewTemplate({\r
- id: this.id,\r
- showTodayText: this.showTodayText,\r
- todayText: this.todayText,\r
- showTime: this.showTime,\r
- showHeader: this.showHeader,\r
- showWeekLinks: this.showWeekLinks,\r
- showWeekNumbers: this.showWeekNumbers\r
- });\r
- }\r
- this.tpl.compile();\r
- this.addClass('ext-cal-monthview ext-cal-ct');\r
-\r
- Ext.calendar.MonthView.superclass.afterRender.call(this);\r
- },\r
-\r
- // private\r
- onResize: function() {\r
- if (this.monitorResize) {\r
- this.maxEventsPerDay = this.getMaxEventsPerDay();\r
- this.refresh();\r
- }\r
- },\r
-\r
- // private\r
- forceSize: function() {\r
- // Compensate for the week link gutter width if visible\r
- if (this.showWeekLinks && this.el && this.el.child) {\r
- var hd = this.el.select('.ext-cal-hd-days-tbl'),\r
- bgTbl = this.el.select('.ext-cal-bg-tbl'),\r
- evTbl = this.el.select('.ext-cal-evt-tbl'),\r
- wkLinkW = this.el.child('.ext-cal-week-link').getWidth(),\r
- w = this.el.getWidth() - wkLinkW;\r
-\r
- hd.setWidth(w);\r
- bgTbl.setWidth(w);\r
- evTbl.setWidth(w);\r
- }\r
- Ext.calendar.MonthView.superclass.forceSize.call(this);\r
- },\r
-\r
- //private\r
- initClock: function() {\r
- if (Ext.fly(this.id + '-clock') !== null) {\r
- this.prevClockDay = new Date().getDay();\r
- if (this.clockTask) {\r
- Ext.TaskMgr.stop(this.clockTask);\r
- }\r
- this.clockTask = Ext.TaskMgr.start({\r
- run: function() {\r
- var el = Ext.fly(this.id + '-clock'),\r
- t = new Date();\r
-\r
- if (t.getDay() == this.prevClockDay) {\r
- if (el) {\r
- el.update(t.format('g:i a'));\r
- }\r
- }\r
- else {\r
- this.prevClockDay = t.getDay();\r
- this.moveTo(t);\r
- }\r
- },\r
- scope: this,\r
- interval: 1000\r
- });\r
- }\r
- },\r
-\r
- // inherited docs\r
- getEventBodyMarkup: function() {\r
- if (!this.eventBodyMarkup) {\r
- this.eventBodyMarkup = ['{Title}',\r
- '<tpl if="_isReminder">',\r
- '<i class="ext-cal-ic ext-cal-ic-rem"> </i>',\r
- '</tpl>',\r
- '<tpl if="_isRecurring">',\r
- '<i class="ext-cal-ic ext-cal-ic-rcr"> </i>',\r
- '</tpl>',\r
- '<tpl if="spanLeft">',\r
- '<i class="ext-cal-spl"> </i>',\r
- '</tpl>',\r
- '<tpl if="spanRight">',\r
- '<i class="ext-cal-spr"> </i>',\r
- '</tpl>'\r
- ].join('');\r
- }\r
- return this.eventBodyMarkup;\r
- },\r
-\r
- // inherited docs\r
- getEventTemplate: function() {\r
- if (!this.eventTpl) {\r
- var tpl,\r
- body = this.getEventBodyMarkup();\r
-\r
- tpl = !(Ext.isIE || Ext.isOpera) ?\r
- new Ext.XTemplate(\r
- '<div id="{_elId}" class="{_selectorCls} {_colorCls} {values.spanCls} ext-cal-evt ext-cal-evr">',\r
- body,\r
- '</div>'\r
- )\r
- : new Ext.XTemplate(\r
- '<tpl if="_renderAsAllDay">',\r
- '<div id="{_elId}" class="{_selectorCls} {values.spanCls} {_colorCls} ext-cal-evt ext-cal-evo">',\r
- '<div class="ext-cal-evm">',\r
- '<div class="ext-cal-evi">',\r
- '</tpl>',\r
- '<tpl if="!_renderAsAllDay">',\r
- '<div id="{_elId}" class="{_selectorCls} {_colorCls} ext-cal-evt ext-cal-evr">',\r
- '</tpl>',\r
- body,\r
- '<tpl if="_renderAsAllDay">',\r
- '</div>',\r
- '</div>',\r
- '</tpl>',\r
- '</div>'\r
- );\r
- tpl.compile();\r
- this.eventTpl = tpl;\r
- }\r
- return this.eventTpl;\r
- },\r
-\r
- // private\r
- getTemplateEventData: function(evt) {\r
- var M = Ext.calendar.EventMappings,\r
- selector = this.getEventSelectorCls(evt[M.EventId.name]),\r
- title = evt[M.Title.name];\r
-\r
- return Ext.applyIf({\r
- _selectorCls: selector,\r
- _colorCls: 'ext-color-' + (evt[M.CalendarId.name] ?\r
- evt[M.CalendarId.name] : 'default') + (evt._renderAsAllDay ? '-ad': ''),\r
- _elId: selector + '-' + evt._weekIndex,\r
- _isRecurring: evt.Recurrence && evt.Recurrence != '',\r
- _isReminder: evt[M.Reminder.name] && evt[M.Reminder.name] != '',\r
- Title: (evt[M.IsAllDay.name] ? '': evt[M.StartDate.name].format('g:ia ')) + (!title || title.length == 0 ? '(No title)': title)\r
- },\r
- evt);\r
- },\r
-\r
- // private\r
- refresh: function() {\r
- if (this.detailPanel) {\r
- this.detailPanel.hide();\r
- }\r
- Ext.calendar.MonthView.superclass.refresh.call(this);\r
-\r
- if (this.showTime !== false) {\r
- this.initClock();\r
- }\r
- },\r
-\r
- // private\r
- renderItems: function() {\r
- Ext.calendar.WeekEventRenderer.render({\r
- eventGrid: this.allDayOnly ? this.allDayGrid: this.eventGrid,\r
- viewStart: this.viewStart,\r
- tpl: this.getEventTemplate(),\r
- maxEventsPerDay: this.maxEventsPerDay,\r
- id: this.id,\r
- templateDataFn: this.getTemplateEventData.createDelegate(this),\r
- evtMaxCount: this.evtMaxCount,\r
- weekCount: this.weekCount,\r
- dayCount: this.dayCount\r
- });\r
- this.fireEvent('eventsrendered', this);\r
- },\r
-\r
- // private\r
- getDayEl: function(dt) {\r
- return Ext.get(this.getDayId(dt));\r
- },\r
-\r
- // private\r
- getDayId: function(dt) {\r
- if (Ext.isDate(dt)) {\r
- dt = dt.format('Ymd');\r
- }\r
- return this.id + this.dayElIdDelimiter + dt;\r
- },\r
-\r
- // private\r
- getWeekIndex: function(dt) {\r
- var el = this.getDayEl(dt).up('.ext-cal-wk-ct');\r
- return parseInt(el.id.split('-wk-')[1], 10);\r
- },\r
-\r
- // private\r
- getDaySize: function(contentOnly) {\r
- var box = this.el.getBox(),\r
- w = box.width / this.dayCount,\r
- h = box.height / this.getWeekCount();\r
-\r
- if (contentOnly) {\r
- var hd = this.el.select('.ext-cal-dtitle').first().parent('tr');\r
- h = hd ? h - hd.getHeight(true) : h;\r
- }\r
- return {\r
- height: h,\r
- width: w\r
- };\r
- },\r
-\r
- // private\r
- getEventHeight: function() {\r
- if (!this.eventHeight) {\r
- var evt = this.el.select('.ext-cal-evt').first();\r
- this.eventHeight = evt ? evt.parent('tr').getHeight() : 18;\r
- }\r
- return this.eventHeight;\r
- },\r
-\r
- // private\r
- getMaxEventsPerDay: function() {\r
- var dayHeight = this.getDaySize(true).height,\r
- h = this.getEventHeight(),\r
- max = Math.max(Math.floor((dayHeight - h) / h), 0);\r
-\r
- return max;\r
- },\r
-\r
- // private\r
- getDayAt: function(x, y) {\r
- var box = this.el.getBox(),\r
- daySize = this.getDaySize(),\r
- dayL = Math.floor(((x - box.x) / daySize.width)),\r
- dayT = Math.floor(((y - box.y) / daySize.height)),\r
- days = (dayT * 7) + dayL,\r
- dt = this.viewStart.add(Date.DAY, days);\r
- return {\r
- date: dt,\r
- el: this.getDayEl(dt)\r
- };\r
- },\r
-\r
- // inherited docs\r
- moveNext: function() {\r
- return this.moveMonths(1);\r
- },\r
-\r
- // inherited docs\r
- movePrev: function() {\r
- return this.moveMonths( - 1);\r
- },\r
-\r
- // private\r
- onInitDrag: function() {\r
- Ext.calendar.MonthView.superclass.onInitDrag.call(this);\r
- Ext.select(this.daySelector).removeClass(this.dayOverClass);\r
- if (this.detailPanel) {\r
- this.detailPanel.hide();\r
- }\r
- },\r
-\r
- // private\r
- onMoreClick: function(dt) {\r
- if (!this.detailPanel) {\r
- this.detailPanel = new Ext.Panel({\r
- id: this.id + '-details-panel',\r
- title: dt.format('F j'),\r
- layout: 'fit',\r
- floating: true,\r
- renderTo: Ext.getBody(),\r
- tools: [{\r
- id: 'close',\r
- handler: function(e, t, p) {\r
- p.hide();\r
- }\r
- }],\r
- items: {\r
- xtype: 'monthdaydetailview',\r
- id: this.id + '-details-view',\r
- date: dt,\r
- view: this,\r
- store: this.store,\r
- listeners: {\r
- 'eventsrendered': this.onDetailViewUpdated.createDelegate(this)\r
- }\r
- }\r
- });\r
- }\r
- else {\r
- this.detailPanel.setTitle(dt.format('F j'));\r
- }\r
- this.detailPanel.getComponent(this.id + '-details-view').update(dt);\r
- },\r
-\r
- // private\r
- onDetailViewUpdated: function(view, dt, numEvents) {\r
- var p = this.detailPanel,\r
- frameH = p.getFrameHeight(),\r
- evtH = this.getEventHeight(),\r
- bodyH = frameH + (numEvents * evtH) + 3,\r
- dayEl = this.getDayEl(dt),\r
- box = dayEl.getBox();\r
-\r
- p.updateBox(box);\r
- p.setHeight(bodyH);\r
- p.setWidth(Math.max(box.width, 220));\r
- p.show();\r
- p.getPositionEl().alignTo(dayEl, 't-t?');\r
- },\r
-\r
- // private\r
- onHide: function() {\r
- Ext.calendar.MonthView.superclass.onHide.call(this);\r
- if (this.detailPanel) {\r
- this.detailPanel.hide();\r
- }\r
- },\r
-\r
- // private\r
- onClick: function(e, t) {\r
- if (this.detailPanel) {\r
- this.detailPanel.hide();\r
- }\r
- if (Ext.calendar.MonthView.superclass.onClick.apply(this, arguments)) {\r
- // The superclass handled the click already so exit\r
- return;\r
- }\r
- if (this.dropZone) {\r
- this.dropZone.clearShims();\r
- }\r
- var el = e.getTarget(this.weekLinkSelector, 3),\r
- dt,\r
- parts;\r
- if (el) {\r
- dt = el.id.split(this.weekLinkIdDelimiter)[1];\r
- this.fireEvent('weekclick', this, Date.parseDate(dt, 'Ymd'));\r
- return;\r
- }\r
- el = e.getTarget(this.moreSelector, 3);\r
- if (el) {\r
- dt = el.id.split(this.moreElIdDelimiter)[1];\r
- this.onMoreClick(Date.parseDate(dt, 'Ymd'));\r
- return;\r
- }\r
- el = e.getTarget('td', 3);\r
- if (el) {\r
- if (el.id && el.id.indexOf(this.dayElIdDelimiter) > -1) {\r
- parts = el.id.split(this.dayElIdDelimiter);\r
- dt = parts[parts.length - 1];\r
-\r
- this.fireEvent('dayclick', this, Date.parseDate(dt, 'Ymd'), false, Ext.get(this.getDayId(dt)));\r
- return;\r
- }\r
- }\r
- },\r
-\r
- // private\r
- handleDayMouseEvent: function(e, t, type) {\r
- var el = e.getTarget(this.weekLinkSelector, 3, true);\r
- if (el) {\r
- el[type == 'over' ? 'addClass': 'removeClass'](this.weekLinkOverClass);\r
- return;\r
- }\r
- Ext.calendar.MonthView.superclass.handleDayMouseEvent.apply(this, arguments);\r
- }\r
-});\r
-\r
-Ext.reg('monthview', Ext.calendar.MonthView);\r
-/**
- * @class Ext.calendar.DayHeaderView
- * @extends Ext.calendar.MonthView
- * <p>This is the header area container within the day and week views where all-day events are displayed.
- * Normally you should not need to use this class directly -- instead you should use {@link Ext.calendar.DayView DayView}
- * which aggregates this class and the {@link Ext.calendar.DayBodyView DayBodyView} into the single unified view
- * presented by {@link Ext.calendar.CalendarPanel CalendarPanel}.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.DayHeaderView = Ext.extend(Ext.calendar.MonthView, {
- // private configs
- weekCount: 1,
- dayCount: 1,
- allDayOnly: true,
- monitorResize: false,
-
- /**
- * @event dayclick
- * Fires after the user clicks within the day view container and not on an event element
- * @param {Ext.calendar.DayBodyView} this
- * @param {Date} dt The date/time that was clicked on
- * @param {Boolean} allday True if the day clicked on represents an all-day box, else false. Clicks within the
- * DayHeaderView always return true for this param.
- * @param {Ext.Element} el The Element that was clicked on
- */
-
- // private
- afterRender: function() {
- if (!this.tpl) {
- this.tpl = new Ext.calendar.DayHeaderTemplate({
- id: this.id,
- showTodayText: this.showTodayText,
- todayText: this.todayText,
- showTime: this.showTime
- });
- }
- this.tpl.compile();
- this.addClass('ext-cal-day-header');
-
- Ext.calendar.DayHeaderView.superclass.afterRender.call(this);
- },
-
- // private
- forceSize: Ext.emptyFn,
-
- // private
- refresh: function() {
- Ext.calendar.DayHeaderView.superclass.refresh.call(this);
- this.recalcHeaderBox();
- },
-
- // private
- recalcHeaderBox: function() {
- var tbl = this.el.child('.ext-cal-evt-tbl'),
- h = tbl.getHeight();
-
- this.el.setHeight(h + 7);
-
- if (Ext.isIE && Ext.isStrict) {
- this.el.child('.ext-cal-hd-ad-inner').setHeight(h + 4);
- }
- if (Ext.isOpera) {
- //TODO: figure out why Opera refuses to refresh height when
- //the new height is lower than the previous one
- // var ct = this.el.child('.ext-cal-hd-ct');
- // ct.repaint();
- }
- },
-
- // private
- moveNext: function(noRefresh) {
- this.moveDays(this.dayCount, noRefresh);
- },
-
- // private
- movePrev: function(noRefresh) {
- this.moveDays( - this.dayCount, noRefresh);
- },
-
- // private
- onClick: function(e, t) {
- var el = e.getTarget('td', 3),
- parts,
- dt;
- if (el) {
- if (el.id && el.id.indexOf(this.dayElIdDelimiter) > -1) {
- parts = el.id.split(this.dayElIdDelimiter);
- dt = parts[parts.length - 1];
-
- this.fireEvent('dayclick', this, Date.parseDate(dt, 'Ymd'), true, Ext.get(this.getDayId(dt)));
- return;
- }
- }
- Ext.calendar.DayHeaderView.superclass.onClick.apply(this, arguments);
- }
-});
-
-Ext.reg('dayheaderview', Ext.calendar.DayHeaderView);
-/**S
- * @class Ext.calendar.DayBodyView
- * @extends Ext.calendar.CalendarView
- * <p>This is the scrolling container within the day and week views where non-all-day events are displayed.
- * Normally you should not need to use this class directly -- instead you should use {@link Ext.calendar.DayView DayView}
- * which aggregates this class and the {@link Ext.calendar.DayHeaderView DayHeaderView} into the single unified view
- * presented by {@link Ext.calendar.CalendarPanel CalendarPanel}.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.DayBodyView = Ext.extend(Ext.calendar.CalendarView, {
- //private
- dayColumnElIdDelimiter: '-day-col-',
-
- //private
- initComponent: function() {
- Ext.calendar.DayBodyView.superclass.initComponent.call(this);
-
- this.addEvents({
- /**
- * @event eventresize
- * Fires after the user drags the resize handle of an event to resize it
- * @param {Ext.calendar.DayBodyView} this
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was resized
- * containing the updated start and end dates
- */
- eventresize: true,
- /**
- * @event dayclick
- * Fires after the user clicks within the day view container and not on an event element
- * @param {Ext.calendar.DayBodyView} this
- * @param {Date} dt The date/time that was clicked on
- * @param {Boolean} allday True if the day clicked on represents an all-day box, else false. Clicks within the
- * DayBodyView always return false for this param.
- * @param {Ext.Element} el The Element that was clicked on
- */
- dayclick: true
- });
- },
-
- //private
- initDD: function() {
- var cfg = {
- createText: this.ddCreateEventText,
- moveText: this.ddMoveEventText,
- resizeText: this.ddResizeEventText
- };
-
- this.el.ddScrollConfig = {
- // scrolling is buggy in IE/Opera for some reason. A larger vthresh
- // makes it at least functional if not perfect
- vthresh: Ext.isIE || Ext.isOpera ? 100: 40,
- hthresh: -1,
- frequency: 50,
- increment: 100,
- ddGroup: 'DayViewDD'
- };
- this.dragZone = new Ext.calendar.DayViewDragZone(this.el, Ext.apply({
- view: this,
- containerScroll: true
- },
- cfg));
-
- this.dropZone = new Ext.calendar.DayViewDropZone(this.el, Ext.apply({
- view: this
- },
- cfg));
- },
-
- //private
- refresh: function() {
- var top = this.el.getScroll().top;
- this.prepareData();
- this.renderTemplate();
- this.renderItems();
-
- // skip this if the initial render scroll position has not yet been set.
- // necessary since IE/Opera must be deferred, so the first refresh will
- // override the initial position by default and always set it to 0.
- if (this.scrollReady) {
- this.scrollTo(top);
- }
- },
-
- /**
- * Scrolls the container to the specified vertical position. If the view is large enough that
- * there is no scroll overflow then this method will have no affect.
- * @param {Number} y The new vertical scroll position in pixels
- * @param {Boolean} defer (optional) <p>True to slightly defer the call, false to execute immediately.</p>
- * <p>This method will automatically defer itself for IE and Opera (even if you pass false) otherwise
- * the scroll position will not update in those browsers. You can optionally pass true, however, to
- * force the defer in all browsers, or use your own custom conditions to determine whether this is needed.</p>
- * <p>Note that this method should not generally need to be called directly as scroll position is managed internally.</p>
- */
- scrollTo: function(y, defer) {
- defer = defer || (Ext.isIE || Ext.isOpera);
- if (defer) {
- (function() {
- this.el.scrollTo('top', y);
- this.scrollReady = true;
- }).defer(10, this);
- }
- else {
- this.el.scrollTo('top', y);
- this.scrollReady = true;
- }
- },
-
- // private
- afterRender: function() {
- if (!this.tpl) {
- this.tpl = new Ext.calendar.DayBodyTemplate({
- id: this.id,
- dayCount: this.dayCount,
- showTodayText: this.showTodayText,
- todayText: this.todayText,
- showTime: this.showTime
- });
- }
- this.tpl.compile();
-
- this.addClass('ext-cal-body-ct');
-
- Ext.calendar.DayBodyView.superclass.afterRender.call(this);
-
- // default scroll position to 7am:
- this.scrollTo(7 * 42);
- },
-
- // private
- forceSize: Ext.emptyFn,
-
- // private
- onEventResize: function(rec, data) {
- var D = Ext.calendar.Date,
- start = Ext.calendar.EventMappings.StartDate.name,
- end = Ext.calendar.EventMappings.EndDate.name;
-
- if (D.compare(rec.data[start], data.StartDate) === 0 &&
- D.compare(rec.data[end], data.EndDate) === 0) {
- // no changes
- return;
- }
- rec.set(start, data.StartDate);
- rec.set(end, data.EndDate);
-
- this.fireEvent('eventresize', this, rec);
- },
-
- // inherited docs
- getEventBodyMarkup: function() {
- if (!this.eventBodyMarkup) {
- this.eventBodyMarkup = ['{Title}',
- '<tpl if="_isReminder">',
- '<i class="ext-cal-ic ext-cal-ic-rem"> </i>',
- '</tpl>',
- '<tpl if="_isRecurring">',
- '<i class="ext-cal-ic ext-cal-ic-rcr"> </i>',
- '</tpl>'
- // '<tpl if="spanLeft">',
- // '<i class="ext-cal-spl"> </i>',
- // '</tpl>',
- // '<tpl if="spanRight">',
- // '<i class="ext-cal-spr"> </i>',
- // '</tpl>'
- ].join('');
- }
- return this.eventBodyMarkup;
- },
-
- // inherited docs
- getEventTemplate: function() {
- if (!this.eventTpl) {
- this.eventTpl = !(Ext.isIE || Ext.isOpera) ?
- new Ext.XTemplate(
- '<div id="{_elId}" class="{_selectorCls} {_colorCls} ext-cal-evt ext-cal-evr" style="left: {_left}%; width: {_width}%; top: {_top}px; height: {_height}px;">',
- '<div class="ext-evt-bd">', this.getEventBodyMarkup(), '</div>',
- '<div class="ext-evt-rsz"><div class="ext-evt-rsz-h"> </div></div>',
- '</div>'
- )
- : new Ext.XTemplate(
- '<div id="{_elId}" class="ext-cal-evt {_selectorCls} {_colorCls}-x" style="left: {_left}%; width: {_width}%; top: {_top}px;">',
- '<div class="ext-cal-evb"> </div>',
- '<dl style="height: {_height}px;" class="ext-cal-evdm">',
- '<dd class="ext-evt-bd">',
- this.getEventBodyMarkup(),
- '</dd>',
- '<div class="ext-evt-rsz"><div class="ext-evt-rsz-h"> </div></div>',
- '</dl>',
- '<div class="ext-cal-evb"> </div>',
- '</div>'
- );
- this.eventTpl.compile();
- }
- return this.eventTpl;
- },
-
- /**
- * <p>Returns the XTemplate that is bound to the calendar's event store (it expects records of type
- * {@link Ext.calendar.EventRecord}) to populate the calendar views with <strong>all-day</strong> events.
- * Internally this method by default generates different markup for browsers that support CSS border radius
- * and those that don't. This method can be overridden as needed to customize the markup generated.</p>
- * <p>Note that this method calls {@link #getEventBodyMarkup} to retrieve the body markup for events separately
- * from the surrounding container markup. This provdes the flexibility to customize what's in the body without
- * having to override the entire XTemplate. If you do override this method, you should make sure that your
- * overridden version also does the same.</p>
- * @return {Ext.XTemplate} The event XTemplate
- */
- getEventAllDayTemplate: function() {
- if (!this.eventAllDayTpl) {
- var tpl,
- body = this.getEventBodyMarkup();
-
- tpl = !(Ext.isIE || Ext.isOpera) ?
- new Ext.XTemplate(
- '<div id="{_elId}" class="{_selectorCls} {_colorCls} {values.spanCls} ext-cal-evt ext-cal-evr" style="left: {_left}%; width: {_width}%; top: {_top}px; height: {_height}px;">',
- body,
- '</div>'
- )
- : new Ext.XTemplate(
- '<div id="{_elId}" class="ext-cal-evt" style="left: {_left}%; width: {_width}%; top: {_top}px; height: {_height}px;">',
- '<div class="{_selectorCls} {values.spanCls} {_colorCls} ext-cal-evo">',
- '<div class="ext-cal-evm">',
- '<div class="ext-cal-evi">',
- body,
- '</div>',
- '</div>',
- '</div></div>'
- );
- tpl.compile();
- this.eventAllDayTpl = tpl;
- }
- return this.eventAllDayTpl;
- },
-
- // private
- getTemplateEventData: function(evt) {
- var selector = this.getEventSelectorCls(evt[Ext.calendar.EventMappings.EventId.name]),
- data = {},
- M = Ext.calendar.EventMappings;
-
- this.getTemplateEventBox(evt);
-
- data._selectorCls = selector;
- data._colorCls = 'ext-color-' + evt[M.CalendarId.name] + (evt._renderAsAllDay ? '-ad': '');
- data._elId = selector + (evt._weekIndex ? '-' + evt._weekIndex: '');
- data._isRecurring = evt.Recurrence && evt.Recurrence != '';
- data._isReminder = evt[M.Reminder.name] && evt[M.Reminder.name] != '';
- var title = evt[M.Title.name];
- data.Title = (evt[M.IsAllDay.name] ? '': evt[M.StartDate.name].format('g:ia ')) + (!title || title.length == 0 ? '(No title)': title);
-
- return Ext.applyIf(data, evt);
- },
-
- // private
- getTemplateEventBox: function(evt) {
- var heightFactor = 0.7,
- start = evt[Ext.calendar.EventMappings.StartDate.name],
- end = evt[Ext.calendar.EventMappings.EndDate.name],
- startMins = start.getHours() * 60 + start.getMinutes(),
- endMins = end.getHours() * 60 + end.getMinutes(),
- diffMins = endMins - startMins;
-
- evt._left = 0;
- evt._width = 100;
- evt._top = Math.round(startMins * heightFactor) + 1;
- evt._height = Math.max((diffMins * heightFactor) - 2, 15);
- },
-
- // private
- renderItems: function() {
- var day = 0,
- evts = [],
- ev,
- d,
- ct,
- item,
- i,
- j,
- l,
- overlapCols,
- prevCol,
- colWidth,
- evtWidth,
- markup,
- target;
- for (; day < this.dayCount; day++) {
- ev = emptyCells = skipped = 0;
- d = this.eventGrid[0][day];
- ct = d ? d.length: 0;
-
- for (; ev < ct; ev++) {
- evt = d[ev];
- if (!evt) {
- continue;
- }
- item = evt.data || evt.event.data;
- if (item._renderAsAllDay) {
- continue;
- }
- Ext.apply(item, {
- cls: 'ext-cal-ev',
- _positioned: true
- });
- evts.push({
- data: this.getTemplateEventData(item),
- date: this.viewStart.add(Date.DAY, day)
- });
- }
- }
-
- // overlapping event pre-processing loop
- i = j = overlapCols = prevCol = 0;
- l = evts.length;
- for (; i < l; i++) {
- evt = evts[i].data;
- evt2 = null;
- prevCol = overlapCols;
- for (j = 0; j < l; j++) {
- if (i == j) {
- continue;
- }
- evt2 = evts[j].data;
- if (this.isOverlapping(evt, evt2)) {
- evt._overlap = evt._overlap == undefined ? 1: evt._overlap + 1;
- if (i < j) {
- if (evt._overcol === undefined) {
- evt._overcol = 0;
- }
- evt2._overcol = evt._overcol + 1;
- overlapCols = Math.max(overlapCols, evt2._overcol);
- }
- }
- }
- }
-
- // rendering loop
- for (i = 0; i < l; i++) {
- evt = evts[i].data;
- if (evt._overlap !== undefined) {
- colWidth = 100 / (overlapCols + 1);
- evtWidth = 100 - (colWidth * evt._overlap);
-
- evt._width = colWidth;
- evt._left = colWidth * evt._overcol;
- }
- markup = this.getEventTemplate().apply(evt);
- target = this.id + '-day-col-' + evts[i].date.format('Ymd');
-
- Ext.DomHelper.append(target, markup);
- }
-
- this.fireEvent('eventsrendered', this);
- },
-
- // private
- getDayEl: function(dt) {
- return Ext.get(this.getDayId(dt));
- },
-
- // private
- getDayId: function(dt) {
- if (Ext.isDate(dt)) {
- dt = dt.format('Ymd');
- }
- return this.id + this.dayColumnElIdDelimiter + dt;
- },
-
- // private
- getDaySize: function() {
- var box = this.el.child('.ext-cal-day-col-inner').getBox();
- return {
- height: box.height,
- width: box.width
- };
- },
-
- // private
- getDayAt: function(x, y) {
- var sel = '.ext-cal-body-ct',
- xoffset = this.el.child('.ext-cal-day-times').getWidth(),
- viewBox = this.el.getBox(),
- daySize = this.getDaySize(false),
- relX = x - viewBox.x - xoffset,
- dayIndex = Math.floor(relX / daySize.width),
- // clicked col index
- scroll = this.el.getScroll(),
- row = this.el.child('.ext-cal-bg-row'),
- // first avail row, just to calc size
- rowH = row.getHeight() / 2,
- // 30 minute increment since a row is 60 minutes
- relY = y - viewBox.y - rowH + scroll.top,
- rowIndex = Math.max(0, Math.ceil(relY / rowH)),
- mins = rowIndex * 30,
- dt = this.viewStart.add(Date.DAY, dayIndex).add(Date.MINUTE, mins),
- el = this.getDayEl(dt),
- timeX = x;
-
- if (el) {
- timeX = el.getLeft();
- }
-
- return {
- date: dt,
- el: el,
- // this is the box for the specific time block in the day that was clicked on:
- timeBox: {
- x: timeX,
- y: (rowIndex * 21) + viewBox.y - scroll.top,
- width: daySize.width,
- height: rowH
- }
- };
- },
-
- // private
- onClick: function(e, t) {
- if (this.dragPending || Ext.calendar.DayBodyView.superclass.onClick.apply(this, arguments)) {
- // The superclass handled the click already so exit
- return;
- }
- if (e.getTarget('.ext-cal-day-times', 3) !== null) {
- // ignore clicks on the times-of-day gutter
- return;
- }
- var el = e.getTarget('td', 3);
- if (el) {
- if (el.id && el.id.indexOf(this.dayElIdDelimiter) > -1) {
- var dt = this.getDateFromId(el.id, this.dayElIdDelimiter);
- this.fireEvent('dayclick', this, Date.parseDate(dt, 'Ymd'), true, Ext.get(this.getDayId(dt, true)));
- return;
- }
- }
- var day = this.getDayAt(e.xy[0], e.xy[1]);
- if (day && day.date) {
- this.fireEvent('dayclick', this, day.date, false, null);
- }
- }
-});
-
-Ext.reg('daybodyview', Ext.calendar.DayBodyView);
-/**
- * @class Ext.calendar.DayView
- * @extends Ext.Container
- * <p>Unlike other calendar views, is not actually a subclass of {@link Ext.calendar.CalendarView CalendarView}.
- * Instead it is a {@link Ext.Container Container} subclass that internally creates and manages the layouts of
- * a {@link Ext.calendar.DayHeaderView DayHeaderView} and a {@link Ext.calendar.DayBodyView DayBodyView}. As such
- * DayView accepts any config values that are valid for DayHeaderView and DayBodyView and passes those through
- * to the contained views. It also supports the interface required of any calendar view and in turn calls methods
- * on the contained views as necessary.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.DayView = Ext.extend(Ext.Container, {
- /**
- * @cfg {Boolean} showTime
- * True to display the current time in today's box in the calendar, false to not display it (defautls to true)
- */
- showTime: true,
- /**
- * @cfg {Boolean} showTodayText
- * True to display the {@link #todayText} string in today's box in the calendar, false to not display it (defautls to true)
- */
- showTodayText: true,
- /**
- * @cfg {String} todayText
- * The text to display in the current day's box in the calendar when {@link #showTodayText} is true (defaults to 'Today')
- */
- todayText: 'Today',
- /**
- * @cfg {String} ddCreateEventText
- * The text to display inside the drag proxy while dragging over the calendar to create a new event (defaults to
- * 'Create event for {0}' where {0} is a date range supplied by the view)
- */
- ddCreateEventText: 'Create event for {0}',
- /**
- * @cfg {String} ddMoveEventText
- * The text to display inside the drag proxy while dragging an event to reposition it (defaults to
- * 'Move event to {0}' where {0} is the updated event start date/time supplied by the view)
- */
- ddMoveEventText: 'Move event to {0}',
- /**
- * @cfg {Number} dayCount
- * The number of days to display in the view (defaults to 1)
- */
- dayCount: 1,
-
- // private
- initComponent : function(){
- // rendering more than 7 days per view is not supported
- this.dayCount = this.dayCount > 7 ? 7 : this.dayCount;
-
- var cfg = Ext.apply({}, this.initialConfig);
- cfg.showTime = this.showTime;
- cfg.showTodatText = this.showTodayText;
- cfg.todayText = this.todayText;
- cfg.dayCount = this.dayCount;
- cfg.wekkCount = 1;
-
- var header = Ext.applyIf({
- xtype: 'dayheaderview',
- id: this.id+'-hd'
- }, cfg);
-
- var body = Ext.applyIf({
- xtype: 'daybodyview',
- id: this.id+'-bd'
- }, cfg);
-
- this.items = [header, body];
- this.addClass('ext-cal-dayview ext-cal-ct');
-
- Ext.calendar.DayView.superclass.initComponent.call(this);
- },
-
- // private
- afterRender : function(){
- Ext.calendar.DayView.superclass.afterRender.call(this);
-
- this.header = Ext.getCmp(this.id+'-hd');
- this.body = Ext.getCmp(this.id+'-bd');
- this.body.on('eventsrendered', this.forceSize, this);
- },
-
- // private
- refresh : function(){
- this.header.refresh();
- this.body.refresh();
- },
-
- // private
- forceSize: function(){
- // The defer call is mainly for good ol' IE, but it doesn't hurt in
- // general to make sure that the window resize is good and done first
- // so that we can properly calculate sizes.
- (function(){
- var ct = this.el.up('.x-panel-body'),
- hd = this.el.child('.ext-cal-day-header'),
- h = ct.getHeight() - hd.getHeight();
-
- this.el.child('.ext-cal-body-ct').setHeight(h);
- }).defer(10, this);
- },
-
- // private
- onResize : function(){
- this.forceSize();
- },
-
- // private
- getViewBounds : function(){
- return this.header.getViewBounds();
- },
-
- /**
- * Returns the start date of the view, as set by {@link #setStartDate}. Note that this may not
- * be the first date displayed in the rendered calendar -- to get the start and end dates displayed
- * to the user use {@link #getViewBounds}.
- * @return {Date} The start date
- */
- getStartDate : function(){
- return this.header.getStartDate();
- },
-
- /**
- * Sets the start date used to calculate the view boundaries to display. The displayed view will be the
- * earliest and latest dates that match the view requirements and contain the date passed to this function.
- * @param {Date} dt The date used to calculate the new view boundaries
- */
- setStartDate: function(dt){
- this.header.setStartDate(dt, true);
- this.body.setStartDate(dt, true);
- },
-
- // private
- renderItems: function(){
- this.header.renderItems();
- this.body.renderItems();
- },
-
- /**
- * Returns true if the view is currently displaying today's date, else false.
- * @return {Boolean} True or false
- */
- isToday : function(){
- return this.header.isToday();
- },
-
- /**
- * Updates the view to contain the passed date
- * @param {Date} dt The date to display
- */
- moveTo : function(dt, noRefresh){
- this.header.moveTo(dt, noRefresh);
- this.body.moveTo(dt, noRefresh);
- },
-
- /**
- * Updates the view to the next consecutive date(s)
- */
- moveNext : function(noRefresh){
- this.header.moveNext(noRefresh);
- this.body.moveNext(noRefresh);
- },
-
- /**
- * Updates the view to the previous consecutive date(s)
- */
- movePrev : function(noRefresh){
- this.header.movePrev(noRefresh);
- this.body.movePrev(noRefresh);
- },
-
- /**
- * Shifts the view by the passed number of days relative to the currently set date
- * @param {Number} value The number of days (positive or negative) by which to shift the view
- */
- moveDays : function(value, noRefresh){
- this.header.moveDays(value, noRefresh);
- this.body.moveDays(value, noRefresh);
- },
-
- /**
- * Updates the view to show today
- */
- moveToday : function(noRefresh){
- this.header.moveToday(noRefresh);
- this.body.moveToday(noRefresh);
- }
-});
-
-Ext.reg('dayview', Ext.calendar.DayView);
-/**
- * @class Ext.calendar.WeekView
- * @extends Ext.calendar.DayView
- * <p>Displays a calendar view by week. This class does not usually need ot be used directly as you can
- * use a {@link Ext.calendar.CalendarPanel CalendarPanel} to manage multiple calendar views at once including
- * the week view.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.WeekView = Ext.extend(Ext.calendar.DayView, {
- /**
- * @cfg {Number} dayCount
- * The number of days to display in the view (defaults to 7)
- */
- dayCount: 7
-});
-
-Ext.reg('weekview', Ext.calendar.WeekView);/**
- * @class Ext.calendar.DateRangeField
- * @extends Ext.form.Field
- * <p>A combination field that includes start and end dates and times, as well as an optional all-day checkbox.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.DateRangeField = Ext.extend(Ext.form.Field, {
- /**
- * @cfg {String} toText
- * The text to display in between the date/time fields (defaults to 'to')
- */
- toText: 'to',
- /**
- * @cfg {String} toText
- * The text to display as the label for the all day checkbox (defaults to 'All day')
- */
- allDayText: 'All day',
-
- // private
- onRender: function(ct, position) {
- if (!this.el) {
- this.startDate = new Ext.form.DateField({
- id: this.id + '-start-date',
- format: 'n/j/Y',
- width: 100,
- listeners: {
- 'change': {
- fn: function() {
- this.checkDates('date', 'start');
- },
- scope: this
- }
- }
- });
- this.startTime = new Ext.form.TimeField({
- id: this.id + '-start-time',
- hidden: this.showTimes === false,
- labelWidth: 0,
- hideLabel: true,
- width: 90,
- listeners: {
- 'select': {
- fn: function() {
- this.checkDates('time', 'start');
- },
- scope: this
- }
- }
- });
- this.endTime = new Ext.form.TimeField({
- id: this.id + '-end-time',
- hidden: this.showTimes === false,
- labelWidth: 0,
- hideLabel: true,
- width: 90,
- listeners: {
- 'select': {
- fn: function() {
- this.checkDates('time', 'end');
- },
- scope: this
- }
- }
- });
- this.endDate = new Ext.form.DateField({
- id: this.id + '-end-date',
- format: 'n/j/Y',
- hideLabel: true,
- width: 100,
- listeners: {
- 'change': {
- fn: function() {
- this.checkDates('date', 'end');
- },
- scope: this
- }
- }
- });
- this.allDay = new Ext.form.Checkbox({
- id: this.id + '-allday',
- hidden: this.showTimes === false || this.showAllDay === false,
- boxLabel: this.allDayText,
- handler: function(chk, checked) {
- this.startTime.setVisible(!checked);
- this.endTime.setVisible(!checked);
- },
- scope: this
- });
- this.toLabel = new Ext.form.Label({
- xtype: 'label',
- id: this.id + '-to-label',
- text: this.toText
- });
-
- this.fieldCt = new Ext.Container({
- autoEl: {
- id: this.id
- },
- //make sure the container el has the field's id
- cls: 'ext-dt-range',
- renderTo: ct,
- layout: 'table',
- layoutConfig: {
- columns: 6
- },
- defaults: {
- hideParent: true
- },
- items: [
- this.startDate,
- this.startTime,
- this.toLabel,
- this.endTime,
- this.endDate,
- this.allDay
- ]
- });
-
- this.fieldCt.ownerCt = this;
- this.el = this.fieldCt.getEl();
- this.items = new Ext.util.MixedCollection();
- this.items.addAll([this.startDate, this.endDate, this.toLabel, this.startTime, this.endTime, this.allDay]);
- }
- Ext.calendar.DateRangeField.superclass.onRender.call(this, ct, position);
- },
-
- // private
- checkDates: function(type, startend) {
- var startField = Ext.getCmp(this.id + '-start-' + type),
- endField = Ext.getCmp(this.id + '-end-' + type),
- startValue = this.getDT('start'),
- endValue = this.getDT('end');
-
- if (startValue > endValue) {
- if (startend == 'start') {
- endField.setValue(startValue);
- } else {
- startField.setValue(endValue);
- this.checkDates(type, 'start');
- }
- }
- if (type == 'date') {
- this.checkDates('time', startend);
- }
- },
-
- /**
- * Returns an array containing the following values in order:<div class="mdetail-params"><ul>
- * <li><b><code>DateTime</code></b> : <div class="sub-desc">The start date/time</div></li>
- * <li><b><code>DateTime</code></b> : <div class="sub-desc">The end date/time</div></li>
- * <li><b><code>Boolean</code></b> : <div class="sub-desc">True if the dates are all-day, false
- * if the time values should be used</div></li><ul></div>
- * @return {Array} The array of return values
- */
- getValue: function() {
- return [
- this.getDT('start'),
- this.getDT('end'),
- this.allDay.getValue()
- ];
- },
-
- // private getValue helper
- getDT: function(startend) {
- var time = this[startend + 'Time'].getValue(),
- dt = this[startend + 'Date'].getValue();
-
- if (Ext.isDate(dt)) {
- dt = dt.format(this[startend + 'Date'].format);
- }
- else {
- return null;
- };
- if (time != '' && this[startend + 'Time'].isVisible()) {
- return Date.parseDate(dt + ' ' + time, this[startend + 'Date'].format + ' ' + this[startend + 'Time'].format);
- }
- return Date.parseDate(dt, this[startend + 'Date'].format);
-
- },
-
- /**
- * Sets the values to use in the date range.
- * @param {Array/Date/Object} v The value(s) to set into the field. Valid types are as follows:<div class="mdetail-params"><ul>
- * <li><b><code>Array</code></b> : <div class="sub-desc">An array containing, in order, a start date, end date and all-day flag.
- * This array should exactly match the return type as specified by {@link #getValue}.</div></li>
- * <li><b><code>DateTime</code></b> : <div class="sub-desc">A single Date object, which will be used for both the start and
- * end dates in the range. The all-day flag will be defaulted to false.</div></li>
- * <li><b><code>Object</code></b> : <div class="sub-desc">An object containing properties for StartDate, EndDate and IsAllDay
- * as defined in {@link Ext.calendar.EventMappings}.</div></li><ul></div>
- */
- setValue: function(v) {
- if (Ext.isArray(v)) {
- this.setDT(v[0], 'start');
- this.setDT(v[1], 'end');
- this.allDay.setValue( !! v[2]);
- }
- else if (Ext.isDate(v)) {
- this.setDT(v, 'start');
- this.setDT(v, 'end');
- this.allDay.setValue(false);
- }
- else if (v[Ext.calendar.EventMappings.StartDate.name]) {
- //object
- this.setDT(v[Ext.calendar.EventMappings.StartDate.name], 'start');
- if (!this.setDT(v[Ext.calendar.EventMappings.EndDate.name], 'end')) {
- this.setDT(v[Ext.calendar.EventMappings.StartDate.name], 'end');
- }
- this.allDay.setValue( !! v[Ext.calendar.EventMappings.IsAllDay.name]);
- }
- },
-
- // private setValue helper
- setDT: function(dt, startend) {
- if (dt && Ext.isDate(dt)) {
- this[startend + 'Date'].setValue(dt);
- this[startend + 'Time'].setValue(dt.format(this[startend + 'Time'].format));
- return true;
- }
- },
-
- // inherited docs
- isDirty: function() {
- var dirty = false;
- if (this.rendered && !this.disabled) {
- this.items.each(function(item) {
- if (item.isDirty()) {
- dirty = true;
- return false;
- }
- });
- }
- return dirty;
- },
-
- // private
- onDisable: function() {
- this.delegateFn('disable');
- },
-
- // private
- onEnable: function() {
- this.delegateFn('enable');
- },
-
- // inherited docs
- reset: function() {
- this.delegateFn('reset');
- },
-
- // private
- delegateFn: function(fn) {
- this.items.each(function(item) {
- if (item[fn]) {
- item[fn]();
- }
- });
- },
-
- // private
- beforeDestroy: function() {
- Ext.destroy(this.fieldCt);
- Ext.calendar.DateRangeField.superclass.beforeDestroy.call(this);
- },
-
- /**
- * @method getRawValue
- * @hide
- */
- getRawValue: Ext.emptyFn,
- /**
- * @method setRawValue
- * @hide
- */
- setRawValue: Ext.emptyFn
-});
-
-Ext.reg('daterangefield', Ext.calendar.DateRangeField);
-/**
- * @class Ext.calendar.ReminderField
- * @extends Ext.form.ComboBox
- * <p>A custom combo used for choosing a reminder setting for an event.</p>
- * <p>This is pretty much a standard combo that is simply pre-configured for the options needed by the
- * calendar components. The default configs are as follows:<pre><code>
- width: 200,
- fieldLabel: 'Reminder',
- mode: 'local',
- triggerAction: 'all',
- forceSelection: true,
- displayField: 'desc',
- valueField: 'value'
-</code></pre>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.ReminderField = Ext.extend(Ext.form.ComboBox, {
- width: 200,
- fieldLabel: 'Reminder',
- mode: 'local',
- triggerAction: 'all',
- forceSelection: true,
- displayField: 'desc',
- valueField: 'value',
-
- // private
- initComponent: function() {
- Ext.calendar.ReminderField.superclass.initComponent.call(this);
-
- this.store = this.store || new Ext.data.ArrayStore({
- fields: ['value', 'desc'],
- idIndex: 0,
- data: [
- ['', 'None'],
- ['0', 'At start time'],
- ['5', '5 minutes before start'],
- ['15', '15 minutes before start'],
- ['30', '30 minutes before start'],
- ['60', '1 hour before start'],
- ['90', '1.5 hours before start'],
- ['120', '2 hours before start'],
- ['180', '3 hours before start'],
- ['360', '6 hours before start'],
- ['720', '12 hours before start'],
- ['1440', '1 day before start'],
- ['2880', '2 days before start'],
- ['4320', '3 days before start'],
- ['5760', '4 days before start'],
- ['7200', '5 days before start'],
- ['10080', '1 week before start'],
- ['20160', '2 weeks before start']
- ]
- });
- },
-
- // inherited docs
- initValue: function() {
- if (this.value !== undefined) {
- this.setValue(this.value);
- }
- else {
- this.setValue('');
- }
- this.originalValue = this.getValue();
- }
-});
-
-Ext.reg('reminderfield', Ext.calendar.ReminderField);
-/**
- * @class Ext.calendar.EventEditForm
- * @extends Ext.form.FormPanel
- * <p>A custom form used for detailed editing of events.</p>
- * <p>This is pretty much a standard form that is simply pre-configured for the options needed by the
- * calendar components. It is also configured to automatically bind records of type {@link Ext.calendar.EventRecord}
- * to and from the form.</p>
- * <p>This form also provides custom events specific to the calendar so that other calendar components can be easily
- * notified when an event has been edited via this component.</p>
- * <p>The default configs are as follows:</p><pre><code>
- labelWidth: 65,
- title: 'Event Form',
- titleTextAdd: 'Add Event',
- titleTextEdit: 'Edit Event',
- bodyStyle: 'background:transparent;padding:20px 20px 10px;',
- border: false,
- buttonAlign: 'center',
- autoHeight: true,
- cls: 'ext-evt-edit-form',
-</code></pre>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.EventEditForm = Ext.extend(Ext.form.FormPanel, {
- labelWidth: 65,
- title: 'Event Form',
- titleTextAdd: 'Add Event',
- titleTextEdit: 'Edit Event',
- bodyStyle: 'background:transparent;padding:20px 20px 10px;',
- border: false,
- buttonAlign: 'center',
- autoHeight: true,
- // to allow for the notes field to autogrow
- cls: 'ext-evt-edit-form',
-
- // private properties:
- newId: 10000,
- layout: 'column',
-
- // private
- initComponent: function() {
-
- this.addEvents({
- /**
- * @event eventadd
- * Fires after a new event is added
- * @param {Ext.calendar.EventEditForm} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was added
- */
- eventadd: true,
- /**
- * @event eventupdate
- * Fires after an existing event is updated
- * @param {Ext.calendar.EventEditForm} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was updated
- */
- eventupdate: true,
- /**
- * @event eventdelete
- * Fires after an event is deleted
- * @param {Ext.calendar.EventEditForm} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was deleted
- */
- eventdelete: true,
- /**
- * @event eventcancel
- * Fires after an event add/edit operation is canceled by the user and no store update took place
- * @param {Ext.calendar.EventEditForm} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was canceled
- */
- eventcancel: true
- });
-
- this.titleField = new Ext.form.TextField({
- fieldLabel: 'Title',
- name: Ext.calendar.EventMappings.Title.name,
- anchor: '90%'
- });
- this.dateRangeField = new Ext.calendar.DateRangeField({
- fieldLabel: 'When',
- anchor: '90%'
- });
- this.reminderField = new Ext.calendar.ReminderField({
- name: 'Reminder'
- });
- this.notesField = new Ext.form.TextArea({
- fieldLabel: 'Notes',
- name: Ext.calendar.EventMappings.Notes.name,
- grow: true,
- growMax: 150,
- anchor: '100%'
- });
- this.locationField = new Ext.form.TextField({
- fieldLabel: 'Location',
- name: Ext.calendar.EventMappings.Location.name,
- anchor: '100%'
- });
- this.urlField = new Ext.form.TextField({
- fieldLabel: 'Web Link',
- name: Ext.calendar.EventMappings.Url.name,
- anchor: '100%'
- });
-
- var leftFields = [this.titleField, this.dateRangeField, this.reminderField],
- rightFields = [this.notesField, this.locationField, this.urlField];
-
- if (this.calendarStore) {
- this.calendarField = new Ext.calendar.CalendarPicker({
- store: this.calendarStore,
- name: Ext.calendar.EventMappings.CalendarId.name
- });
- leftFields.splice(2, 0, this.calendarField);
- };
-
- this.items = [{
- id: 'left-col',
- columnWidth: 0.65,
- layout: 'form',
- border: false,
- items: leftFields
- },
- {
- id: 'right-col',
- columnWidth: 0.35,
- layout: 'form',
- border: false,
- items: rightFields
- }];
-
- this.fbar = [{
- text: 'Save',
- scope: this,
- handler: this.onSave
- },
- {
- cls: 'ext-del-btn',
- text: 'Delete',
- scope: this,
- handler: this.onDelete
- },
- {
- text: 'Cancel',
- scope: this,
- handler: this.onCancel
- }];
-
- Ext.calendar.EventEditForm.superclass.initComponent.call(this);
- },
-
- // inherited docs
- loadRecord: function(rec) {
- this.form.loadRecord.apply(this.form, arguments);
- this.activeRecord = rec;
- this.dateRangeField.setValue(rec.data);
- if (this.calendarStore) {
- this.form.setValues({
- 'calendar': rec.data[Ext.calendar.EventMappings.CalendarId.name]
- });
- }
- this.isAdd = !!rec.data[Ext.calendar.EventMappings.IsNew.name];
- if (this.isAdd) {
- rec.markDirty();
- this.setTitle(this.titleTextAdd);
- Ext.select('.ext-del-btn').setDisplayed(false);
- }
- else {
- this.setTitle(this.titleTextEdit);
- Ext.select('.ext-del-btn').setDisplayed(true);
- }
- this.titleField.focus();
- },
-
- // inherited docs
- updateRecord: function() {
- var dates = this.dateRangeField.getValue();
-
- this.form.updateRecord(this.activeRecord);
- this.activeRecord.set(Ext.calendar.EventMappings.StartDate.name, dates[0]);
- this.activeRecord.set(Ext.calendar.EventMappings.EndDate.name, dates[1]);
- this.activeRecord.set(Ext.calendar.EventMappings.IsAllDay.name, dates[2]);
- },
-
- // private
- onCancel: function() {
- this.cleanup(true);
- this.fireEvent('eventcancel', this, this.activeRecord);
- },
-
- // private
- cleanup: function(hide) {
- if (this.activeRecord && this.activeRecord.dirty) {
- this.activeRecord.reject();
- }
- delete this.activeRecord;
-
- if (this.form.isDirty()) {
- this.form.reset();
- }
- },
-
- // private
- onSave: function() {
- if (!this.form.isValid()) {
- return;
- }
- this.updateRecord();
-
- if (!this.activeRecord.dirty) {
- this.onCancel();
- return;
- }
-
- this.fireEvent(this.isAdd ? 'eventadd': 'eventupdate', this, this.activeRecord);
- },
-
- // private
- onDelete: function() {
- this.fireEvent('eventdelete', this, this.activeRecord);
- }
-});
-
-Ext.reg('eventeditform', Ext.calendar.EventEditForm);
-/**
- * @class Ext.calendar.EventEditWindow
- * @extends Ext.Window
- * <p>A custom window containing a basic edit form used for quick editing of events.</p>
- * <p>This window also provides custom events specific to the calendar so that other calendar components can be easily
- * notified when an event has been edited via this component.</p>
- * @constructor
- * @param {Object} config The config object
- */
-Ext.calendar.EventEditWindow = function(config) {
- var formPanelCfg = {
- xtype: 'form',
- labelWidth: 65,
- frame: false,
- bodyStyle: 'background:transparent;padding:5px 10px 10px;',
- bodyBorder: false,
- border: false,
- items: [{
- id: 'title',
- name: Ext.calendar.EventMappings.Title.name,
- fieldLabel: 'Title',
- xtype: 'textfield',
- anchor: '100%'
- },
- {
- xtype: 'daterangefield',
- id: 'date-range',
- anchor: '100%',
- fieldLabel: 'When'
- }]
- };
-
- if (config.calendarStore) {
- this.calendarStore = config.calendarStore;
- delete config.calendarStore;
-
- formPanelCfg.items.push({
- xtype: 'calendarpicker',
- id: 'calendar',
- name: 'calendar',
- anchor: '100%',
- store: this.calendarStore
- });
- }
-
- Ext.calendar.EventEditWindow.superclass.constructor.call(this, Ext.apply({
- titleTextAdd: 'Add Event',
- titleTextEdit: 'Edit Event',
- width: 600,
- autocreate: true,
- border: true,
- closeAction: 'hide',
- modal: false,
- resizable: false,
- buttonAlign: 'left',
- savingMessage: 'Saving changes...',
- deletingMessage: 'Deleting event...',
-
- fbar: [{
- xtype: 'tbtext',
- text: '<a href="#" id="tblink">Edit Details...</a>'
- },
- '->', {
- text: 'Save',
- disabled: false,
- handler: this.onSave,
- scope: this
- },
- {
- id: 'delete-btn',
- text: 'Delete',
- disabled: false,
- handler: this.onDelete,
- scope: this,
- hideMode: 'offsets'
- },
- {
- text: 'Cancel',
- disabled: false,
- handler: this.onCancel,
- scope: this
- }],
- items: formPanelCfg
- },
- config));
-};
-
-Ext.extend(Ext.calendar.EventEditWindow, Ext.Window, {
- // private
- newId: 10000,
-
- // private
- initComponent: function() {
- Ext.calendar.EventEditWindow.superclass.initComponent.call(this);
-
- this.formPanel = this.items.items[0];
-
- this.addEvents({
- /**
- * @event eventadd
- * Fires after a new event is added
- * @param {Ext.calendar.EventEditWindow} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was added
- */
- eventadd: true,
- /**
- * @event eventupdate
- * Fires after an existing event is updated
- * @param {Ext.calendar.EventEditWindow} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was updated
- */
- eventupdate: true,
- /**
- * @event eventdelete
- * Fires after an event is deleted
- * @param {Ext.calendar.EventEditWindow} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was deleted
- */
- eventdelete: true,
- /**
- * @event eventcancel
- * Fires after an event add/edit operation is canceled by the user and no store update took place
- * @param {Ext.calendar.EventEditWindow} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was canceled
- */
- eventcancel: true,
- /**
- * @event editdetails
- * Fires when the user selects the option in this window to continue editing in the detailed edit form
- * (by default, an instance of {@link Ext.calendar.EventEditForm}. Handling code should hide this window
- * and transfer the current event record to the appropriate instance of the detailed form by showing it
- * and calling {@link Ext.calendar.EventEditForm#loadRecord loadRecord}.
- * @param {Ext.calendar.EventEditWindow} this
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} that is currently being edited
- */
- editdetails: true
- });
- },
-
- // private
- afterRender: function() {
- Ext.calendar.EventEditWindow.superclass.afterRender.call(this);
-
- this.el.addClass('ext-cal-event-win');
-
- Ext.get('tblink').on('click',
- function(e) {
- e.stopEvent();
- this.updateRecord();
- this.fireEvent('editdetails', this, this.activeRecord);
- },
- this);
- },
-
- /**
- * Shows the window, rendering it first if necessary, or activates it and brings it to front if hidden.
- * @param {Ext.data.Record/Object} o Either a {@link Ext.data.Record} if showing the form
- * for an existing event in edit mode, or a plain object containing a StartDate property (and
- * optionally an EndDate property) for showing the form in add mode.
- * @param {String/Element} animateTarget (optional) The target element or id from which the window should
- * animate while opening (defaults to null with no animation)
- * @return {Ext.Window} this
- */
- show: function(o, animateTarget) {
- // Work around the CSS day cell height hack needed for initial render in IE8/strict:
- var anim = (Ext.isIE8 && Ext.isStrict) ? null: animateTarget;
-
- Ext.calendar.EventEditWindow.superclass.show.call(this, anim,
- function() {
- Ext.getCmp('title').focus(false, 100);
- });
- Ext.getCmp('delete-btn')[o.data && o.data[Ext.calendar.EventMappings.EventId.name] ? 'show': 'hide']();
-
- var rec,
- f = this.formPanel.form;
-
- if (o.data) {
- rec = o;
- this.isAdd = !!rec.data[Ext.calendar.EventMappings.IsNew.name];
- if (this.isAdd) {
- // Enable adding the default record that was passed in
- // if it's new even if the user makes no changes
- rec.markDirty();
- this.setTitle(this.titleTextAdd);
- }
- else {
- this.setTitle(this.titleTextEdit);
- }
-
- f.loadRecord(rec);
- }
- else {
- this.isAdd = true;
- this.setTitle(this.titleTextAdd);
-
- var M = Ext.calendar.EventMappings,
- eventId = M.EventId.name,
- start = o[M.StartDate.name],
- end = o[M.EndDate.name] || start.add('h', 1);
-
- rec = new Ext.calendar.EventRecord();
- rec.data[M.EventId.name] = this.newId++;
- rec.data[M.StartDate.name] = start;
- rec.data[M.EndDate.name] = end;
- rec.data[M.IsAllDay.name] = !!o[M.IsAllDay.name] || start.getDate() != end.clone().add(Date.MILLI, 1).getDate();
- rec.data[M.IsNew.name] = true;
-
- f.reset();
- f.loadRecord(rec);
- }
-
- if (this.calendarStore) {
- Ext.getCmp('calendar').setValue(rec.data[Ext.calendar.EventMappings.CalendarId.name]);
- }
- Ext.getCmp('date-range').setValue(rec.data);
- this.activeRecord = rec;
-
- return this;
- },
-
- // private
- roundTime: function(dt, incr) {
- incr = incr || 15;
- var m = parseInt(dt.getMinutes(), 10);
- return dt.add('mi', incr - (m % incr));
- },
-
- // private
- onCancel: function() {
- this.cleanup(true);
- this.fireEvent('eventcancel', this);
- },
-
- // private
- cleanup: function(hide) {
- if (this.activeRecord && this.activeRecord.dirty) {
- this.activeRecord.reject();
- }
- delete this.activeRecord;
-
- if (hide === true) {
- // Work around the CSS day cell height hack needed for initial render in IE8/strict:
- //var anim = afterDelete || (Ext.isIE8 && Ext.isStrict) ? null : this.animateTarget;
- this.hide();
- }
- },
-
- // private
- updateRecord: function() {
- var f = this.formPanel.form,
- dates = Ext.getCmp('date-range').getValue(),
- M = Ext.calendar.EventMappings;
-
- f.updateRecord(this.activeRecord);
- this.activeRecord.set(M.StartDate.name, dates[0]);
- this.activeRecord.set(M.EndDate.name, dates[1]);
- this.activeRecord.set(M.IsAllDay.name, dates[2]);
- this.activeRecord.set(M.CalendarId.name, this.formPanel.form.findField('calendar').getValue());
- },
-
- // private
- onSave: function() {
- if (!this.formPanel.form.isValid()) {
- return;
- }
- this.updateRecord();
-
- if (!this.activeRecord.dirty) {
- this.onCancel();
- return;
- }
-
- this.fireEvent(this.isAdd ? 'eventadd': 'eventupdate', this, this.activeRecord);
- },
-
- // private
- onDelete: function() {
- this.fireEvent('eventdelete', this, this.activeRecord);
- }
-});/**
- * @class Ext.calendar.CalendarPanel
- * @extends Ext.Panel
- * <p>This is the default container for Ext calendar views. It supports day, week and month views as well
- * as a built-in event edit form. The only requirement for displaying a calendar is passing in a valid
- * {@link #calendarStore} config containing records of type {@link Ext.calendar.EventRecord EventRecord}. In order
- * to make the calendar interactive (enable editing, drag/drop, etc.) you can handle any of the various
- * events fired by the underlying views and exposed through the CalendarPanel.</p>
- * {@link #layoutConfig} option if needed.</p>
- * @constructor
- * @param {Object} config The config object
- * @xtype calendarpanel
- */
-Ext.calendar.CalendarPanel = Ext.extend(Ext.Panel, {
- /**
- * @cfg {Boolean} showDayView
- * True to include the day view (and toolbar button), false to hide them (defaults to true).
- */
- showDayView: true,
- /**
- * @cfg {Boolean} showWeekView
- * True to include the week view (and toolbar button), false to hide them (defaults to true).
- */
- showWeekView: true,
- /**
- * @cfg {Boolean} showMonthView
- * True to include the month view (and toolbar button), false to hide them (defaults to true).
- * If the day and week views are both hidden, the month view will show by default even if
- * this config is false.
- */
- showMonthView: true,
- /**
- * @cfg {Boolean} showNavBar
- * True to display the calendar navigation toolbar, false to hide it (defaults to true). Note that
- * if you hide the default navigation toolbar you'll have to provide an alternate means of navigating the calendar.
- */
- showNavBar: true,
- /**
- * @cfg {String} todayText
- * Alternate text to use for the 'Today' nav bar button.
- */
- todayText: 'Today',
- /**
- * @cfg {Boolean} showTodayText
- * True to show the value of {@link #todayText} instead of today's date in the calendar's current day box,
- * false to display the day number(defaults to true).
- */
- showTodayText: true,
- /**
- * @cfg {Boolean} showTime
- * True to display the current time next to the date in the calendar's current day box, false to not show it
- * (defaults to true).
- */
- showTime: true,
- /**
- * @cfg {String} dayText
- * Alternate text to use for the 'Day' nav bar button.
- */
- dayText: 'Day',
- /**
- * @cfg {String} weekText
- * Alternate text to use for the 'Week' nav bar button.
- */
- weekText: 'Week',
- /**
- * @cfg {String} monthText
- * Alternate text to use for the 'Month' nav bar button.
- */
- monthText: 'Month',
-
- // private
- layoutConfig: {
- layoutOnCardChange: true,
- deferredRender: true
- },
-
- // private property
- startDate: new Date(),
-
- // private
- initComponent: function() {
- this.tbar = {
- cls: 'ext-cal-toolbar',
- border: true,
- buttonAlign: 'center',
- items: [{
- id: this.id + '-tb-prev',
- handler: this.onPrevClick,
- scope: this,
- iconCls: 'x-tbar-page-prev'
- }]
- };
-
- this.viewCount = 0;
-
- if (this.showDayView) {
- this.tbar.items.push({
- id: this.id + '-tb-day',
- text: this.dayText,
- handler: this.onDayClick,
- scope: this,
- toggleGroup: 'tb-views'
- });
- this.viewCount++;
- }
- if (this.showWeekView) {
- this.tbar.items.push({
- id: this.id + '-tb-week',
- text: this.weekText,
- handler: this.onWeekClick,
- scope: this,
- toggleGroup: 'tb-views'
- });
- this.viewCount++;
- }
- if (this.showMonthView || this.viewCount == 0) {
- this.tbar.items.push({
- id: this.id + '-tb-month',
- text: this.monthText,
- handler: this.onMonthClick,
- scope: this,
- toggleGroup: 'tb-views'
- });
- this.viewCount++;
- this.showMonthView = true;
- }
- this.tbar.items.push({
- id: this.id + '-tb-next',
- handler: this.onNextClick,
- scope: this,
- iconCls: 'x-tbar-page-next'
- });
- this.tbar.items.push('->');
-
- var idx = this.viewCount - 1;
- this.activeItem = this.activeItem === undefined ? idx: (this.activeItem > idx ? idx: this.activeItem);
-
- if (this.showNavBar === false) {
- delete this.tbar;
- this.addClass('x-calendar-nonav');
- }
-
- Ext.calendar.CalendarPanel.superclass.initComponent.call(this);
-
- this.addEvents({
- /**
- * @event eventadd
- * Fires after a new event is added to the underlying store
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was added
- */
- eventadd: true,
- /**
- * @event eventupdate
- * Fires after an existing event is updated
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was updated
- */
- eventupdate: true,
- /**
- * @event eventdelete
- * Fires after an event is removed from the underlying store
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was removed
- */
- eventdelete: true,
- /**
- * @event eventcancel
- * Fires after an event add/edit operation is canceled by the user and no store update took place
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was canceled
- */
- eventcancel: true,
- /**
- * @event viewchange
- * Fires after a different calendar view is activated (but not when the event edit form is activated)
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.CalendarView} view The view being activated (any valid {@link Ext.calendar.CalendarView CalendarView} subclass)
- * @param {Object} info Extra information about the newly activated view. This is a plain object
- * with following properties:<div class="mdetail-params"><ul>
- * <li><b><code>activeDate</code></b> : <div class="sub-desc">The currently-selected date</div></li>
- * <li><b><code>viewStart</code></b> : <div class="sub-desc">The first date in the new view range</div></li>
- * <li><b><code>viewEnd</code></b> : <div class="sub-desc">The last date in the new view range</div></li>
- * </ul></div>
- */
- viewchange: true
-
- //
- // NOTE: CalendarPanel also relays the following events from contained views as if they originated from this:
- //
- /**
- * @event eventsrendered
- * Fires after events are finished rendering in the view
- * @param {Ext.calendar.CalendarPanel} this
- */
- /**
- * @event eventclick
- * Fires after the user clicks on an event element
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was clicked on
- * @param {HTMLNode} el The DOM node that was clicked on
- */
- /**
- * @event eventover
- * Fires anytime the mouse is over an event element
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that the cursor is over
- * @param {HTMLNode} el The DOM node that is being moused over
- */
- /**
- * @event eventout
- * Fires anytime the mouse exits an event element
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that the cursor exited
- * @param {HTMLNode} el The DOM node that was exited
- */
- /**
- * @event datechange
- * Fires after the start date of the view changes
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Date} startDate The start date of the view (as explained in {@link #getStartDate}
- * @param {Date} viewStart The first displayed date in the view
- * @param {Date} viewEnd The last displayed date in the view
- */
- /**
- * @event rangeselect
- * Fires after the user drags on the calendar to select a range of dates/times in which to create an event
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Object} dates An object containing the start (StartDate property) and end (EndDate property) dates selected
- * @param {Function} callback A callback function that MUST be called after the event handling is complete so that
- * the view is properly cleaned up (shim elements are persisted in the view while the user is prompted to handle the
- * range selection). The callback is already created in the proper scope, so it simply needs to be executed as a standard
- * function call (e.g., callback()).
- */
- /**
- * @event eventmove
- * Fires after an event element is dragged by the user and dropped in a new position
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was moved with
- * updated start and end dates
- */
- /**
- * @event initdrag
- * Fires when a drag operation is initiated in the view
- * @param {Ext.calendar.CalendarPanel} this
- */
- /**
- * @event eventresize
- * Fires after the user drags the resize handle of an event to resize it
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was resized
- * containing the updated start and end dates
- */
- /**
- * @event dayclick
- * Fires after the user clicks within a day/week view container and not on an event element
- * @param {Ext.calendar.CalendarPanel} this
- * @param {Date} dt The date/time that was clicked on
- * @param {Boolean} allday True if the day clicked on represents an all-day box, else false.
- * @param {Ext.Element} el The Element that was clicked on
- */
- });
-
- this.layout = 'card';
- // do not allow override
- if (this.showDayView) {
- var day = Ext.apply({
- xtype: 'dayview',
- title: this.dayText,
- showToday: this.showToday,
- showTodayText: this.showTodayText,
- showTime: this.showTime
- },
- this.dayViewCfg);
-
- day.id = this.id + '-day';
- day.store = day.store || this.eventStore;
- this.initEventRelay(day);
- this.add(day);
- }
- if (this.showWeekView) {
- var wk = Ext.applyIf({
- xtype: 'weekview',
- title: this.weekText,
- showToday: this.showToday,
- showTodayText: this.showTodayText,
- showTime: this.showTime
- },
- this.weekViewCfg);
-
- wk.id = this.id + '-week';
- wk.store = wk.store || this.eventStore;
- this.initEventRelay(wk);
- this.add(wk);
- }
- if (this.showMonthView) {
- var month = Ext.applyIf({
- xtype: 'monthview',
- title: this.monthText,
- showToday: this.showToday,
- showTodayText: this.showTodayText,
- showTime: this.showTime,
- listeners: {
- 'weekclick': {
- fn: function(vw, dt) {
- this.showWeek(dt);
- },
- scope: this
- }
- }
- },
- this.monthViewCfg);
-
- month.id = this.id + '-month';
- month.store = month.store || this.eventStore;
- this.initEventRelay(month);
- this.add(month);
- }
-
- this.add(Ext.applyIf({
- xtype: 'eventeditform',
- id: this.id + '-edit',
- calendarStore: this.calendarStore,
- listeners: {
- 'eventadd': {
- scope: this,
- fn: this.onEventAdd
- },
- 'eventupdate': {
- scope: this,
- fn: this.onEventUpdate
- },
- 'eventdelete': {
- scope: this,
- fn: this.onEventDelete
- },
- 'eventcancel': {
- scope: this,
- fn: this.onEventCancel
- }
- }
- },
- this.editViewCfg));
- },
-
- // private
- initEventRelay: function(cfg) {
- cfg.listeners = cfg.listeners || {};
- cfg.listeners.afterrender = {
- fn: function(c) {
- // relay the view events so that app code only has to handle them in one place
- this.relayEvents(c, ['eventsrendered', 'eventclick', 'eventover', 'eventout', 'dayclick',
- 'eventmove', 'datechange', 'rangeselect', 'eventdelete', 'eventresize', 'initdrag']);
- },
- scope: this,
- single: true
- };
- },
-
- // private
- afterRender: function() {
- Ext.calendar.CalendarPanel.superclass.afterRender.call(this);
- this.fireViewChange();
- },
-
- // private
- onLayout: function() {
- Ext.calendar.CalendarPanel.superclass.onLayout.call(this);
- if (!this.navInitComplete) {
- this.updateNavState();
- this.navInitComplete = true;
- }
- },
-
- // private
- onEventAdd: function(form, rec) {
- rec.data[Ext.calendar.EventMappings.IsNew.name] = false;
- this.eventStore.add(rec);
- this.hideEditForm();
- this.fireEvent('eventadd', this, rec);
- },
-
- // private
- onEventUpdate: function(form, rec) {
- rec.commit();
- this.hideEditForm();
- this.fireEvent('eventupdate', this, rec);
- },
-
- // private
- onEventDelete: function(form, rec) {
- this.eventStore.remove(rec);
- this.hideEditForm();
- this.fireEvent('eventdelete', this, rec);
- },
-
- // private
- onEventCancel: function(form, rec) {
- this.hideEditForm();
- this.fireEvent('eventcancel', this, rec);
- },
-
- /**
- * Shows the built-in event edit form for the passed in event record. This method automatically
- * hides the calendar views and navigation toolbar. To return to the calendar, call {@link #hideEditForm}.
- * @param {Ext.calendar.EventRecord} record The event record to edit
- * @return {Ext.calendar.CalendarPanel} this
- */
- showEditForm: function(rec) {
- this.preEditView = this.layout.activeItem.id;
- this.setActiveView(this.id + '-edit');
- this.layout.activeItem.loadRecord(rec);
- return this;
- },
-
- /**
- * Hides the built-in event edit form and returns to the previous calendar view. If the edit form is
- * not currently visible this method has no effect.
- * @return {Ext.calendar.CalendarPanel} this
- */
- hideEditForm: function() {
- if (this.preEditView) {
- this.setActiveView(this.preEditView);
- delete this.preEditView;
- }
- return this;
- },
-
- // private
- setActiveView: function(id) {
- var l = this.layout;
- l.setActiveItem(id);
-
- if (id == this.id + '-edit') {
- this.getTopToolbar().hide();
- this.doLayout();
- }
- else {
- l.activeItem.refresh();
- this.getTopToolbar().show();
- this.updateNavState();
- }
- this.activeView = l.activeItem;
- this.fireViewChange();
- },
-
- // private
- fireViewChange: function() {
- var info = null,
- view = this.layout.activeItem;
-
- if (view.getViewBounds) {
- vb = view.getViewBounds();
- info = {
- activeDate: view.getStartDate(),
- viewStart: vb.start,
- viewEnd: vb.end
- };
- };
- this.fireEvent('viewchange', this, view, info);
- },
-
- // private
- updateNavState: function() {
- if (this.showNavBar !== false) {
- var item = this.layout.activeItem,
- suffix = item.id.split(this.id + '-')[1];
-
- var btn = Ext.getCmp(this.id + '-tb-' + suffix);
- btn.toggle(true);
- }
- },
-
- /**
- * Sets the start date for the currently-active calendar view.
- * @param {Date} dt
- */
- setStartDate: function(dt) {
- this.layout.activeItem.setStartDate(dt, true);
- this.updateNavState();
- this.fireViewChange();
- },
-
- // private
- showWeek: function(dt) {
- this.setActiveView(this.id + '-week');
- this.setStartDate(dt);
- },
-
- // private
- onPrevClick: function() {
- this.startDate = this.layout.activeItem.movePrev();
- this.updateNavState();
- this.fireViewChange();
- },
-
- // private
- onNextClick: function() {
- this.startDate = this.layout.activeItem.moveNext();
- this.updateNavState();
- this.fireViewChange();
- },
-
- // private
- onDayClick: function() {
- this.setActiveView(this.id + '-day');
- },
-
- // private
- onWeekClick: function() {
- this.setActiveView(this.id + '-week');
- },
-
- // private
- onMonthClick: function() {
- this.setActiveView(this.id + '-month');
- },
-
- /**
- * Return the calendar view that is currently active, which will be a subclass of
- * {@link Ext.calendar.CalendarView CalendarView}.
- * @return {Ext.calendar.CalendarView} The active view
- */
- getActiveView: function() {
- return this.layout.activeItem;
- }
-});
-
-Ext.reg('calendarpanel', Ext.calendar.CalendarPanel);
\ No newline at end of file