jMonthCalendar Options, Events, & Methods Documentation

In this post I am going to cover all the custom event/options as well as methods that can be configured and used in jMonthCalendar. All of these are options that can be supplied at initialization in order to manipulate the calendar further or be able to tie into some additional logic or rules. As well as methods that are exposed for manipulating the calendar after initialization. This is my first attempt at formal documentation, so bare with me.

Options

containerId - default: #jMonthCalendar

Use this to configure where your calendar should be placed in the page. You must have a matching DOM element with the ID

$.jMonthCalendar.Initialize({ containerId: '#MyContainerId' }, null);

headerHeight - default: 50

This sets the height of the navigation header.

$.jMonthCalendar.Initialize({ headerHeight: 50 }, null);

firstDayOfWeek - default: 0

This determines which day of the week weeks should start on (default 0 refers to sunday). Monday is 1, Tuesday is 2, etc.

$.jMonthCalendar.Initialize({ firstDayOfWeek: 1 }, null);

calendarStartDate - default: new Date()

This determines which month to display when the calendar is first loaded. The default is to start in the current month (today).

$.jMonthCalendar.Initialize({ calendarStartDate: new Date(2009, 1, 1) }, null);

dragableEvents - default: true

This determines weather or not you want event blocks to be dragable. Note this depends on jquery.ui.dragable.

$.jMonthCalendar.Initialize({ dragableEvents: false }, null);

dragHoverClass - default: 'DateBoxOver'

This is the css class that is added when an element is being hovered over an acceptable date cell.

$.jMonthCalendar.Initialize({ dragHoverClass: 'SomeCssClass' }, null);

navLinks (object of values)

These are the label text and switches to determine the header navigation.

$.jMonthCalendar.Initialize({   
    navLinks: {
        enableToday: true,
        enableNextYear: true,
        enablePrevYear: true,
        p:'‹ Prev', 
        n:'Next ›', 
        t:'Today',
        showMore: 'Show More'
    }
}, null);

Events

onMonthChanging

This event is triggered upon changing the calendar's month. If the callback function returns false, the change will be prevented. Note: this would be an excelent point to do an AJAX call for the next months events.

// supply this callback as an option with the collowing signature
$.jMonthCalendar.Initialize({
    onMonthChanging(newDate) { ... }
}, null);

// AJAX call sample for more events
$.jMonthCalendar.Initialize({
    onMonthChanging(newDate) { 

    }
}, null);

onMonthChanged

This event is triggered after calendar's month has been changed.

$.jMonthCalendar.Initialize({
    onMonthChanged(event, newDate) { ... }
}, null);

onEventLinkClick

This event is triggered when the anchor tag of the event is clicked. Note: good place to link out to another page.

$.jMonthCalendar.Initialize({
    onEventLinkClick(event) { 
        alert(event.data.Event);
    }
}, null);

onEventBlockClick

This event is triggered when the div container of the event is clicked. Note: this our the link click would be a good place to show tooltips.

$.jMonthCalendar.Initialize({
    onEventBlockClick(event) { 
        alert(event.data.Event);
    }
}, null);

onEventBlockOver

This event is triggered when your mouse is over the event div container.

$.jMonthCalendar.Initialize({
    onEventBlockOver(event) { 
        alert(event.data.Event);
    }
}, null);

onEventBlockOut

This event is triggered when you mouse moves off the event div container.

$.jMonthCalendar.Initialize({
    onEventBlockOut(event) { 
        alert(event.data.Event);
    }
}, null);

onDayLinkClick

This event is triggered when the user clicks on the label of the day (number in upper right corner)

$.jMonthCalendar.Initialize({
    onDayLinkClick(event) { 
        alert(event.data.Date);
    }
}, null);

onDayCellClick

This event is triggered when the user clicks on the cell that contains the event div containers.

$.jMonthCalendar.Initialize({
    onDayCellClick(event) { 
        alert(event.data.Event);
    }
}, null);

onDayCellDblClick

This event is triggered wehn the user double clicks ont eh cell that contains the event div containers.

