Calendario: A Flexible Calendar Plugin

A jQuery calendar plugin for creating flexible calendars.

Calendario: A Flexible Calendar Plugin

View demo Download source

Today we want to share a flexible calendar concept with you. Calendars can be a very tricky thing when it comes to their layout and responsiveness. This is an experiment for trying out some grid layouts that can be applied to calendars. We’ve created a jQuery plugin for the calendar itself and you can see some examples of how to use it in the demos. The aim is to provide a suitable layout for both, small and big screens and keeping the calendar structure fluid when possible. On large screens we want to show a grid-based layout while on smaller screens, we want to simply stack the days of the month.

Please note that the demos will only work as intended in browsers that support the new CSS properties used here, especially calc().

The calendar designs are based on these two beauties found on Dribbble:

For the calendar plugin to work, we simply need a container with the class “fc-calendar-container”:

<div id="calendar" class="fc-calendar-container"></div>

The plugin can be called like this:

$( '#calendar' ).calendario();

The plugin will create a calendar with the following structure:

<div id="calendar" class="fc-calendar-container">
   <div class="fc-calendar fc-five-rows">
	  <div class="fc-head">
		 <div>Monday</div>
		 <div>Tuesday</div>
		 <div>Wednesday</div>
		 <div>Thursday</div>
		 <div>Friday</div>
		 <div>Saturday</div>
		 <div>Sunday</div>
	  </div>
	  <div class="fc-body">
		 <div class="fc-row">
			<div></div>
			<div></div>
			<div></div>
			<div><span class="fc-date">1</span><span class="fc-weekday">Thu</span></div>
			<div><span class="fc-date">2</span><span class="fc-weekday">Fri</span></div>
			<div><span class="fc-date">3</span><span class="fc-weekday">Sat</span></div>
			<div><span class="fc-date">4</span><span class="fc-weekday">Sun</span></div>
		 </div>
		 <div class="fc-row">
			<!-- ... -->
		 </div>
		 <div class="fc-row">
			<!-- ... -->
		 </div>
		 <div class="fc-row">
			<!-- ... -->
		 </div>
		 <!-- ... -->
	  </div>
   </div>
</div>

The calendar will consist of a head for the listing of the weekdays and a body with rows for the days of the month. Each “cell” will contain the date and weekday (if applicable) and we control the height of the rows by setting the right class to the container (four, five or six rows). The styling for the default calendar is defined in calendar.css.
Note that a cell that contains some content/event will look as follows:

<div class="fc-content">
   	<span class="fc-date">14</span>
  	<span class="fc-weekday">Wed</span>
   	<div>
		<!-- Some event/content -->
	</div>
</div>

Note that the weekday of each cell is hidden by default because we have the calendar head with the weekdays. The ones in the cell are especially for the case when we apply media queries to reset the layout of the calendar to be stacked vertically. Here we will want to show the weekdays for each day.

It’s clear that a calendar could/should be represented by a table, but due to some table rendering differences between the browsers (especially IE9), we chose not to use it. You can of course adjust the plugin to output a table, though.

The important part of making the calendar grid fluid is the styling of the row and the div (or the “cell”):

.fc-four-rows .fc-row  {
	height: 25%;
}

.fc-five-rows .fc-row  {
	height: 20%;
}

.fc-six-rows .fc-row {
	height: 16.66%;
	height: -moz-calc(100%/6);
	height: -webkit-calc(100%/6);
	height: calc(100%/6);
}

.fc-calendar .fc-row > div,
.fc-calendar .fc-head > div {
	float: left;
	height: 100%;
	width:  14.28%; /* 100% / 7 */
	width: -moz-calc(100%/7);
	width: -webkit-calc(100%/7);
	width: calc(100%/7);
	position: relative;
}

So, we define different heights depending on the amount of rows we’ll have, using calc() where we know that the result is not a round number. For the inner div we will set the width to be 100 divided by 7.

Options

The following (default) options are available:

// initialize calendar with this month (1-12). Default is today
month : null,

// initialize calendar with this year. Default is today
year : null,

