jQuery Calendar Plugin Using HTML Templates - CLNDR.js

File Size: 70.6 KB
Views Total: 51516
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
jQuery Calendar Plugin Using HTML Templates - CLNDR.js

CLNDR.js is a jQuery plugin that allows you to create a pretty clean calendar with event support using HTML template.

You might also like:

Install & download:

$ npm install clndr --save

How to use it:

1. Include jQuery javascript library and jQuery.clndr.js script on your web page.

<script src="js/jquery.js"></script>
<script src="js/clndr.js"></script>

<-- Or From The CDN -->
<script src="https://unpkg.com/[email protected]/src/clndr.js"></script>

2. Include moment.js and underscore.js on the page.

<script src="js/moment.js" type="text/javascript"></script>
<script src="js/underscore.js" type="text/javascript"></script>

3. Create the html template for the calendar.

<div id="full-clndr" class="clearfix"> 
<script type="text/template" id="full-clndr-template">
<div class="clndr-grid">
<div class="days-of-the-week clearfix">
<% _.each(daysOfTheWeek, function(day) { %>
<div class="header-day"><%= day %></div>
<% }); %>
<div class="days clearfix">
<% _.each(days, function(day) { %>
<div class="<%= day.classes %>" id="<%= day.id %>"><span class="day-number"><%= day.day %></span></div>
<% }); %>
<div class="event-listing">
<div class="event-listing-title">EVENTS THIS MONTH</div>
<% _.each(eventsThisMonth, function(event) { %>
<div class="event-item">
<div class="event-item-name"><%= event.title %></div>
<div class="event-item-location"><%= event.location %></div>
<% }); %>

4. The javascript to generate a calendar from the template.

var clndr = {};