$.jMonthCalendar.Initialize({
    onDayCellDblClick(event) { 
        alert(event.data.Event);
    }
}, null);

onEventDropped

This event is fired after a user drags and drops and event onto a new day.

$.jMonthCalendar.Initialize({
    onEventDropped(event, calEvent, newDate) { 
        alert(calEvent);
        alert(newDate);
    }
}, null);

onShowMoreClick

This event is triggered when the user wishes to "see more" events than what can be displayed in the cell. Note: this would be a good place to use a tooltip or dialog as well.

$.jMonthCalendar.Initialize({
    onShowMoreClick(dayEvents) { 
        // dayEvents is an array of events 
        alert(dayEvents.length);
    }
}, null);

Methods

Initialize(options, eventArray)

This is the main method needed to be called to get a calendar on the page. You can initialize it with the options and event callbacks mentioned above to get a more custom plugin.

$.jMonthCalendar.Initialize({ containerId: '#MyContainerId' }, []);

ChangeMonth(newDate)

This method will change the current selected month of the calendar. This method will fire the callback onMonthChanging and onMonthChanged.

$.jMonthCalendar.ChangeMonth(new Date(2009, 1, 1));

ReplaceEventCollection(eventArray)

This will replace all events in the plugin with the new event array passed in. This will clear all existing events being displayed and redraw all the events after the replacement.

$.jMonthCalendar.ReplaceEventCollection([]);

AddEvents(eventArray)

This method will add a single event to the plugin or an array of events by merging into the existing array of events. After which the method will clear all visible event on the calendar and draw the events in the updated array.

$.jMonthCalendar.AddEvents([]);

ClearEventsOnCalendar()

This method will remove all the events in the plugin and and remove any being displayed.

$.jMonthCalendar.ClearEventsOnCalendar();

jMonthCalendar-1.3.2-beta Release

I have released a new version of jMonthCalendar (1.3.2-beta). Below I will provide a sample of the use of event callback as options. Well this release is pretty straight forward for the most part. It includes changes to how the custom events are fired mostly and addresses various bug fixes. As well as includes some reduction in file size. UPDATE Beta2 is released to fix some minor bug issues.

Download location: jMonthCalendar-1.3.2-Beta

The biggest change in this release is how events are handled. Before I was not passing the DOM event back to you for control, I was simply just calling the methods you configured as options and passing parameters. Now, the original DOM event is bubbled up to the custom event in most cases. Along with the original DOM event I am also stuffing in the custom data for the callback into the jQuery event object.

jQuery provides a nice way of encapsulating the original DOM event into a jQuery event object. A property on that object is 'data' (which can be waht ever I want). So now, all custom events are mostly passed one single parameter (with the exception of onMonthChanging and onShowMoreClick); the jquery typed event. Inside that event object I have put the data I want to send back, like the date or event object clicked on. Don't worry I will get to a sample of what I am talking about.

First I will start off by showing you the old way of doing it prior to this release.

OLD Way

$().ready(function() {
    var options = {
        onMonthChanging: function(dateIn) {
            // this could be an Ajax call to the backend to get this months events
            alert("on month changing");
            // $.jMonthCalendar.ReplaceEventCollection(events);
        },
        onEventLinkClick: function(calEvent) { 
            // calEvent will be the calendar event you clicked on
            alert("event link click");
            return true; 
        },
        onDayLinkClick: function(dateIn) { 
            // date might be wrong here, held reference from last item
            alert(dateIn.toLocaleDateString());
        }
    };

    $.jMonthCalendar.Initialize(options, []);
});

Okay, so the obvious problem with that is that there is no way to get to the original DOM event.

NEW recommended Way

$().ready(function() {
    var options = {
        onMonthChanging: function(dateIn) {
            // this could be an Ajax call to the backend to get this months events
            alert("on month changing");
            // $.jMonthCalendar.ReplaceEventCollection(events);
        },
        onEventLinkClick: function(event) { 
            // event is the jQuery event passed
            alert("event link click");
            // can get to the actual calendar event now through the Data property
            alert(event.data.Event);
            // want to prevent event bubbling use:
            event.stopPropagation();
        },
        onDayLinkClick: function(event) { 
            alert(event.data.Date.toLocaleDateString());
        }
    };

    $.jMonthCalendar.Initialize(options, []);
});