// initial data/content for the calendar
// format:
// {
//		'MM-DD-YYYY' : 'HTML Content',
//		'MM-DD-YYYY' : 'HTML Content',
//		'MM-DD-YYYY' : 'HTML Content'
//		...
//	}
caldata : null,
weeks : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
weekabbrs : [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
months : [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
monthabbrs : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],

// choose between values in options.weeks or options.weekabbrs
displayWeekAbbr : false,

// choose between values in options.months or options.monthabbrs
displayMonthAbbr : false,

// left-most day in the calendar
// 0 - Sunday, 1 - Monday, ... , 6 - Saturday
startIn : 1,

// callback function for when clicking on a day cell in the calendar
// $el is the cell
// $content is the content division of the cell
// dateProperties is an object with the following properties:
// day : day number,
// month : month number from 1 - 12,
// monthname : name from options.months,
// year : year number,
// weekday : week number from 0 - 6,
// weekdayname : name from options.weeks
onDayClick : function( $el, $content, dateProperties ) { return false; }

The following public methods are available:

// return the year that is currently being viewed
getYear()

// return the month that is currently being viewed (1-12)
getMonth()

// returns the name of the month that is currently being viewed
getMonthName()

// returns the content division inside the cell associated to day "day"
getCell( day )

// sets the data to the calendar. Merges the contents of the passed caldata with the one already set (if any)
setData( caldata )

// shows the calendar for today's month and year
// month is from 1-12
gotoNow( callback )

// shows the calendar for month "month" and year "year"
// month is from 1-12
goto( month, year, callback )

// goes back one month in the calendar
gotoPreviousMonth( callback )

// goes back one year in the calendar
gotoPreviousYear( callback )

// goes further one month in the calendar
gotoNextMonth( callback )

// goes further one year in the calendar
gotoNextYear( callback )

You can use setData to add content to the calendar. You can see examples for that in the demo files.

The basic styling is defined in the calendar.css file and you can see examples of how to modify the calendar style and add to it in the custom CSS files.

Demos

Check out the demos:

View demo Download source

Previous:
Next:

Tagged with:

Mary Lou (Manoela Ilic) is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://tympanus.net/

Related Articles

Feedback 112

Comments are closed.
  1. 1

    This calendar is great, just one question one i had being a designer i have modified what i want the dates for the empty cells like for EX:july 2013 has 6 empty cells of the week for august i want to fill the dates for august in that

  2. 2

    Can someone please provide the code to print the next 5 events to occur from the data.js.

    I would like a list of the events in addition to the calendar, but only the next 5 events to occur is sufficient.

    Cheers.

  3. 3

    This is great, but adding events dynamically is causing me some trouble. I have a form where the user can enter the date for a new event, so I can’t hard-code the date like in your example. That is, I can’t do this:
    cal.setData( {"07-15-2013" : "<div >My event here</div>"} );

    I need to do this:
    cal.setData( {stringDate: "<div >My event here</div>"} );

    The problem is with getting the quotes around the date. Perhaps I am missing something basic and obvious? Thanks for your help…

    • 4

      ahhh – figured it out. The issue was with mismatched quotes. Serves me right for trying to fix this at 3AM.

      For anyone struggling with this, here’s how I solved it:


      var jsonData = "{\"" + stringDate + "\": \"<div class='event' '>" + eventInfo + "</div>\"}";
      cal.setData(JSON.parse(jsonData));

  4. 6

    mary good job, but I need to dynamically create events.
    My situation is this, I have pdf files that name with the date format CALDATA and create events and put everything inside a jquery object but when I go to the plugin it does not return anything

  5. 7

    Hi There
    Any Idea where to set hover on the cells?

    .no-touch .fc-calendar .fc-row > div > div a:hover {
    background: rgba(255,0,0,0.7);
    }

    This should give at read hover?

  6. 8

    Found the solution

    .no-touch .fc-calendar .fc-row > div:hover {
    background: rgba(202,202,202,0.7);
    /*magic*/
    -webkit-transition: all 0.2s ease-out;
    -moz-transition: all 0.2s ease-out;
    -o-transition: all 0.2s ease-out;
    transition: all 0.2s ease-out;
    }

    To spice it up I gave it a bit of css magic :)

  7. 9

    Anyone managed to get a popup box working with this? User clicks a date and then clicks the link in that date to get more info on that event. (there could be more than one event on that day so putting the data in the normal slide up box wont really work. Using the demo 2 layout here. thanks

  8. 10

    To get this working in IE10, we just had to modify this chunk of CSS:

    .fc-calendar .fc-row > div,
    .fc-calendar .fc-head > div {
    float: left;
    height: 100%;
    width: 14.28%; /* 100% / 7 */
    width: -moz-calc(100%/7);
    width: -webkit-calc(100%/7);
    width: calc(100%/7);
    position: relative;
    }

    removing the calculations and leaving just the percentage. I guess IE10 doesn’t calculate very accurately, so it pushes the last element in a row on the calendar over to the next line? So modify that chunk to this:


    .fc-calendar .fc-row > div,
    .fc-calendar .fc-head > div {
    float: left;
    height: 100%;
    width: 14.28%; /* 100% / 7 */
    position: relative;
    }

    If anyone has a different solution, let me know. :)

  9. 11

    Is there a way to display the calendar as a day view or a week view, vs the whole 30 days?

  10. 12

    Great calendar!

    Is there a way that I can bring in data from a MySQL database? Also this database may have a lot of data entries so I was hoping to only get the data for the month being currently viewed. Any ideas?

    Thanks!

  11. 14

    Hi,
    the calendar look beautiful!
    I still does not understand how you load the data from the data.js or another source?
    I am working on django python and would love to know how to implement it on my project.
    thank for your help

    • 15

      I think I may have found the solution

      use this in my template:
      var codropsEvents = {
      ’08-23-2013′ : ‘blablablablaa’,
      ’08-22-2013′ : ‘bloublou’,
      ’08-21-2013′ : ‘<a href=”http://tympanus.net/codrops/2012/11/23/three-script-updates/” rel=”nofollow”>Three Script Updates‘
      };

      and instead of the date and content I will directly put my tempate tag {{ }} to fill the information.

      great stuff!

  12. 16

    Hello,
    does anyone know how you can do to open an event in a modal window? I have imported jquery-ui, entered the code correctly but the popup does not work. Do not get any javascript error
    thanks

  13. 18

    Is there any way to fire a JS function after calendario has done it’s magic?

    basically, I want to iterate over each event in the calendar (after Calendario is done firing) and and some markup using the event data for tooltips.

    I wrapped each event in a “.event” class, so my code I’m looking to use after Calendario is completed is this:

    $(‘.event’).each(function(){

    var title = $(this).find(‘a’);
    var description = $(this).find(‘.description’);
    var more = $(this).find(‘.more’);

    $(this).append(” + title + description + more + ”);

    });

  14. 19

    This isfantastic. I’m tryingt o use demo 1, but with the show events vertical slide like in demo 2 (instead of just direct link), but no success so far. Anybody has tried to do the same with success and would like to share? Thanks in advance.

    • 20

      Its’s quite easy, just copy inside of onDayClick(), those two functions that goes with it – showEvents() and hideEvents() and CSS styles for #custom-content-reveal. And don’t forget to define wrapper.

  15. 22

    Hello Mary, I enjoyed your project and applied on my website using events dynamically with php, but I wonder if it is possible to place more than one event on the same day?

    Thank you

Comments are closed.