X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/b37ceabb82336ee82757cd32efe353cfab8ec267..f5240829880f87e0cf581c6a296e436fdef0ef80:/examples/docs/source/DayBodyView.html diff --git a/examples/docs/source/DayBodyView.html b/examples/docs/source/DayBodyView.html new file mode 100644 index 00000000..0a945cb7 --- /dev/null +++ b/examples/docs/source/DayBodyView.html @@ -0,0 +1,458 @@ + + + + The source code + + + + +
/*!
+ * Ext JS Library 3.3.0
+ * Copyright(c) 2006-2010 Ext JS, Inc.
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+
/**S + * @class Ext.calendar.DayBodyView + * @extends Ext.calendar.CalendarView + *

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}.

+ * @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)

True to slightly defer the call, false to execute immediately.

+ *

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.

+ *

Note that this method should not generally need to be called directly as scroll position is managed internally.

+ */ + 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}', + '', + ' ', + '', + '', + ' ', + '' + // '', + // ' ', + // '', + // '', + // ' ', + // '' + ].join(''); + } + return this.eventBodyMarkup; + }, + + // inherited docs + getEventTemplate: function() { + if (!this.eventTpl) { + this.eventTpl = !(Ext.isIE || Ext.isOpera) ? + new Ext.XTemplate( + '
', + '
', this.getEventBodyMarkup(), '
', + '
 
', + '
' + ) + : new Ext.XTemplate( + '
', + '
 
', + '
', + '
', + this.getEventBodyMarkup(), + '
', + '
 
', + '
', + '
 
', + '
' + ); + this.eventTpl.compile(); + } + return this.eventTpl; + }, + +
/** + *

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 all-day 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.

+ *

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.

+ * @return {Ext.XTemplate} The event XTemplate + */ + getEventAllDayTemplate: function() { + if (!this.eventAllDayTpl) { + var tpl, + body = this.getEventBodyMarkup(); + + tpl = !(Ext.isIE || Ext.isOpera) ? + new Ext.XTemplate( + '
', + body, + '
' + ) + : new Ext.XTemplate( + '
', + '
', + '
', + '
', + body, + '
', + '
', + '
' + ); + 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); +
+ + \ No newline at end of file