Getting Started with jMonthCalendar

So you are interested in using jMonthCalendar and are unsure how to start using it...? Well hopefully I can give the 5 minute startup that will help you along the way. In this post I will show you how to install and place a calendar on the page as well as show you how to populate the calendar with some events. Easy enough right? I hope so.

Getting started with jMonthCalendar is really quite easy, it is like any other Javascript library or jQuery plugin in that it requires a Javascript file and reference in the page.

Step 1 - Download

Well you will first need a copy of jQuery if you don't already have one, I recomend jQuery 1.3.2 which can be found here, you either want the uncompressed version or the compressed version depending on your preferences.

You will will also need a copy of jMonthCalendar which can be downloaded here. The download contains the Javascript files, a sample html page, and some default css (which can be changed to suit your needs).

Step 2 - Include in Html

After the files are downloaded you will want to move them to a directory in your project/website that can be references either relativley or absolutly. You'll want to include a reference to the jQuery file you downloaded as well as the jMonthCalendar plugin. You can place these references in the head of the html or the body, with Javascript it is all the same. You'll want to put these two line in your html document:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script src="js/jMonthCalendar.js" type="text/javascript"></script>

If you want to use the default styles now is the time to either copy the contents of the core.css (from the jMonthCalendar download) into your css file or include a reference in the head like so:

<link href="css/core.css" type="text/css" rel="stylesheet"></link>  

Step 3 - Create place holder in the Html body

In order to draw the calendar on to the page, the plugin needs to know where to put it. Add and empty div tag someplace in the body of the html like so: (The ID of the div is VERY important, you can change the ID but you must tell the plugin what it should look for through the options.)

<div id="jMonthCalendar"></div> 

Step 4 - Initialize calendar on page load.

To draw the calendar after the page has loaded you will need to hook up that standard jQuery onLoad event. This usually happens once on the page and is surrounded in a script block at either the top or the bottom of the page. The safest place to do this is with another script block right after step 2. This will create the calendar and draw it on the screen using the empty div you created in step 3.

<script type="text/javascript">
    $().ready(function() {
    $.jMonthCalendar.Initialize(null, null);
    });
</script>

Thats it! That is all you need to do in order to display the calendar on te page. There are of course configurable options and events that you can tie into to perform advanced operations but I will save that for another post. The next topic I will cover is, "okay now what...", how to load events into the calendar.

Update: Added the first bits of documentation for the plugin here.

jMonthCalendar 1.3.0 Beta

jMonthCalendar has reached a new milestone! It now supports multi-day events (events that span multiple days). Plus it retains all the same features as before including drag and drop and event stacking. This release is a huge change from the previous version and is thus labeled as Beta. Most significant to the change is how events are rendered onto the calendar. In this post I am going to go over the new features and how they will affect existing users. I will also try to cover some of the new functionality and how it might be used.

Change Log

  • Events that span multiple days with continuation over days, weeks, months, years.
  • jQuery 1.3.2 Support
  • Events are now pre-sorted for multi day events on top.
  • "Show More Events" setting/hoot that passes the days worth of event object as an array.
  • Start of jQuery UI theme support, arrows for spanning events.
  • Removed initialize for static height and width, now all set on the main calendar using CSS (everything else is dynamic).
  • Note: you must specify an EventID in the event objects, they are required now.

The biggest change to this release is the fact that multi-day events are being drawn now. In order to add this I had to make a huge amount of changes under the hood and thus I am adding a Beta to the release to warn people. At the same time I want to see how it behalves for people and fix any issues people might have.

In the last release events were being appended into the table cell tag of the specified day. This created huge problems as you can't do a column span on the event easily, plus how are you supposed to handle overflow and events that wrap over weeks or months. So I chose to rewrite how the events were drawn and make them absolutely positioned. I also added an object for each day on the calendar and set some properties, that made it a lot easier to reference the object from an array and grab the days worth of events.

