source: trunk/prototype/app/plugins/fullcalendar/fullcalendar.year.js @ 5341

Revision 5341, 15.4 KB checked in by wmerlotto, 12 years ago (diff)

Ticket #2434 - Commit inicial do novo módulo de agenda do Expresso - expressoCalendar

Line 
1//Year View Start ----------------------------------------------------------------------------------
2//add by kebin --> 6
3fcViews.year = YearView;
4
5function YearView(element, calendar) {
6        var t = this;
7        // exports
8        t.render = render;
9       
10       
11        // imports
12        BasicYearView.call(t, element, calendar, 'year');
13        var opt = t.opt;
14        var renderYear = t.renderYear;
15        var formatDate = calendar.formatDate;
16        function render(date, delta) {
17                if (delta) {
18                        addYears(date, delta);
19                }
20                var start = cloneDate(date, true);             
21                start.setFullYear(start.getFullYear(),0,1);
22                var end = cloneDate(start);
23                end.setFullYear(end.getFullYear(), 11,31);
24                var visStart = cloneDate(start); //set startDay
25                var visEnd = cloneDate(end);
26                var firstDay = opt('firstDay');
27                var nwe = opt('weekends') ? 0 : 1;
28                rowCnt = 54;
29                t.title = formatDate(start, opt('titleFormat'));
30                t.start = start;
31                t.end = end;
32                t.visStart = visStart;
33                t.visEnd = visEnd;
34                renderYear(rowCnt, nwe ? 5 : 7, true);
35        }
36}
37
38function BasicYearView(element, calendar, viewName) {
39        var t = this;
40       
41        // exports
42        t.renderYear = renderYear;
43        t.setHeight = setHeight;
44        t.setWidth = setWidth;
45        t.renderDayOverlay = renderDayOverlay;
46        t.defaultSelectionEnd = defaultSelectionEnd;
47        t.renderSelection = renderSelection;
48        t.clearSelection = clearSelection;
49        t.reportDayClick = reportDayClick; // for selection (kinda hacky)
50        t.dragStart = dragStart;
51        t.dragStop = dragStop;
52        t.defaultEventEnd = defaultEventEnd;
53        t.getHoverListener = function() { return hoverListener };
54        t.colContentLeft = colContentLeft;
55        t.colContentRight = colContentRight;
56        t.dayOfWeekCol = dayOfWeekCol;
57        t.dateCell = dateCell;
58        t.cellDate = cellDate;
59        t.cellIsAllDay = function() { return true };
60        t.allDayRow = allDayRow;
61        t.allDayBounds = allDayBounds;
62        t.getRowCnt = function() { return rowCnt };
63        t.getColCnt = function() { return colCnt };
64        t.getColWidth = function() { return colWidth };
65        t.getDaySegmentContainer = function() { return daySegmentContainer };
66       
67       
68        // imports
69        View.call(t, element, calendar, viewName);
70        OverlayManager.call(t);
71        SelectionManager.call(t);
72        BasicYearEventRenderer.call(t);
73        var opt = t.opt;
74        var trigger = t.trigger;
75        var clearEvents = t.clearEvents;
76        var renderOverlay = t.renderOverlay;
77        var clearOverlays = t.clearOverlays;
78        var daySelectionMousedown = t.daySelectionMousedown;
79        var formatDate = calendar.formatDate;
80       
81       
82        // locals
83       
84        var head;
85        var headCells;
86        var body;
87        var bodyRows;
88        var bodyCells;
89        var bodyFirstCells;
90        var bodyCellTopInners;
91        var daySegmentContainer;
92       
93        var viewWidth;
94        var viewHeight;
95        var colWidth;
96       
97        var rowCnt, colCnt;
98        var coordinateGrid;
99        var hoverListener;
100        var colContentPositions;
101       
102        var rtl, dis, dit;
103        var firstDay;
104        var nwe;
105        var tm;
106        var colFormat;
107       
108       
109       
110        /* Rendering
111        ------------------------------------------------------------*/
112       
113       
114        disableTextSelection(element.addClass('fc-grid'));
115       
116       
117        function renderYear(maxr, r, c, showNumbers) {
118                rowCnt = r;
119                colCnt = c;
120                updateOptions();
121                var firstTime = !body;
122                if (firstTime) {
123                        buildSkeleton(maxr, showNumbers);
124                }else{
125                        clearEvents();
126                }
127                updateCells(firstTime);
128        }
129       
130       
131       
132        function updateOptions() {
133                rtl = opt('isRTL');
134                if (rtl) {
135                        dis = -1;
136                        dit = colCnt - 1;
137                }else{
138                        dis = 1;
139                        dit = 0;
140                }
141                firstDay = opt('firstDay');
142                nwe = opt('weekends') ? 0 : 1;
143                tm = opt('theme') ? 'ui' : 'fc';
144                colFormat = opt('columnFormat');
145        }
146       
147       
148       
149        function buildSkeleton(maxRowCnt, showNumbers) {
150                var s;
151                var headerClass = tm + "-widget-header";
152                var contentClass = tm + "-widget-content";
153                var i, j;
154                var table;
155               
156                s =
157                        "<table class='fc-border-separate' style='width:100%' cellspacing='0'>" +
158                        "<thead>" +
159                        "<tr>";
160                for (i=0; i<colCnt; i++) {
161                        s +=
162                                "<th class='fc- " + headerClass + "'/>"; // need fc- for setDayID
163                }
164                s +=
165                        "</tr>" +
166                        "</thead>" +
167                        "<tbody>";
168                for (i=0; i<maxRowCnt; i++) {
169                        s +=
170                                "<tr class='fc-week" + i + "'>";
171                        for (j=0; j<colCnt; j++) {
172                                s +=
173                                        "<td class='fc- " + contentClass + " fc-day" + (i*colCnt+j) + "'>" + // need fc- for setDayID
174                                        "<div>" +
175                                        (showNumbers ?
176                                                "<div class='fc-day-number'/>" :
177                                                ''
178                                                ) +
179                                        "<div class='fc-day-content'>" +
180                                        "<div style='position:relative'>&nbsp;</div>" +
181                                        "</div>" +
182                                        "</div>" +
183                                        "</td>";
184                        }
185                        s +=
186                                "</tr>";
187                }
188                s +=
189                        "</tbody>" +
190                        "</table>";
191                table = $(s).appendTo(element);
192               
193                head = table.find('thead');
194                headCells = head.find('th');
195                body = table.find('tbody');
196                bodyRows = body.find('tr');
197                bodyCells = body.find('td');
198                bodyFirstCells = bodyCells.filter(':first-child');
199                bodyCellTopInners = bodyRows.eq(0).find('div.fc-day-content div');
200               
201                markFirstLast(head.add(head.find('tr'))); // marks first+last tr/th's
202                markFirstLast(bodyRows); // marks first+last td's
203                bodyRows.eq(0).addClass('fc-first'); // fc-last is done in updateCells
204               
205                dayBind(bodyCells);
206               
207                daySegmentContainer =
208                        $("<div style='position:absolute;z-index:8;top:0;left:0'/>")
209                                .appendTo(element);
210        }
211       
212       
213       
214        function updateCells(firstTime) {
215                var dowDirty = firstTime || rowCnt == 1; // could the cells' day-of-weeks need updating?
216                var month = t.start.getMonth();
217                var today = clearTime(new Date());
218                var cell;
219                var date;
220                var row;
221       
222                if (dowDirty) {
223                        headCells.each(function(i, _cell) {
224                                cell = $(_cell);
225                                date = indexDate(i);
226                                cell.html(formatDate(date, colFormat));
227                                setDayID(cell, date);
228                        });
229                }
230               
231                bodyCells.each(function(i, _cell) {
232                        cell = $(_cell);
233                        date = indexDate(i);
234                        if (date.getMonth() == month) {
235                                cell.removeClass('fc-other-month');
236                        }else{
237                                cell.addClass('fc-other-month');
238                        }
239                        if (+date == +today) {
240                                cell.addClass(tm + '-state-highlight fc-today');
241                        }else{
242                                cell.removeClass(tm + '-state-highlight fc-today');
243                        }
244                        cell.find('div.fc-day-number').text(date.getDate());
245                        if (dowDirty) {
246                                setDayID(cell, date);
247                        }
248                });
249               
250                bodyRows.each(function(i, _row) {
251                        row = $(_row);
252                        if (i < rowCnt) {
253                                row.show();
254                                if (i == rowCnt-1) {
255                                        row.addClass('fc-last');
256                                }else{
257                                        row.removeClass('fc-last');
258                                }
259                        }else{
260                                row.hide();
261                        }
262                });
263        }
264       
265       
266       
267        function setHeight(height) {
268                viewHeight = height;
269               
270                var bodyHeight = viewHeight - head.height();
271                var rowHeight;
272                var rowHeightLast;
273                var cell;
274                       
275                if (opt('weekMode') == 'variable') {
276                        rowHeight = rowHeightLast = Math.floor(bodyHeight / (rowCnt==1 ? 2 : 6));
277                }else{
278                        rowHeight = Math.floor(bodyHeight / rowCnt);
279                        rowHeightLast = bodyHeight - rowHeight * (rowCnt-1);
280                }
281               
282                bodyFirstCells.each(function(i, _cell) {
283                        if (i < rowCnt) {
284                                cell = $(_cell);
285                                setMinHeight(
286                                        cell.find('> div'),
287                                        (i==rowCnt-1 ? rowHeightLast : rowHeight) - vsides(cell)
288                                );
289                        }
290                });
291               
292        }
293       
294       
295        function setWidth(width) {
296                viewWidth = width;
297                colContentPositions.clear();
298                colWidth = Math.floor(viewWidth / colCnt);
299                setOuterWidth(headCells.slice(0, -1), colWidth);
300        }
301       
302       
303       
304        /* Day clicking and binding
305        -----------------------------------------------------------*/
306       
307       
308        function dayBind(days) {
309                days.click(dayClick)
310                        .mousedown(daySelectionMousedown);
311        }
312       
313       
314        function dayClick(ev) {
315                if (!opt('selectable')) { // if selectable, SelectionManager will worry about dayClick
316                        var index = parseInt(this.className.match(/fc\-day(\d+)/)[1]); // TODO: maybe use .data
317                        var date = indexDate(index);
318                        trigger('dayClick', this, date, true, ev);
319                }
320        }
321       
322       
323       
324        /* Semi-transparent Overlay Helpers
325        ------------------------------------------------------*/
326       
327       
328        function renderDayOverlay(overlayStart, overlayEnd, refreshCoordinateGrid) { // overlayEnd is exclusive
329                if (refreshCoordinateGrid) {
330                        coordinateGrid.build();
331                }
332                var rowStart = cloneDate(t.visStart);
333                var rowEnd = addDays(cloneDate(rowStart), colCnt);
334                for (var i=0; i<rowCnt; i++) {
335                        var stretchStart = new Date(Math.max(rowStart, overlayStart));
336                        var stretchEnd = new Date(Math.min(rowEnd, overlayEnd));
337                        if (stretchStart < stretchEnd) {
338                                var colStart, colEnd;
339                                if (rtl) {
340                                        colStart = dayDiff(stretchEnd, rowStart)*dis+dit+1;
341                                        colEnd = dayDiff(stretchStart, rowStart)*dis+dit+1;
342                                }else{
343                                        colStart = dayDiff(stretchStart, rowStart);
344                                        colEnd = dayDiff(stretchEnd, rowStart);
345                                }
346                                dayBind(
347                                        renderCellOverlay(i, colStart, i, colEnd-1)
348                                );
349                        }
350                        addDays(rowStart, 7);
351                        addDays(rowEnd, 7);
352                }
353        }
354       
355       
356        function renderCellOverlay(row0, col0, row1, col1) { // row1,col1 is inclusive
357                var rect = coordinateGrid.rect(row0, col0, row1, col1, element);
358                return renderOverlay(rect, element);
359        }
360       
361       
362       
363        /* Selection
364        -----------------------------------------------------------------------*/
365       
366       
367        function defaultSelectionEnd(startDate, allDay) {
368                return cloneDate(startDate);
369        }
370       
371       
372        function renderSelection(startDate, endDate, allDay) {
373                renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); // rebuild every time???
374        }
375       
376       
377        function clearSelection() {
378                clearOverlays();
379        }
380       
381       
382        function reportDayClick(date, allDay, ev) {
383                var cell = dateCell(date);
384                var _element = bodyCells[cell.row*colCnt + cell.col];
385                trigger('dayClick', _element, date, allDay, ev);
386        }
387       
388       
389       
390        /* External Dragging
391        -----------------------------------------------------------------------*/
392       
393       
394        function dragStart(_dragElement, ev, ui) {
395                hoverListener.start(function(cell) {
396                        clearOverlays();
397                        if (cell) {
398                                renderCellOverlay(cell.row, cell.col, cell.row, cell.col);
399                        }
400                }, ev);
401        }
402       
403       
404        function dragStop(_dragElement, ev, ui) {
405                var cell = hoverListener.stop();
406                clearOverlays();
407                if (cell) {
408                        var d = cellDate(cell);
409                        trigger('drop', _dragElement, d, true, ev, ui);
410                }
411        }
412       
413       
414       
415        /* Utilities
416        --------------------------------------------------------*/
417       
418       
419        function defaultEventEnd(event) {
420                return cloneDate(event.start);
421        }
422       
423       
424        coordinateGrid = new CoordinateGrid(function(rows, cols) {
425                var e, n, p;
426                headCells.each(function(i, _e) {
427                        e = $(_e);
428                        n = e.offset().left;
429                        if (i) {
430                                p[1] = n;
431                        }
432                        p = [n];
433                        cols[i] = p;
434                });
435                p[1] = n + e.outerWidth();
436                bodyRows.each(function(i, _e) {
437                        if (i < rowCnt) {
438                                e = $(_e);
439                                n = e.offset().top;
440                                if (i) {
441                                        p[1] = n;
442                                }
443                                p = [n];
444                                rows[i] = p;
445                        }
446                });
447                p[1] = n + e.outerHeight();
448        });
449       
450       
451        hoverListener = new HoverListener(coordinateGrid);
452       
453       
454        colContentPositions = new HorizontalPositionCache(function(col) {
455                return bodyCellTopInners.eq(col);
456        });
457       
458       
459        function colContentLeft(col) {
460                return colContentPositions.left(col);
461        }
462       
463       
464        function colContentRight(col) {
465                return colContentPositions.right(col);
466        }
467       
468       
469       
470       
471        function dateCell(date) {
472                return {
473                        row: Math.floor(dayDiff(date, t.visStart) / 7),
474                        col: dayOfWeekCol(date.getDay())
475                };
476        }
477       
478       
479        function cellDate(cell) {
480                return _cellDate(cell.row, cell.col);
481        }
482       
483       
484        function _cellDate(row, col) {
485                return addDays(cloneDate(t.visStart), row*7 + col*dis+dit);
486                // what about weekends in middle of week?
487        }
488       
489       
490        function indexDate(index) {
491                return _cellDate(Math.floor(index/colCnt), index%colCnt);
492        }
493       
494       
495        function dayOfWeekCol(dayOfWeek) {
496                return ((dayOfWeek - Math.max(firstDay, nwe) + colCnt) % colCnt) * dis + dit;
497        }
498       
499       
500       
501       
502        function allDayRow(i) {
503                return bodyRows.eq(i);
504        }
505       
506       
507        function allDayBounds(i) {
508                return {
509                        left: 0,
510                        right: viewWidth
511                };
512        }
513       
514       
515}
516
517function BasicYearEventRenderer() {
518        var t = this;
519       
520       
521        // exports
522        t.renderEvents = renderEvents;
523        t.compileDaySegs = compileSegs; // for DayEventRenderer
524        t.clearEvents = clearEvents;
525        t.bindDaySeg = bindDaySeg;
526       
527       
528        // imports
529        DayEventRenderer.call(t);
530        var opt = t.opt;
531        var trigger = t.trigger;
532        //var setOverflowHidden = t.setOverflowHidden;
533        var isEventDraggable = t.isEventDraggable;
534        var isEventResizable = t.isEventResizable;
535        var reportEvents = t.reportEvents;
536        var reportEventClear = t.reportEventClear;
537        var eventElementHandlers = t.eventElementHandlers;
538        var showEvents = t.showEvents;
539        var hideEvents = t.hideEvents;
540        var eventDrop = t.eventDrop;
541        var getDaySegmentContainer = t.getDaySegmentContainer;
542        var getHoverListener = t.getHoverListener;
543        var renderDayOverlay = t.renderDayOverlay;
544        var clearOverlays = t.clearOverlays;
545        var getRowCnt = t.getRowCnt;
546        var getColCnt = t.getColCnt;
547        var renderDaySegs = t.renderDaySegs;
548        var resizableDayEvent = t.resizableDayEvent;
549       
550       
551       
552        /* Rendering
553        --------------------------------------------------------------------*/
554       
555       
556        function renderEvents(events, modifiedEventId) {
557                reportEvents(events);
558                renderDaySegs(compileSegs(events), modifiedEventId);
559        }
560       
561       
562        function clearEvents() {
563                reportEventClear();
564                getDaySegmentContainer().empty();
565        }
566       
567       
568        function compileSegs(events) {
569                var rowCnt = getRowCnt(),
570                        colCnt = getColCnt(),
571                        d1 = cloneDate(t.visStart),
572                        d2 = addDays(cloneDate(d1), colCnt),
573                        visEventsEnds = $.map(events, exclEndDay),
574                        i, row,
575                        j, level,
576                        k, seg,
577                        segs=[];
578                for (i=0; i<rowCnt; i++) {
579                        row = stackSegs(sliceSegs(events, visEventsEnds, d1, d2));
580                        for (j=0; j<row.length; j++) {
581                                level = row[j];
582                                for (k=0; k<level.length; k++) {
583                                        seg = level[k];
584                                        seg.row = i;
585                                        seg.level = j; // not needed anymore
586                                        segs.push(seg);
587                                }
588                        }
589                        addDays(d1, 7);
590                        addDays(d2, 7);
591                }
592                return segs;
593        }
594       
595       
596        function bindDaySeg(event, eventElement, seg) {
597                if (isEventDraggable(event)) {
598                        draggableDayEvent(event, eventElement);
599                }
600                if (seg.isEnd && isEventResizable(event)) {
601                        resizableDayEvent(event, eventElement, seg);
602                }
603                eventElementHandlers(event, eventElement);
604                        // needs to be after, because resizableDayEvent might stopImmediatePropagation on click
605        }
606       
607       
608       
609        /* Dragging
610        ----------------------------------------------------------------------------*/
611       
612       
613        function draggableDayEvent(event, eventElement) {
614                var hoverListener = getHoverListener();
615                var dayDelta;
616                eventElement.draggable({
617                        zIndex: 9,
618                        delay: 50,
619                        opacity: opt('dragOpacity'),
620                        revertDuration: opt('dragRevertDuration'),
621                        start: function(ev, ui) {
622                                trigger('eventDragStart', eventElement, event, ev, ui);
623                                hideEvents(event, eventElement);
624                                hoverListener.start(function(cell, origCell, rowDelta, colDelta) {
625                                        eventElement.draggable('option', 'revert', !cell || !rowDelta && !colDelta);
626                                        clearOverlays();
627                                        if (cell) {
628                                                //setOverflowHidden(true);
629                                                dayDelta = rowDelta*7 + colDelta * (opt('isRTL') ? -1 : 1);
630                                                renderDayOverlay(
631                                                        addDays(cloneDate(event.start), dayDelta),
632                                                        addDays(exclEndDay(event), dayDelta)
633                                                );
634                                        }else{
635                                                //setOverflowHidden(false);
636                                                dayDelta = 0;
637                                        }
638                                }, ev, 'drag');
639                        },
640                        stop: function(ev, ui) {
641                                hoverListener.stop();
642                                clearOverlays();
643                                trigger('eventDragStop', eventElement, event, ev, ui);
644                                if (dayDelta) {
645                                        eventDrop(this, event, dayDelta, 0, event.allDay, ev, ui);
646                                }else{
647                                        eventElement.css('filter', ''); // clear IE opacity side-effects
648                                        showEvents(event, eventElement);
649                                }
650                                //setOverflowHidden(false);
651                        }
652                });
653        }
654
655
656}
657
658// Year View END ----------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.