Giter Site home page Giter Site logo

themouette / jquery-week-calendar Goto Github PK

View Code? Open in Web Editor NEW

This project forked from robmonie/jquery-week-calendar

719.0 61.0 254.0 1.55 MB

A weekly calendar plugin based on jquery and jquery-ui

Home Page: http://groups.google.com/group/jquery-week-calendar

JavaScript 100.00%

jquery-week-calendar's People

Contributors

adammeghji avatar andrzej-aa avatar bojanpejic avatar brokenseal avatar crevillo avatar darkbreton avatar felix-sigac avatar jlew avatar k-phoen avatar kuahyeow avatar ludovicpelle avatar manentia avatar nnarhinen avatar pablogd avatar powermick avatar robmonie avatar themouette avatar xnopre avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jquery-week-calendar's Issues

displaying events with equal start and end

this is a dirty fix, but it will do the trick ...

change line 1274 from
if ( start < initialEnd ) {
to
if ( start <= initialEnd ) {

change line 1508 from
$calEvent.css({top: pxTop, height: pxHeight});
to
var pxHeightFallback = pxPerMillis * (60 / options.timeslotsPerHour) * 60 * 1000;
$calEvent.css({top: pxTop, height: pxHeight || pxHeightFallback});

if someone has got a better solution, please post!

Fast Switching of Weeks Causes Ajax Error

Using Safari, Chrome or Firefox (not sure about IE), with an ajax data source for the calendar data, if the user presses the 'next' or 'previous' buttons in rapid succession an alert is shown saying "unable to get data, error:"

This is caused by _currentAjaxCall.abort(); which fires the xhr objects error callback.

I recommend changing:
error: function(XMLHttpRequest, textStatus, errorThrown){
alert('unable to get data, error:' + textStatus);
}

to look for the 'abort' error, and then ignoring it.
error: function(XMLHttpRequest, textStatus, errorThrown){
if(errorThrown != 'abort'){
alert('unable to get data, error:' + textStatus);
}
}

Note that errorThrown and textStatus are just "error" with jQuery <= 1.4.4 and "abort" with jQuery 1.5.

As an aside:
I know jQuery 1.5 is brand-new, is weekCalendar compatible?

Multiple instances aborts each other ajax requests

Hello everyone,
I'm new here and don't have commit privilege.
I've already improved this scirpt for my purposes like that

Don't use global variable! like here(line 19)
(function($) {
var _currentAjaxCall;

Put it as object option instead. like here(line22)
options: {
_currentAjaxCall: false,
date: new Date(),

and now when you want to talk to this variable add "options." each time like:
options._currentAjaxCall
these are in lines 1113, 11211, 1132

cheers,
Pawel

Cachable events

we are using weekCalendar with 2 different eventSources, as we are using 2 different eventTypes. one of this eventSource has a dynamic parameter (user) as well ...

to get some idea of our user-interface: http://dl.dropbox.com/u/21379421/weekCalendar.PNG

first problem: weekCalendar does not support multiple eventSources
second problem: weekCalendar does not support any caching of events - so clicking prev and next causes retrieving the same events from the eventSource...

var cachableEventManager = {
    settings: {
        queryStringParameters: {
            start: 'start',
            end: 'end',
            userIds: 'userIds',
            transformUserIds: function (userIds) {
                return userIds;
            },
            transformStartDate: function (startDate) {
                return startDate.getTime() / 1000;
            },
            transformEndDate: function (endDate) {
                return endDate.getTime() / 1000;
            }
        },
        additionalDays: 7, // how many should be removed from startDate and added to endDate
        sources: null, // define an array with strings (= plain urls) or objects with properties url and data
        eventLoading: null, // this will be kicked off, if we need to load data via $.ajax
        eventFinishedLoading: null, // this will be kicked off, if all $.ajax-requests are completed
        // generic way to query against objects
        getUserId: function (index, user) {
            return index;
        },
        getEventUserId: function (event) {
            return event.userId;
        },
        getParsedEventStart: function (event) {
            var start = event.start;
            var typeofStart = typeof start;
            if (typeofStart == 'object') {
                return start;
            }
            return Date.parse(start);
        },
        getParsedEventEnd: function (event) {
            var end = event.end;
            var typeofEnd = typeof end;
            if (typeofEnd == 'object') {
                return end;
            }
            return Date.parse(end);
        },
        getEventId: function (event) {
            return event.id;
        }
    },
    fetchData: function (callback, startDate, endDate, users) {
        var self = this;

        self._buildAdaptedSources();

        var adaptedSourcesLength = self._adaptedSources.length;
        if (!adaptedSourcesLength) {
            return;
        }

        var pendingAdaptedSourcesCount = adaptedSourcesLength;
        var currentData = new Array();

        if ($.isFunction(self.settings.eventLoading)) {
            self.settings.eventLoading();
        }

        for (var i = 0; i < adaptedSourcesLength; i++) {
            var adaptedSource = self._adaptedSources[i];
            var adaptedOptions = self._buildAdaptedOptions(adaptedSource, startDate, endDate, users);

            self._fetchDataFromAdaptedSource(adaptedSource, adaptedOptions, function (data) {
                if (data) {
                    currentData = currentData.concat(data);
                }

                pendingAdaptedSourcesCount--;
                if (!pendingAdaptedSourcesCount) {
                    callback(currentData);
                    if ($.isFunction(self.settings.eventFinishedLoading)) {
                        self.settings.eventFinishedLoading();
                    }
                }
            });
        }
    },
    _adaptedSources: null,
    _buildAdaptedSources: function () {
        var self = this;
        if (!self.settings.sources || !self.settings.sources.length) {
            return;
        }
        if (self._adaptedSources) {
            return;
        }

        var adaptedSources = new Array();

        for (var i = 0; i < self.settings.sources.length; i++) {
            var source = self.settings.sources[i];

            var typeOfSource = typeof source;
            if (typeOfSource == 'object') {
                source = {
                    url: source.url,
                    staticData: source.data || [],
                    sourceIndex: i,
                    useUsers: source.useUsers || false
                }
            }
            else if (typeOfSource == 'string') {
                source = {
                    url: source,
                    staticData: [],
                    sourceIndex: sourceIndex,
                    useUsers: false
                };
            }
            else {
                // currently we cannot deal with anything different than strings (= plain url) or objects
                throw '_fetchDataFromSource works with urls only - no functions or alikes supported'
            }

            adaptedSources.push(source);
        }

        self._adaptedSources = adaptedSources;
    },
    _cache: new Array(),
    _addToCache: function (adaptedSource, adaptedOptions, result) {
        var self = this;
        var cacheForAdaptedSource = self._getCacheForAdaptedSource(adaptedSource);
        cacheForAdaptedSource.addDateRange(adaptedOptions);
        $.each(result, function (index, element) {
            cacheForAdaptedSource.addEvent(element);
        });
    },
    _getCacheForAdaptedSource: function (adaptedSource) {
        var manager = this;
        var cacheForAdaptedSource = manager._cache[adaptedSource.sourceIndex];
        if (!cacheForAdaptedSource) {
            cacheForAdaptedSource = {
                _adaptedSource: adaptedSource,
                _cacheForUsers: null, // this could be an array of 'cacheForUser' or a single 'cacheForUser' - depending on adaptedSource.useUsers
                _getCacheForUser: function (userId) {
                    var self = this;
                    var cacheForUser;

                    if (!self._adaptedSource.useUsers) {
                        cacheForUser = self._cacheForUsers;
                        if (!cacheForUser) {
                            cacheForUser = self._createCacheForUser(userId);
                            self._cacheForUsers = cacheForUser;
                        }
                    }
                    else {
                        if (!self._cacheForUsers) {
                            self._cacheForUsers = new Array();
                        }
                        else {
                            $.each(self._cacheForUsers, function (index, element) {
                                if (element.userId == userId) {
                                    cacheForUser = element;
                                }
                            });
                        }

                        if (!cacheForUser) {
                            cacheForUser = self._createCacheForUser(userId);
                            self._cacheForUsers.push(cacheForUser);
                        }
                    }

                    return cacheForUser;
                },
                _createCacheForUser: function (userId) {
                    var cacheForUser = {
                        userId: userId,
                        events: new Array(),
                        addEvent: function (event) {
                            var self = this;
                            event = manager._cloneEvent(event);
                            event = self._parseEvent(event);
                            self.events.push(event);
                        },
                        _parseEvent: function (event) {
                            var self = this;
                            var eventStartDate = manager.settings.getParsedEventStart(event);
                            var eventEndDate = manager.settings.getParsedEventEnd(event);

                            event.startDate = eventStartDate;
                            event.endDate = eventEndDate;

                            return event;
                        },
                        getEvents: function (startDate, endDate) {
                            var self = this;
                            var result = new Array();
                            $.each(self.events, function (index, element) {
                                var overlaps = element.startDate <= endDate && element.endDate >= startDate;
                                if (overlaps) {
                                    var copiedElement = manager._cloneEvent(element);
                                    result.push(element);
                                }
                            });
                            return result;
                        }
                    };
                    return cacheForUser;
                },
                addEvent: function (event) {
                    var self = this;
                    var userId = manager.settings.getEventUserId(event);
                    var cacheForUser = self._getCacheForUser(userId);
                    cacheForUser.addEvent(event);
                },
                getEvents: function (startDate, endDate, userId) {
                    var self = this;
                    var cacheForUser = self._getCacheForUser(userId);
                    return cacheForUser.getEvents(startDate, endDate);
                },
                _requestDateRanges: new Array(),
                addDateRange: function (adaptedOptions) {
                    var self = this;
                    if (self._adaptedSource.useUsers) {
                        $.each(adaptedOptions.adaptedUsers, function (index, element) {
                            var userId = manager.settings.getUserId(index, element);
                            self._requestDateRanges.push({
                                startDate: adaptedOptions.adaptedStartDate,
                                endDate: adaptedOptions.adaptedEndDate,
                                userId: userId
                            });
                        });
                    }
                    else {
                        self._requestDateRanges.push({
                            startDate: adaptedOptions.adaptedStartDate,
                            endDate: adaptedOptions.adaptedEndDate
                        });
                    }
                },
                hasDateRange: function (startDate, endDate, userId) {
                    var self = this;
                    var success = false;
                    $.each(self._requestDateRanges, function (index, element) {
                        if (success) {
                            return;
                        }
                        success = (userId ? element.userId == userId : true) && element.startDate <= endDate && element.endDate >= startDate;
                    });
                    return success;
                },
                getAdaptedDateRange: function (startDate, endDate, userId) {
                    var self = this;
                    var dateRange = {
                        startDate: manager._cloneDate(startDate),
                        endDate: manager._cloneDate(endDate)
                    };
                    dateRange.startDate.setDate(dateRange.startDate.getDate() - manager.settings.additionalDays);
                    dateRange.endDate.setDate(dateRange.endDate.getDate() + manager.settings.additionalDays);

                    $.each(self._requestDateRanges, function (index, element) {
                        if (self._adaptedSource.useUsers) {
                            if (element.userId != userId) {
                                return;
                            }
                        }

                        if (element.startDate < dateRange.startDate
                            && dateRange.startDate < element.endDate
                            && element.endDate < dateRange.endDate) {
                            dateRange.startDate = manager._cloneDate(element.endDate);
                        }
                        if (dateRange.startDate < element.startDate
                            && element.startDate < dateRange.endDate
                            && dateRange.endDate < element.endDate) {
                            dateRange.endDate = manager._cloneDate(element.startDate);
                        }
                    });

                    return dateRange;
                }
            };
            manager._cache[adaptedSource.sourceIndex] = cacheForAdaptedSource;
        }

        return cacheForAdaptedSource;
    },
    _buildAdaptedOptions: function (adaptedSource, startDate, endDate, users) {
        var self = this;

        var adaptedStartDate;
        var adaptedEndDate;
        var adaptedUsers = new Array();
        var adaptedData = new Array();
        var cachedEvents;

        var cacheForAdaptedSource = self._getCacheForAdaptedSource(adaptedSource);
        if (adaptedSource.useUsers) {
            $.each(users, function (index, element) {
                var userId = self.settings.getUserId(index, element);
                var hasDateRange = cacheForAdaptedSource.hasDateRange(startDate, endDate, userId);
                if (hasDateRange) {
                    if (!cachedEvents) {
                        cachedEvents = new Array();
                    }
                    var events = cacheForAdaptedSource.getEvents(startDate, endDate, userId);
                    cachedEvents = cachedEvents.concat(events);
                }
                else {
                    adaptedUsers.push(element);
                    var dateRange = cacheForAdaptedSource.getAdaptedDateRange(startDate, endDate, userId);
                    if (!adaptedStartDate) {
                        adaptedStartDate = dateRange.startDate;
                    }
                    if (!adaptedEndDate) {
                        adaptedEndDate = dateRange.endDate;
                    }
                }
            });
        }
        else {
            var hasDateRange = cacheForAdaptedSource.hasDateRange(startDate, endDate);
            if (hasDateRange) {
                cachedEvents = cacheForAdaptedSource.getEvents(startDate, endDate);
            }
            else {
                var dateRange = cacheForAdaptedSource.getAdaptedDateRange(startDate, endDate);
                adaptedStartDate = dateRange.startDate;
                adaptedEndDate = dateRange.endDate;
            }
        }

        if (adaptedUsers.length) {
            var userIds = new Array();
            $.each(adaptedUsers, function (index, element) {
                var userId = self.settings.getUserId(index, element);
                userIds.push(userId);
            });
            adaptedData[self.settings.queryStringParameters.userIds] = self.settings.queryStringParameters.transformUserIds(userIds);
        }
        if (adaptedStartDate && adaptedEndDate) {
            adaptedData[self.settings.queryStringParameters.start] = self.settings.queryStringParameters.transformStartDate(adaptedStartDate);
            adaptedData[self.settings.queryStringParameters.end] = self.settings.queryStringParameters.transformEndDate(adaptedEndDate);
        }

        var adaptedOptions = {
            adaptedStartDate: adaptedStartDate,
            adaptedEndDate: adaptedEndDate,
            adaptedUsers: adaptedUsers,
            adaptedData: adaptedData,
            cachedEvents: cachedEvents
        };

        return adaptedOptions;
    },
    _fetchDataFromAdaptedSource: function (adaptedSource, adaptedOptions, callback) {
        var self = this;

        var cachedEvents = adaptedOptions.cachedEvents;

        var needFetch = false;
        if (adaptedSource.useUsers && adaptedOptions.adaptedUsers.length) {
            needFetch = true;
        }
        else if (adaptedOptions.adaptedStartDate && adaptedOptions.adaptedEndDate) {
            needFetch = true;
        }

        if (!needFetch) {
            if (cachedEvents) {
                callback(cachedEvents);
            }
            return;
        }

        var staticData = adaptedSource.staticData;
        var adaptedData = adaptedOptions.adaptedData;
        data = jQuery.extend({}, staticData, adaptedData);

        var options = {
            url: adaptedSource.url,
            data: data,
            dataType: 'json',
            success: function (result) {
                self._addToCache(adaptedSource, adaptedOptions, result);
                if (cachedEvents) {
                    result = result.concat(cachedEvents);
                }
                callback(result);
            }
        };

        $.ajax(options);
    },
    _cloneDate: function (date) {
        var clonedDate = new Date(date.getTime());
        return clonedDate;
    },
    _cloneEvent: function (event) {
        var clonedEvent = jQuery.extend(true, {}, event);
        return clonedEvent;
    }
};

which could be used:

cachableEventManager.settings.queryStringParameters.start = 'customStart';
cachableEventManager.settings.queryStringParameters.end = 'customeEnd';
cachableEventManager.settings.queryStringParameters.userIds = 'userIds';
cachableEventManager.settings.additionalDays = 14;
cachableEventManager.settings.eventLoading = function () {
    $.blockUI();
};
cachableEventManager.settings.eventFinishedLoading = function () {
    $.unblockUI();
};
cachableEventManager.settings.sources = [
    {
        'url': 'service.wcf',
        'data': {
            'staticParamter': 'testValue'
        },
        'useUsers': true
    }
];

var weekCalendar = $('#weekCalendar');
weekCalendar.weekCalendar({
    data: function (start, end, callback) {
        // maybe update this.users here ...
        cachableEventManager.fetchData(callback, start, end, this.users);
    }
});

Calendar is completely off

First of all thanks for this script !

I'm trying to merge the calendar with google calendar.

I managed to fetch the events in JSON format here is an example.

[

{"id":"0vph199u88ptubouu659cvuruo","title":"13h 15h","start":"2011-03-29T13:00:00.000+02:00","end":"2011-03-29T15:00:00.000+02:00"},
{"id":"if1fa7d9u13r7sapu4juqkj4pk","title":"10h 12h","start":"2011-03-29T10:00:00.000+02:00","end":"2011-03-29T12:00:00.000+02:00"}]

So there is an event from 10 to 12 and another one from 13 to 15 but In the calendar

But in the calendar It's not displayed at all like that

http://i51.tinypic.com/xbwo4z.jpg

Any ideas ?

fix style for event (themeroller)

to enable themeroller for event

replace line 1348-1350

     eventHtml = "<div class=\"" + eventClass + " ui-corner-all\">\
            <div class=\"wc-time ui-corner-top\"></div>\
            <div class=\"wc-title\"></div></div>";

with

     eventHtml = "<div class=\"" + eventClass + " ui-widget ui-corner-all\">\
            <div class=\"wc-time ui-corner-top ui-widget-header\"></div>\
            <div class=\"wc-title ui-corner-bottom ui-widget-content\"></div></div>";

and remove style

.wc-cal-event .wc-time {
    background-color: #2b72d0;
    border: 1px solid #1b62c0;
    color: #fff;
    padding: 0;
    font-weight: bold;
}

Multiday event

Looks like the multiday event is not working.
When I drag a multiday event to somewhere else, only the first part of the event is being dragged.

Example Event:
Start: Wed 10PM
End: Thu 2AM

Action: Drag to Wed 5PM
There are 2 events now: One from Wed 5PM to 7PM and one from Thu 0AM to 2AM.

enhance style for timeslot-headers (themeroller)

if you set options.businessHours.limitDisplay to true the style of the timeslot-headers is set to "active". but you do not need any highlight due to the limitation.

workaround:
replace line 946
var bhClass = (options.businessHours.start <= i && options.businessHours.end > i) ? "ui-state-active wc-business-hours" : "ui-state-default";

with
var bhClass;
if (options.businessHours.limitDisplay) {
bhClass = 'ui-state-default wc-business-hours';
}
else if (options.businessHours.start <= i
&& options.businessHours.end > 0) {
bhClass = 'ui-state-active wc-business-hours';
}
else {
bhClass = 'ui-state-default';
}

and replace style

.wc-grid-timeslot-header {
    width: 6%;
    background: #eee;   
}

with

.wc-grid-timeslot-header {
    width: 6%;
    background: #eee;
    vertical-align: top;
}

Resizable dialogs

Dialogs where the contents do not scale automatically should not be resizable at all.

height option after load causes calendar to have 0 height

I'm using Safari, after my page loads in the debugger I type:

jQuery("#calendar").weekCalendar("option", "height", 486);

The result is that the body of the calendar disappears, but the masthead remains.

The expected result is for the calendar to shrink/grow to 486.

Month mode is missing

When it comes down to days, the week-calendar hits the nail. But imagine a "month"-mode ...
Sure, that would give some serious problems (eg. n users with events), but it would be very helpful!
The "light" version of this would be: just render the events, and zoom into day- or week-mode when clicking on a day. then the users can get rendered, but there won't be any struggeling with users in month-mode

Example/Inspiration: http://arshaw.com/fullcalendar/

First resize after drag&drop fails if you do an "updateEvent" in the eventDrop handler

If you call
$calendar.weekCalendar("updateEvent", newValEvent);
in the eventDrop handler, you'll get unexpected behavior - the first attempt to resize an event after a drag&drop will fail.

I found out that it's simply not necessary to do an "updateEvent" in the handler, because the new calendar event will be rendered after the handler is called anyway.

I spent quite a few hours chasing this down, and I think it would be nice to document it for the benefit of other users.

If you do an "updateEvent" in your eventDrop handler, the value of $calEvent.data("calEvent") will be null in the function addDroppableToWeekDay, which will then crash at the following line:
var $weekDayOld = self._findWeekDayForEvent($calEvent.data("calEvent"), self.element.find(".wc-time-slots .wc-day-column-inner"));

Since addDroppableToWeekDay never finishes, $calEvent (the old one) never gets removed. Now if you try to resize the event using the gui, $calEvent gets picked up by the collision detection logic in adjustForEventCollisions. The end result is that your resized event reverts to its original dimensions. This is all similar to issue 115 on the old list:

http://code.google.com/p/jquery-week-calendar/issues/detail?id=115

highlight-mode of today

the slots are highlighted correctly, but the header is missing out. the current implemented variant is not themeroller-enabled either.

to fix this,

remove

.wc-header .wc-today  {
    font-weight: bold;
}

from css

replace line 1163-1202

     self.element.find(".wc-header td.wc-day-column-header").each(function(i, val) {
        $(this).html(self._getHeaderDate(currentDay));
        if (self._isToday(currentDay)) {
           $(this).addClass("wc-today");
        } else {
           $(this).removeClass("wc-today");
        }
        currentDay = self._addDays(currentDay, 1);

     });

     currentDay = self._cloneDate(self.element.data("startDate"));
             if(showAsSeparatedUser)
             {
                    self.element.find('.wc-header td.wc-user-header').each(function(i, val){
                        if (self._isToday(currentDay)) {
                             $(this).addClass("wc-today");
                        } else {
                             $(this).removeClass("wc-today");
                        }
                        currentDay = ((i+1) % options.users.length) ? currentDay : self._addDays(currentDay, 1);
                    });
             }

     currentDay = self._cloneDate(self.element.data("startDate"));

     $weekDayColumns.each(function(i, val) {

        $(this).data("startDate", self._cloneDate(currentDay));
        $(this).data("endDate", new Date(currentDay.getTime() + (MILLIS_IN_DAY)));
        if (self._isToday(currentDay)) {
           $(this).parent().addClass("wc-today");
        } else {
           $(this).parent().removeClass("wc-today");
        }

        if(!showAsSeparatedUser || !((i+1)%options.users.length)){
          currentDay = self._addDays(currentDay, 1);
        }
     });

with

     var todayClass = 'ui-state-highlight';

     self.element.find(".wc-header td.wc-day-column-header").each(function(i, val) {
        $(this).html(self._getHeaderDate(currentDay));
        if (self._isToday(currentDay)) {
           $(this).addClass(todayClass);
        } else {
           $(this).removeClass(todayClass);
        }
        currentDay = self._addDays(currentDay, 1);

     });

     currentDay = self._cloneDate(self.element.data("startDate"));
             if(showAsSeparatedUser)
             {
                    self.element.find('.wc-header td.wc-user-header').each(function(i, val){
                        if (self._isToday(currentDay)) {
                             $(this).addClass(todayClass);
                        } else {
                             $(this).removeClass(todayClass);
                        }
                        currentDay = ((i+1) % options.users.length) ? currentDay : self._addDays(currentDay, 1);
                    });
             }

     currentDay = self._cloneDate(self.element.data("startDate"));

     $weekDayColumns.each(function(i, val) {

        $(this).data("startDate", self._cloneDate(currentDay));
        $(this).data("endDate", new Date(currentDay.getTime() + (MILLIS_IN_DAY)));
        if (self._isToday(currentDay)) {
           $(this).parent().addClass(todayClass);
        } else {
           $(this).parent().removeClass(todayClass);
        }

        if(!showAsSeparatedUser || !((i+1)%options.users.length)){
          currentDay = self._addDays(currentDay, 1);
        }
     });

FFox raises undefined calEvent.end.setFullYear exception

calEvent.end.setFullYear(start.getFullYear()); within _renderEvents:

    while( start.getDay() < endDay ){
        calEvent.start = start;
        //end of this virual calEvent is set to the end of the day

        calEvent.end.setFullYear(start.getFullYear());

Ability to make some "Users" readonly.

if possible i would like the ability to make some "Users" readonly. Administrators could create events but not the public. Public would still see the events though.
Thanks.

iPad support

This looks awesome. I might use this in a project. But I tested on my iPad and it did not support scrolling or moving of events. Also it will not display the entire height of the calendar. Any plans to fix this?

businessHours ?

I have used many option and they all work , but I tryed to put businessHours option but it not work, is my syntax correct ?

businessHours: [{"start": 8, "end": 18, limitDisplay: true}]

I also try : businessHours: [{start: 8, end: 18, limitDisplay: true}]

I upload a zip file with test files : http://www.mediafire.com/?0d9lc482n1he7ed

Thanks !

Bug with drag/drop

If the business day starts at 8am to 10pm and I create an event from 9am to 10pm, save it. Then drag it to 8am, it starts the event at zero. It only does this in IE.
Thanks.

Drag & drop event error in IE

Hi,

I have one issue in IE browser. After changing the date, when i will try to drag & drop any event then it's give error.

How we can rebind that event?

Thanks!!

Cannot drag an event to first user column of the calendar.

In a multi-user setup, an event cannot be dragged to the first user column of the day column.

Setup:

  • multi-user like the one shown at weekcalendar_demo_3.html
  • daysToShow: 3 or 1

To replicate this issue:

  • edit weekcalendar_demo_3.html to look like this from iines 141 to 149
    var minDate = new Date(2011,01,11,12,00,000);
    var maxDate = new Date(2011,01,25,12,00,000);

    $(document).ready(function() {
    
        var $calendar = $('#calendar').weekCalendar({
            minDate: minDate,
            maxDate: maxDate,
            timeslotsPerHour: 4,
    
  • open weekcalendar_demo_3.html on your browser

  • select 3 next days button or 1 day

  • create an event on the second user (user 2)

  • try to drag that event to the first user (left-most column)

Based on the above, I noticed that when an event comes from the second (user 2) or third user (long username) in whichever day, you cannot drag it to the first user (left-most column).

wrong calculation of DateLastMilliOfWeek

  _dateLastMilliOfWeek : function(date) {
     var lastDayOfWeek = this._dateLastDayOfWeek(date);
     return new Date(lastDayOfWeek.getTime() + (MILLIS_IN_DAY));

  }

this is wrong:
if we have eg. sunday 00:00 and we want to get monday 00:00, adding 24 hours to sunday 00:00 ain't monday 00:00...

fix:

  _dateLastMilliOfWeek : function(date) {
     var lastDayOfWeek = this._dateLastDayOfWeek(date);
     lastDayOfWeek.setDate(lastDayOfWeek.getDate() + 1);
     return lastDayOfWeek;
  }

wrong alternation

the alternation of odd/even-class is done over the whole day-pool, not for each day separately. which gets confusing if you associate colors (or color-state) to a user and using an odd amount of users > 1.

this leads to eg.

user
1st day: odd
2nd day: even

to fix this

replace line 863-886

      //now let's display oddEven placeholders
      for (var i = 1; i <= options.daysToShow; i++){
        if(options.displayOddEven){
          if(!showAsSeparatedUser){
            oddEven = ( oddEven == "odd" ? 'even' : 'odd' );
            renderRow+= "<td class=\"wc-day-column day-" + i + "\">";
            renderRow+=   "<div class=\"wc-no-height-wrapper wc-oddeven-wrapper\">";
            renderRow+=     "<div class=\"wc-full-height-column wc-column-" + oddEven + "\"></div>";
            renderRow+=   "</div>";
            renderRow+= "</td>";
          }
          else{
            var uLength = options.users.length;
            for(var j = 0; j< uLength; j++){
               oddEven = ( oddEven == "odd" ? 'even' : 'odd' );
               renderRow+= "<td class=\"wc-day-column day-" + i + "\">";
               renderRow+=   "<div class=\"wc-no-height-wrapper wc-oddeven-wrapper\">";
               renderRow+=     "<div class=\"wc-full-height-column wc-column-" + oddEven + "\" ></div>";
               renderRow+=   "</div>";
               renderRow+= "</td>";
            }
          }
        }
      }

with

      //now let's display oddEven placeholders
      for (var i = 1; i <= options.daysToShow; i++){
          // no need to check displayOddEven again... look @ line 857
          oddEven = oddClass;
          if(!showAsSeparatedUser){
            oddEven = (oddEven == oddClass ? evenClass : oddClass);
            renderRow+= "<td class=\"wc-day-column day-" + i + "\">";
            renderRow+=   "<div class=\"wc-no-height-wrapper wc-oddeven-wrapper\">";
            renderRow+=     "<div class=\"wc-full-height-column wc-column-" + oddEven + "\"></div>";
            renderRow+=   "</div>";
            renderRow+= "</td>";
          }
          else{
            var uLength = options.users.length;
            for(var j = 0; j< uLength; j++){
               oddEven = (oddEven == oddClass ? evenClass : oddClass);
               renderRow+= "<td class=\"wc-day-column day-" + i + "\">";
               renderRow+=   "<div class=\"wc-no-height-wrapper wc-oddeven-wrapper\">";
               renderRow+=     "<div class=\"wc-full-height-column wc-column-" + oddEven + "\" ></div>";
               renderRow+=   "</div>";
               renderRow+= "</td>";
            }
          }
      }

After each update all events disappear

Hi,
After each "save" or "delete" the events disappear from the calendar, but when click on "Today" button, they re-appear.

Have any idea what should I look into?

Events are treated as overlapping when End Time = Start Time of next event

As part of playing with the Demo, I added an event to the JSON events that went from 6pm to 12:00am (midnight) and another event from 12am to 8:00am - these were then rendered as overlapping.

As part of scheduling, it is common for the next event to begin at the same time that the prior event finishes. Therefore, the overlap functionality should only consider end times that are > start times, and allow end times = start times.

Wrong date adaption on multiday events

startDate: 2011-02-28 00:00:00
endDate: 2011-03-29 00:00:00

this one will make a problem in there

          while( start.getDay() < endDay ){
            calEvent.start = start;
            //end of this virual calEvent is set to the end of the day 
            calEvent.end.setFullYear(start.getFullYear());
            calEvent.end.setMonth(start.getMonth());
            calEvent.end.setDate(start.getDate());

it should state

          while( start.getDay() < endDay ){
            calEvent.start = start;
            //end of this virual calEvent is set to the end of the day 
            calEvent.end.setFullYear(start.getFullYear());
            calEvent.end.setDate(start.getDate());
            calEvent.end.setMonth(start.getMonth());

:)

an alternative would be: why not clone the startDate and set the hours/minutes...??

Bug with use24Hour

When i put use24Hour to true, the hours displayed are too big and overstep on the calendar grid...

use24Hour not working

"use24Hour: true" only sets the times on left to 24h format, all other times are still in am/pm, "$calendar.weekCalendar("formatDate", calEvent.start/stop)" always returns AM/PM.

Event drag on day 6 or day 7 of week display

The issue: if the week calendar is displaying more than five days, there is a bug when dragging an event in the furthest day to the right of the display.

For example, let's say the calendar is set to display seven days, and day 7 (i.e., Saturday) has an event in it. If you select that event to drag, it snaps into day 6 and cannot be moved back into day 7 without first saving it outside day 7.

To give a more detailed example, let's say the event on day 7 in the above example is Lunch from 12-1. Somethings comes up and you have to reschedule lunch from 1-2. So you want to drag Lunch from 12-1 on day 7 to the 1-2 slot on day 7. But when you grab the event to move it, it pops into day 6 and is locked out of day 7! So you have to first "save" it in day 6, and then can re-drag it back into day 7.

If this example isn't clear, please let me know.

IMPORTANT EDIT: This bug only appears when there is a vertical scroll bar inside the calendar window. If the div containing the calendar is resized vertically to accomodate the calendar without the calendar requiring a scroll bar to view all times in a day, dragging and dropping behaves as expected.

Multiple User Events Multiply on Drag

If I create an event with an array for userId I see the multiple events as separate blocks. If I drag it drags only the one I click on and then when I drop it it creates new copies of the event.

For example, I have 3 userIds in the array. I drag the 3rd and when I drop it I end up with 5 events because the one I dragged is creating 2 new copies of itself.

Use of minDate and maxDate.

Hi,

Thanks for this wonderful jQuery plugin. I need help in using the minDate and maxDate options:

I set the values to:
....
var minDate = new Date(2011,01,11,12,00,000);
var maxDate = new Date(2011,01,20,12,00,000);
....
var $calendar = $('#calendar').weekCalendar({
minDate: minDate,
maxDate: maxDate,
....

However, when I click on the Previous, Today, and Next buttons it does not work as expected.

The calendar behaves erratically, either:
* it moves the days backwards (whatever button I click)
* it moves the days forwards (whatever button I click)

I may be doing something wrong here, tried looking at the wiki at https://github.com/themouette/jquery-week-calendar/wiki/Script-options and it's not documented there too.

Thanks in advance for the help.

P.S.:
* I already saw issue #8 but it does not mention how to limit the start and end dates. https://github.com/themouette/jquery-week-calendar/issues/closed#issue/8
* I also saw issue #33 https://github.com/themouette/jquery-week-calendar/issuesearch?state=open&q=mindate#issue/33

Error: b("<div></div>").addClass("ui-widget-overlay") is undefined Source File: http://staging.indusnettechnologies.com:81/noema.com/dalmorocha/sgd/libs/jquery-ui-1.8rc3.custom.min.js

I am keep getting this error when adding 3 or more events.After creating 2 events when i tried to add 3 events i am getting this error and event does not add.Please help me..

Error: b("

").addClass("ui-widget-overlay") is undefined
Source File: http://staging.indusnettechnologies.com:81/noema.com/dalmorocha/sgd/libs/jquery-ui-1.8rc3.custom.min.js
Line: 199

please help....

multiple eventSources

atm you cannot declare multiple eventSources.

therefore i've written a little generic eventManager:

var eventManager = {
    fetchData: function (sources, callback) {
        var sourcesLength = sources.length;

        var pendingSourcesCount = sourcesLength;
        var currentData = new Array();
        for (var i = 0; i < sourcesLength; i++) {
            var source = sources[i];
            this._fetchDataFromSource(source, function (data) {
                currentData = currentData.concat(data);
                pendingSourcesCount--;
                if (!pendingSourcesCount) {
                    callback(currentData);
                }
            });
        }
    },
    _fetchDataFromSource: function (source, callback) {
        if (typeof source == 'string') {
            $.ajax({
                'url': source,
                'dataType': 'json',
                'success': function (events) {
                    callback(events);
                }
            });
        }
        else if ($.isFunction(source)) {
            source(function (events) {
                callback(events);
            });
        }
        else {
            callback(source);
        }
    }
};

which can be used eg:

    var $calendar = $('#selector').weekCalendar({
        'data': function (start, end, callback) {
            eventManager.fetchData([
                function (internalCallback) {
                    var url = 'help1.wcf';
                    var data = {
                        'start': new Date(),
                        'end': new Date()
                    };
                    $.getJSON(url, data, function (data) {
                        internalCallback(data);
                    });
                },
                function (internalCallback) {
                    var url = 'help2.wcf';
                    var data = {
                        'start': new Date(),
                        'end': new Date()
                    };
                    $.getJSON(url, data, function (data) {
                        internalCallback(data);
                    });
                }
            ], callback);
        }
    });

maybe sth like this shoule be integrated...

Would be great to add public functions for single day prev/next.

It would be very useful to have single day prev/next functions available, as follows:

prevDay : function() {
    var newDate = new Date(this.element.data("startDate").getTime() - MILLIS_IN_DAY);
    this._clearCalendar();
    this._loadCalEvents(newDate);
},

If that is undesirable, may I suggest adding a public function that returns the current calendar start date, so that we can achieve single day prev/next using the gotoDate function.

the refresh method remove all new events

Hi,

to reproduce it :

  1. create a new event in current week
  2. click on the Save button
  3. click on Today button
  4. Voila (I'm french to ^^ )

Thanks for your work on this nice project.

IE Support

I was wondering if there are any tricks to get this to work with IE8/9.

It seems to work fine in everything else but in IE 8/9 both don't seem to render the events. I have checked and the data is being passed to the to "data" option.

Any ideas you could give me would be much appreciated.

(With the exception of telling me not to use IE, I would gladly stop, but my users would throw a fit)

Event Resize Snapping

While resizing an event it snaps to the time slots per hour but when you release it doesn't always stick to the slot. In testing this appears to be coming from the resizable event itself, there is a grid attribute that appears to be working when the resizing is happening but upon "stop" the ui.size.height does not necessarily match a gridded value.

Limit start and end dates?

My project calls for a window of dates. For example, May 15th to May 28th. I would like to be able to limit the prev/next buttons to a date range like that.

I can't seem to find a solution for this.

Thanks

event repeated

Hello

I would like to know how to create few events in the week ? I would like to create a periodicity for an event and when the user fill this information, the event is repeated in the week.
I have took the jquery-week-calendar from themouette and in the /full_demo/demo.js, I add this after the line 59 :

id++;
calEvent.id = id;
calEvent.start = new Date(startField.val());
calEvent.start = calEvent.start.setTime(calEvent.start.getTime() +  86400000);
calEvent.end = new Date(endField.val());
calEvent.end = calEvent.end.setTime(calEvent.end.getTime() +  86400000);
calEvent.title = titleField.val();
calEvent.body = bodyField.val();

$calendar.weekCalendar("updateEvent", calEvent);

and when I create an event on 5th July, it brings forward to 6th July

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.