Some people may look into this and think that I have missed how to display "More Events" (events that overflow the day). I have left this out and added a hook instead. I was unable to settle on an implementation and with so many other good balloon pop ups, I thought I would leave it up to you. There is a new hook called onShowMoreClick that passes an array of events to it. The array of events is a representation to all the events for that day, including the non-visible ones. I hope to provide a series of usage posts on how this might be done using my favorite plugins.

One last piece of information is regrading drag and drop events. They are supported with multi-day events even. They will fire the same hooks as in the past: onEventDropped (passing the event and the new date).

Please let me know what you think in the comments, I am very proud of where this plugin has come so far and hope to keep pushing it's feature set. If you experience any issues please feel free to leave a comment, email, or better yet; file an issue over at the Google Code Home page.

Download From Google Code** **

log4net Dynamic Properties in XML Configuration

I just learned about a new feature today of log4net that would have saved me a few hours of time had I known or been able to find this earlier. I learned that you can have dynamic properties stored into log4net's global context from code and then access them from the XML configuration file. This is useful in the case where dynamic configuration of log4net is needed.

My Case: I have been building console application that will run nightly to sync some integration records and I wanted to setup logging in order to see that status of the job and gather some reporting information (counts, time run, etc). There was a catch though this process would run multiple times in a night but each time for a different customer. This would make it difficult to read the logs for a particular customer as all I would have to go on is the file date and time.

I needed a way to break my log files into different customers yet retain the rolling file appender features of log4net. My first pass at with was to configure log4net using the basic configurator all in code and create the appender, with a dynamic file name, and set the level of the logger programmatically. This was not my preferred way but was my only hope to getting the application out of development. Then I found how to set properties into log4net's global context and access them through the configuration file. I did run into a small problem that my app.config file was not being read in so I had to add these two variable to my assembly.

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
[assembly: log4net.Config.Repository]

My goal was to make the file name dynamic based on the CustomerID passed into the application. Please not the file tag as it is the ticket to my case.

<log4net>
    <root>
        <level value="INFO"></level>
        <appender-ref ref="RollingLogFileAppender"></appender-ref>
    </root>


    <appender type="log4net.Appender.RollingFileAppender" name="RollingLogFileAppender">
        <file type="log4net.Util.PatternString" value="logs\logFile_%property{BrokerID}.txt"></file> 
        <appendtofile value="false"></appendtofile>
        <rollingstyle value="Size"></rollingstyle>
        <maxsizerollbackups value="-1"></maxsizerollbackups>
        <maximumfilesize value="50GB"></maximumfilesize>
        <layout type="log4net.Layout.PatternLayout">
            <conversionpattern value="%date [%thread] %-5level %logger - %message%newline"></conversionpattern>
        </layout>
    </appender>
</log4net>

Here is a sample of my log4net configuration section. Please note the file tag and type attribute to be log4net.Util.PatternString. The pattern of the value is important to, it must be %property{property_name} to get the right replacement. This is the ticket to dynamic values.

private static void InitLogger()
{
    //This is freaking awesome, put a property into the log4net context and using the 
    //  log4net.Util.PatternString type you can dynamically set values for the logging context from code.
    log4net.GlobalContext.Properties["CustomerID"] = (CustomerID!= 0) ? CustomerID.ToString() : "Error";
}

Here is an example of my small InitLogger. This method is the very first item to be called when the main routine starts up. All that needs to be done now is get a logger and start logging. A file will be created based on the CustomerID which in this case is retrieved from the command line arguments before InitLogger is called. If no CustomerID is passed in than the file will be to logFile_Error.txt

private static ILog Logger;

static void Main(string[] args)
{
    if (args.Length > 0)
        CustomerID= Util.GetInt(args[0]);

    InitLogger();
    Logger = LogManager.GetLogger("Process");
}

Pretty cool I think, I hope this saves people some headaches. I wish I would have found this a few days ago. Oh well it is to my benefit to learn. Happy coding.