$( function() {

  var currentMonth = moment().format('YYYY-MM');
  var nextMonth    = moment().add('month', 1).format('YYYY-MM');

  var events = [
    { date: currentMonth + '-' + '10', title: 'Persian Kitten Auction', location: 'Center for Beautiful Cats' },
    { date: currentMonth + '-' + '19', title: 'Cat Frisbee', location: 'Jefferson Park' },
    { date: currentMonth + '-' + '23', title: 'Kitten Demonstration', location: 'Center for Beautiful Cats' },
    { date: nextMonth + '-' + '07',    title: 'Small Cat Photo Session', location: 'Center for Cat Photography' }

  clndr = $('#full-clndr').clndr({
    template: $('#full-clndr-template').html(),
    events: events

5. All the options to customize the calendar.


      end: '2013-11-08',
      start: '2013-11-04',
      title: 'Monday to Friday Event'
    }, {
      end: '2013-11-20',
      start: '2013-11-15',
      title: 'Another Long Event'
  events: [],

  // the template: this could be stored in markup as a <script type="text/template"></script>
  // or pulled in as a string
  template: clndrTemplate,

  // determines which month to start with using either a date string or a moment object.
  startWithMonth: "YYYY-MM-DD" or moment(),

  // start the week off on Sunday (0), Monday (1), etc. Sunday is the default.
  // WARNING: if you are dealing with i18n and multiple languages, you probably
  // don't want this! See the "Internationalization" section below for more.
  weekOffset: 0,

  // an array of day abbreviation labels. If you have moment.js set to a different language,
  // it will guess these for you! If for some reason that doesn't work, use this...
  // WARNING: if you are dealing with i18n and multiple languages, you probably
  // don't want this! See the "Internationalization" section below for more.
  daysOfTheWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],

  // Optional callback function that formats the day in the header. If none
  // supplied, defaults to moment's `dd` and truncates to one character.
  // The callback is passed a moment object representing the day, and a string
  // is to be returned.
  formatWeekdayHeader: function (day) {
    return day.format('dd').charAt(0);

  // the target classnames that CLNDR will look for to bind events.
  // these are the defaults.
  targets: {
    nextButton: 'clndr-next-button',
    previousButton: 'clndr-previous-button',
    nextYearButton: 'clndr-next-year-button',
    previousYearButton: 'clndr-previous-year-button',
    todayButton: 'clndr-today-button',
    day: 'day',
    empty: 'empty'

  // custom classes to avoid styling issues. pass in only the
  // classnames that you wish to override.
  // these are the defaults.
  classes: {
    today: "today",
    event: "event",
    past: "past",
    lastMonth: "last-month",
    nextMonth: "next-month",
    adjacentMonth: "adjacent-month",
    inactive: "inactive",
    selected: "selected"

  // click callbacks! the keyword 'this' is set to the clndr instance in all callbacks.
  clickEvents: {
    // fired whenever a calendar box is clicked.
    // returns a 'target' object containing the DOM element, any events,
    // and the date as a moment.js object.
    click: function(target){ },

    // fired when a user goes forward a month.
    // returns a moment.js object set to the correct month.
    nextMonth: function(month){ },

    // fired when a user goes back a month.
    // returns a moment.js object set to the correct month.
    previousMonth: function(month){ },

    // fired when the next year button is clicked.
    // returns a moment.js object set to the correct month and year.
    nextYear: function(month) { },

    // fired when the previous year button is clicked.
    // returns a moment.js object set to the correct month and year.
    previousYear: function(month) { },

    // fires any time the month changes as a result of a click action.
    // returns a moment.js object set to the correct month.
    onMonthChange: function(month) { },

    // fires any time the year changes as a result of a click action.
    // if onMonthChange is also set, it is fired BEFORE onYearChange.
    // returns a moment.js object set to the correct month and year.
    onYearChange: function(month) { },

    // fired when a user goes to the current month & year.
    // returns a moment.js object set to the correct month.
    today: function(month){ },

    onMonthChange: null,
    onYearChange: null,
    onIntervalChange: null

  // this is called only once after clndr has been initialized and rendered.
  // use this to bind custom event handlers that don't need to be re-attached
  // every time the month changes (most event handlers fall in this category).
  // hint: this.element refers to the parent element that holds the clndr,
  // and is a great place to attach handlers that don't get tossed out every
  // time the clndr is re-rendered.
  ready: function() { },

  // a callback when the calendar is done rendering.
  // This is a good place to bind custom event handlers
  // (also see the 'ready' option above).
  doneRendering: function(){ },

  // if you're supplying an events array, dateParameter points to the
  // field in your event object containing a date string.
  // It's set to 'date' by default.
  dateParameter: 'date',

  // CLNDR can accept events lasting more than one day!
  // just pass in the multiDayEvents option and specify what the start and
  // end fields are called within your event objects. See the example file
  // for a working instance of this.
  multiDayEvents: {
    startDate: 'startDate',
    endDate: 'endDate',
    // if you also have single day events with a different date field,
    // use the singleDay property and point it to the date field.
    singleDay: 'date'

  // show the dates of days in months adjacent to the current month.
  // defaults to true.
  showAdjacentMonths: true,

  // when days from adjacent months are clicked, switch the current month.
  // fires nextMonth/previousMonth/onMonthChange click callbacks. defaults to false.
  adjacentDaysChangeMonth: false,

  // always make the calendar six rows tall (42 days) so that every month has a
  // consistent height. defaults to 'false'.
  forceSixRows: false,

  // anything you want access to in your template
  extras: { }

  // if you want to use a different templating language, here's your ticket.
  // Precompile your template (before you call clndr),
  // pass the data from the render function into your template,
  // and return the result. The result must be a string containing valid markup.
  // The keyword 'this' is set to the clndr instance
  // in case you need access to any other properties.
  // More under 'Template Rendering Engine' below.
  render: function(data){
  return '<div class="html data as a string"></div>';

  // if you want to prevent the user from navigating the calendar outside
  // of a certain date range (e.g. if you are making a datepicker), specify
  // either the startDate, endDate, or both in the constraints option. You
  // can change these while the calendar is on the page... See documentation
  // below for more on this!
  constraints: {
    startDate: '2017-12-22',
    endDate: '2018-01-09'

  // Set this, if you want a date to be "selected" (see classes.selected) after plugin init. Defualts to null, no initially selected date.
  selectedDate: null,
  trackSelectedDate: false,

  // Set this to true, if you want the plugin to track the last clicked day.
  // If trackSelectedDate is true, "selected" class will always be applied only to the most recently clicked date; otherwise - selectedDate will not change.
  ignoreInactiveDaysInSelection: null

  // CLNDR can render in any time interval!
  // You can specify if you want to render one or more months, or one ore more
  // days in the calendar, as well as the paging interval whenever forward or
  // back is triggered. If both months and days are null, CLNDR will default
  // to the standard monthly view.
  lengthOfTime: {
    months: null,
    days: null,
    interval: 1

  // Pass a Moment instance to use instead of the CLNDR settings. 
  moment: null

6. API methods.

// Create a Clndr and save the instance as myCalendar
var myCalendar = $('#myCalendar').clndr();

// Go to the next month

// Go to the previous month

// Set the month using a number from 0-11 or a month name

// Go to the next year

// Go to the previous year

// Set the year

// Change the events. Note that this triggers a re-render of the calendar.

// Add events. Note that this triggers a re-render of the calendar.

// Remove events.  All events for which the passed in function returns true will
// be removed from the calendar.
// Note that this triggers a re-render of the calendar.
  return event.id == idToRemove;


v1.5.1 (2019-11-28)

  • Added new functional option formatWeekdayHeader to format the weekday string used in the calendar's header. 
  • Improved date comparison operations

v1.5.0 (2019-05-29)

  • Bug fixes, linted all files, NPM audit updates

v1.4.8/9 (2019-05-28)

  • Fixes inconsistencies with selectedDate and showAdjacentMonths
  • Fixed a bug with weekOffset

v1.4.7 (2016-11-26)

  • Fixed compatibility issue with momentjs v2.17.0

v1.4.6 (2016-08-02)

  • Fixed bugs with the constraints.

v1.4.5 (2016-07-05)

  • Bug fix for marking selected dates for more complex templates

v1.4.4 (2016-07-03)

  • Recompiled assets. Includes fix for startWithDate in weekly calendars.

v1.4.3 (2016-07-02)

  • Bug fix for data is not defined, PR from keioka.

v1.4.2 (2016-06-29)

  • Added second option to addEvents to suppress the re-render.

v1.4.1 (2016-01-14)

  • Rebuilt assets for version update. This includes the interval event fixes

v1.4.0 (2015-12-15)

  • added onIntervalChange to defaults

v1.3.4 (2015-11-05)

  • Fixed a bug where calling destroy and reinstantiating a clndr on the same element would not bind new click handlers.

v1.3.3 (2015-10-22)

  • Adds ignoreInactiveDaysInSelection option for disabling selection of inactive dates when using both trackSelectedDates and constraints.

v1.3.2 (2015-10-22)

  • Adds destroy and get-instance methods.

v1.3.0 (2015-10-14)

  • Adds destroy and get-instance methods.

v1.2.16 (2015-08-19)

  • Fixed: nextMonth click event was firing previousMonth's event erroneously.

v1.2.14 (2015-07-22)

  • Fixed next and previous buttons weren't navigating properly for certain configurations.

v1.2.14 (2015-07-09)

  • update.

v1.2.12 (2015-06-27)

  • Updated version for bugfix from selected day merge. Recompiled JS.

v1.2.10 (2015-03-11)

  • Added a performance optimization that should make rendering multiday events slightly faster in the case that some are <= one day long. This update is backwards-compatible.

v1.2.9 (2015-02-21)

  • Fixed a bug where the daysArray was accidently introduced into the global namespace. This shouldn't have affected your world. This update is backwards-compatible.

v1.2.8 (2015-02-16)

  • Added previousMonth and nextMonth variables into the template, which match month in format, so that now in "April" you also have access to the strings "March" and "May". This update is backwards-compatible.

v1.2.7 (2015-01-21)

  • Added the ability to mix multi-day and single-day events using the new multiDayEvents.singleDay property. Also introduced lazy setting of startDate and endDate in multi-day events so that if one of them is missing they will both be set to the value that is present. 

v1.2.6 (2015-01-07)

  • Added the ability to specify custom classnames for event, next-month, previous-month, etc. using options.classes. 

v1.2.5 (2014-12-01)

  • Reverting the previous DST code change, which introduced a bug for a large number of users.

v1.2.4 (2014-11-25)

  • Fixed a bug related to DST in specific timezones that would cause duplicate dates to appear.
  • Added removeEvents filtering function.

v1.2.3 (2014-10-16)

  • Fixed a bug that introduced a global variable. It's possible (but very unlikely) that this might have caused some weirdness when using multiple instances of CLNDR on the same page.

v1.2.2 (2014-10-02)

  • updated moment dependency to >=latest

v1.2.1 (2014-07-10)

  • Fixed a bug in eventsLastMonth, eventsThisMonth, and eventsNextMonth.
  • Added CommonJS/AMD wrapper to the plugin.

v1.1.4 (2014-01-22)

  • BC break for Bower users! Underscore is no longer listed as a dependency in the Bower plugin, allowing you the flexibility of choosing the templating language you prefer.
  • Also added a day of the week class to all clndr days in the format calendar-dow-<0 - 6>, allowing you to style weekends/specific days of the week differently.

v1.1.3 (2014-01-18)

  • fixed a bug where multiday events longer than two months would not show up. Fixed a bug that prevented clndr from loading in IE8.

v1.1.2 (2013-12-17)

  • using the forceSixRows option, you can now force your calendar to render six rows at all times, giving each month the same height. All classes and events come through this extra set of days just as you would expect. The usage jQuery's $.data has been corrected such that calling $(#calendar-parent-element).data('plugin_clndr') returns the clndr instance.

v1.1.1 (2013-12-02)

  • You can now only call clndr on one element at a time. If you attempt to call it on more than one element, an error is thrown. This should have no effect on previous code as long as your selectors were only returning one element. 

v1.0.13 (2013-10-25)

  • update and fixes

v1.0.12 (2013-10-23)

  • added next and previous year controls
  • fixed doneRendering context
  • added onYearChange and ready callbacks

v1.0.11 (2013-10-17)

  • set context in click callbacks and render function to the clndr instance. 
  • added past class to days before today.

v1.0.10 (2013-10-17)

  • fixed a bug in event propagation

v1.0.8 (2013-10-14)

  • fixed a bug where clndr would not fully respect the starting day of the week using moment.js settings.

v1.0.8 (2013-10-14)

  • fixed adjacent-month bug & added date validation, switched to using classes instead of ids for identifying days.


This awesome jQuery plugin is developed by kylestetz. For more Advanced Usages, please check the demo page or visit the official website.