星期三, 10月 05, 2011

How to make your view in FullCalendar: the hack way 如何硬改FullCalendar做出自己的View

因為FullCalendar的變數命名空間及呼叫方式,要在不動原始.js檔情況下建立自己的View很困難,因此先用「硬改」fullcalendar.js 的方式。

It's difficult to make a new view without modifying the source code of "fullcalendar.js", thus I chose the easy way.


環境說明:
Versions of components:
jQuery 1.6.4、jQuery UI 1.8.6、FullCalendar 1.5.2

在編輯器打開 fullcalendar.js ,找 「fcViews.agendaDay = AgendaDayView;」,加上以下這段文字:
Open fullcalendar in your text editor, find " AgendaDayView;", add following words before that.
    fcViews.agendaList = agendaListView;
    function agendaListView(element, calendar, viewName) {
        var t = this;
        function dayClick(ev) {
        }
        function trigger(name, thisObj) {
        }
        // exports
        t.render = render;

        t.setHeight = setHeight;
        t.setWidth = setWidth;

        t.renderEvents = renderEvents;

        // pseudo method...
        t.unselect = function() {
        };

        t.clearEvents = clearEvents;
        //another way to write pseudo method
        function clearEvents() {
        }

        function setHeight(height, dateChanged) {
        }

        function setWidth(width) {
        }

        // imports
        View.call(t, element, calendar, 'agendaList');
        var opt = t.opt;

        //var renderAgenda = t.renderAgenda;
        var formatDate = calendar.formatDate;

        function sortEvent(a, b) {
            return a.start - b.start;
        }

        function render(date, delta) {
            if (delta) {
                addDays(date, delta);
                if (!opt('weekends')) {
                    skipWeekend(date, delta < 0 ? -1 : 1);
                }
            }
            var start = cloneDate(date, true);
            var end = addDays(cloneDate(start), 1);
            t.title = formatDate(date, opt('titleFormat'));
            t.start = t.visStart = start;
            t.end = t.visEnd = end;
        }

        function eventsOfThisDay(events, theDate) {
            var start = new Date(theDate.toString("yyyy/MM/dd 00:00")); // It's a good format for me...
            var end = new Date(theDate.toString("yyyy/MM/dd 23:59:59"));
            var retArr = new Array();
            for (i in events) {
                if (events[i].start <= end && events[i].end >= start) {
                    retArr.push(events[i]);
                }
            }
            return retArr;
        }

        function getListDateString(event) {
            var ret = "";
            if (event.allDay) { //all day event
                ret = opt('allDayText');
            }
            else {
                ret = event.start.toString("HH:mm") + "~" + event.end.toString("HH:mm"); // You can change format here
            }
            return ret;
        }

        function renderEvents(events, modifiedEventId) {
            // render grid here

            var sortedEvents = events.sort(sortEvent);

            var x = ""; // "";
            var total = sortedEvents.length;
            if (total > 0) {
                var start = cloneDate(sortedEvents[0].start);
                var dateVar = cloneDate(start);
                var end = cloneDate(sortedEvents[total - 1].start);
                while (dateVar <= end) {
                    var arr = eventsOfThisDay(sortedEvents, dateVar);
                    if (arr.length > 0) {
                        x += "";
                        for (i in arr) {
                            x += "";
                            x += "";
                        }
                    }
                    dateVar=dateVar.addDays(1);
                }
            }
            x += "
"; x += dateVar.toString(opt('titleFormat')); x += "
";
x += getListDateString(arr[i]);
x += "
";
x += ""; x += classtemp.replace(",", " "); //Avoid className is array x += arr[i].title; x += "
"; $('.fc-view-agendaList').html(x); //direct output XDDD } function rerenderEvents(modifiedEventId) { } } setDefaults({ titleFormat: { list: 'yyyy/MMM/d dddd' }, columnFormat: { list: 'M/d dddd' }, buttonText: { list: 'List' } });

再加一個list.css或是加在fullcalendar.css裏:

.fc-list-table
{
    margin: 10px;
    border-style: hidden;
    border-width: 10px;
    padding: 10px;
    vertical-align: top;
    width: 100%;
}
.fc-list-table tr:hover
{
    color: #0000FF;
    background-color: #CCFFCC;
}
.fc-list-date
{
    margin: 16px;
    white-space: nowrap;
    text-align: left;
    width: 100%;
    background-color: #808080;
    color: #FFFFFF;
    font-weight: bold;
    font-family: Arial, Helvetica, sans-serif;
}
.fc-list-time
{
    text-align: center;
    white-space: nowrap;
    width: 1%;
}
.fc-list-event
{
     text-align: left;
     cursor: pointer;
}

原始碼放在github上,請自便。 The source codes are on github, get that if you need.

2 則留言:

456y72345 提到...

fullcalendar 支援 jquery 1.6版嗎?

鳥毅 提到...

耶....你沒看文章耶。
『環境說明:jQuery 1.6.4、jQuery UI 1.8.6、FullCalendar 1.5.2』

之前jQuery UI到 1.8.16的拖拉都不支援jQuery 1.7+,現在jQuery UI 1.8.17+之後就支援Drap and Drop,所以也讓FullCalendar 支援到jQuery 1.7+,不過正式支援jQuery 1.7+應該是FullCalendar 1.5.3。