Full-featured Calendar JavaScript Library – tui.calendar

Category: Date & Time , Javascript , Recommended | February 17, 2022
Views Total:11,655 views
Official Page:Go to website
Last Update:February 17, 2022


Full-featured Calendar JavaScript Library – tui.calendar


tui.calendar is a powerful, full-featured calendar library used to showcase custom events, schedules, tasks in daily, weekly, and monthly views.


$ npm install tui-calendar --save

Basic usage:

Include the bundled JavaScript and CSS files on the page.

<link rel="stylesheet" href="dist/tui-calendar.css">
<script src="dist/tui-calendar.js"></script>

Create a container where you want to render the Tui Calendar.

<div id="calendar"></div>

Create a new Tui Calendar as these:

var Calendar = tui.Calendar;
var calendar = new Calendar('#calendar', {
    // options here

Possible options to customize the calendar.

var calendar = new Calendar('#calendar', {
    // 'day', 'week', 'month'
    defaultView: 'week',
    // shows the milestone and task in weekly, daily view
    taskView: true,
    // shows the all day and time grid in weekly, daily view
    scheduleView: true,
    // override default styles here
    theme: {
      'common.border': '1px solid #e5e5e5',
      'common.backgroundColor': 'white',
      'common.holiday.color': '#ff4040',
      'common.saturday.color': '#333',
      'common.dayname.color': '#333',
      'common.today.color': '#333',
      // creation guide style
      'common.creationGuide.backgroundColor': 'rgba(81, 92, 230, 0.05)',
      'common.creationGuide.border': '1px solid #515ce6',
      // month header 'dayname'
      'month.dayname.height': '31px',
      'month.dayname.borderLeft': '1px solid #e5e5e5',
      'month.dayname.paddingLeft': '10px',
      'month.dayname.paddingRight': '10px',
      'month.dayname.backgroundColor': 'inherit',
      'month.dayname.fontSize': '12px',
      'month.dayname.fontWeight': 'normal',
      'month.dayname.textAlign': 'left',
      // month day grid cell 'day'
      'month.holidayExceptThisMonth.color': 'rgba(255, 64, 64, 0.4)',
      'month.dayExceptThisMonth.color': 'rgba(51, 51, 51, 0.4)',
      'month.weekend.backgroundColor': 'inherit',
      'month.day.fontSize': '14px',
      // month schedule style
      'month.schedule.borderRadius': '2px',
      'month.schedule.height': '24px',
      'month.schedule.marginTop': '2px',
      'month.schedule.marginLeft': '8px',
      'month.schedule.marginRight': '8px',
      // month more view
      'month.moreView.border': '1px solid #d5d5d5',
      'month.moreView.boxShadow': '0 2px 6px 0 rgba(0, 0, 0, 0.1)',
      'month.moreView.backgroundColor': 'white',
      'month.moreView.paddingBottom': '17px',
      'month.moreViewTitle.height': '44px',
      'month.moreViewTitle.marginBottom': '12px',
      'month.moreViewTitle.backgroundColor': 'inherit',
      'month.moreViewTitle.borderBottom': 'none',
      'month.moreViewTitle.padding': '12px 17px 0 17px',
      'month.moreViewList.padding': '0 17px',
      // week header 'dayname'
      'week.dayname.height': '42px',
      'week.dayname.borderTop': '1px solid #e5e5e5',
      'week.dayname.borderBottom': '1px solid #e5e5e5',
      'week.dayname.borderLeft': 'inherit',
      'week.dayname.paddingLeft': '0',
      'week.dayname.backgroundColor': 'inherit',
      'week.dayname.textAlign': 'left',
      'week.today.color': '#333',
      'week.pastDay.color': '#bbb',
      // week vertical panel 'vpanel'
      'week.vpanelSplitter.border': '1px solid #e5e5e5',
      'week.vpanelSplitter.height': '3px',
      // week daygrid 'daygrid'
      'week.daygrid.borderRight': '1px solid #e5e5e5',
      'week.daygrid.backgroundColor': 'inherit',
      'week.daygridLeft.width': '72px',
      'week.daygridLeft.backgroundColor': 'inherit',
      'week.daygridLeft.paddingRight': '8px',
      'week.daygridLeft.borderRight': '1px solid #e5e5e5',
      'week.today.backgroundColor': 'rgba(81, 92, 230, 0.05)',
      'week.weekend.backgroundColor': 'inherit',
      // week timegrid 'timegrid'
      'week.timegridLeft.width': '72px',
      'week.timegridLeft.backgroundColor': 'inherit',
      'week.timegridLeft.borderRight': '1px solid #e5e5e5',
      'week.timegridLeft.fontSize': '11px',
      'week.timegridLeftTimezoneLabel.height': '40px',
      'week.timegridLeftAdditionalTimezone.backgroundColor': 'white',
      'week.timegridOneHour.height': '52px',
      'week.timegridHalfHour.height': '26px',
      'week.timegridHalfHour.borderBottom': 'none',
      'week.timegridHorizontalLine.borderBottom': '1px solid #e5e5e5',
      'week.timegrid.paddingRight': '8px',
      'week.timegrid.borderRight': '1px solid #e5e5e5',
      'week.timegridSchedule.borderRadius': '2px',
      'week.timegridSchedule.paddingLeft': '2px',
      'week.currentTime.color': '#515ce6',
      'week.currentTime.fontSize': '11px',
      'week.currentTime.fontWeight': 'normal',
      'week.pastTime.color': '#bbb',
      'week.pastTime.fontWeight': 'normal',
      'week.futureTime.color': '#333',
      'week.futureTime.fontWeight': 'normal',
      'week.currentTimeLinePast.border': '1px dashed #515ce6',
      'week.currentTimeLineBullet.backgroundColor': '#515ce6',
      'week.currentTimeLineToday.border': '1px solid #515ce6',
      'week.currentTimeLineFuture.border': 'none',
      // week creation guide style
      'week.creationGuide.color': '#515ce6',
      'week.creationGuide.fontSize': '11px',
      'week.creationGuide.fontWeight': 'bold',
      // week daygrid schedule style
      'week.dayGridSchedule.borderRadius': '2px',
      'week.dayGridSchedule.height': '24px',
      'week.dayGridSchedule.marginTop': '2px',
      'week.dayGridSchedule.marginLeft': '8px',
      'week.dayGridSchedule.marginRight': '8px'
    // template options
    template: {
      milestone: function(schedule) {
        return '&lt;span style="color:red;"&gt;&lt;i class="fa fa-flag"&gt;&lt;/i&gt; ' + schedule.title + '&lt;/span&gt;';
      milestoneTitle: function() {
        return 'Milestone';
      task: function(schedule) {
        return '&amp;nbsp;&amp;nbsp;#' + schedule.title;
      taskTitle: function() {
        return '&lt;label&gt;&lt;input type="checkbox" /&gt;Task&lt;/label&gt;';
      allday: function(schedule) {
        return schedule.title + ' &lt;i class="fa fa-refresh"&gt;&lt;/i&gt;';
      alldayTitle: function() {
        return 'All Day';
      time: function(schedule) {
        return schedule.title + ' &lt;i class="fa fa-refresh"&gt;&lt;/i&gt;' + schedule.start;
    // Options for daily, weekly view
    week: {
      daynames: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
      startDayOfWeek: 0,
      narrowWeekend: true,
      workweek: false,
      showTimezoneCollapseButton: false,
      timezonesCollapsed: false,
      hourStart: 0,
      hourEnd: 24,
    // Options for monthly view.
    month: {
      daynames: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
      startDayOfWeek: 0,
      narrowWeekend: true,
      visibleWeeksCount: 6,
      isAlways6Week: true,
      workweek: false,
      visibleScheduleCount: 1,
      moreLayerSize: {},
      grid: {}, // grid's header and footer information
      scheduleFilter: null
    // list of Calendars that can be used to add new schedule
    /* e.g.
          id: '1',
          name: 'My Calendar',
          color: '#ffffff',
          bgColor: '#9e5fff',
          dragBgColor: '#9e5fff',
          borderColor: '#9e5fff'
          id: '2',
          name: 'Company',
          color: '#00a9ff',
          bgColor: '#00a9ff',
          dragBgColor: '#00a9ff',
          borderColor: '#00a9ff'
    calendars: [],
    // whether use default creation popup or not
    useCreationPopup: false,
    // whether use default detail popup or not
    useDetailPopup: false,
    // timezone options
    timezone: {
      zones: [
          timezoneName: 'Asia/Seoul',
          displayLabel: 'GMT+09:00',
          tooltip: 'Seoul'
          timezoneName: 'America/New_York',
          displayLabel: 'GMT-05:00',
          tooltip: 'New York',
      offsetCalculator: function(timezoneName, timestamp){
        // matches 'getTimezoneOffset()' of Date API
        // e.g. +09:00 => -540, -04:00 => 240
        return moment.tz.zone(timezoneName).utcOffset(timestamp);
    // disable double click
    disableDblClick: false,
    // disble click
    disableClick: false,
    // is readonly?
    isReadOnly: false,
    // enable usage statistics
    usageStatistics: true


v1.15.3 (02/17/2021)

  • Fix: prevent missing view error on toggling popup options

v1.15.2 (01/05/2021)

  • Bug Fixes

v1.15.1 (11/15/2021)

  • Fix: wrong private schedule assignment in default popup

v1.15.0 (10/21/2021)

  • Feat: improve UX of default creation popup
  • Fix: allow target=”_blank” attribute for user-generated string

v1.14.0 (08/30/2021)

  • Bug Fixes

v1.13.1 (07/06/2021)

  • Fix: treat calendarId as string type when finding selected calendar

v1.13.0 (12/23/2020)

  • Feat: : add new timezone option
  • Feat: : when you do not set a custom timezone, the schedule will always be displayed the same

v1.12.14 (11/18/2020)

  • feat : when you do not set a custom timeZone, the schedule will always be displayed the same. (#718)
  • style: add prettier config
  • fix: when you do not set a custom timeZone, the schedule will always be displayed the same
  • style: update code style

v1.12.13 (04/28/2020)

  • Bug Fixes
  • Enhancement: Enable text selection on popup
  • Improved default detail popup location

v1.12.12 (03/24/2020)

  • Bug Fixes
  • Refactor: change the properties of accessible objects using util.pick

v1.12.11 (02/05/2020)

  • Bug Fixes

v1.12.10 (01/23/2020)

  • Bug Fixes

v1.12.9 (12/30/2019)

  • Fix: Date convert wrong type as number

v1.12.8 (11/28/2019)

  • fix: remove fixing start of milestone and task as one day

v1.12.6 (10/24/2019)

  • Fix: resolve security vulnerabiliti for npm audi.
  • Fix: If the user directly inputs the end time as 00:00, render the schedule correctly.
  • Fix: change method name ‘getNextStartDay’ to ‘getStartOfNextDay’.
  • Fix: when changing timezone, today display issue.

v1.12.5 (07/31/2019)

  • Fix: add semicolon for more view schdule custom style (#374)
  • Fix: add dependency tui-dom for cdn example pages. (fix #376)
  • Fix: can use html text for templates (fix #380) (#389)
  • Fix: update type definition file

v1.12.4 (07/31/2019)

  • Feat: support minimum height of month and week view
  • Bugs fixed

v1.12.3 (07/05/2019)

  • Fix: remove duplicate tui-time-picker option
  • Fix: resolve tracking GA option inside using tui component

v1.12.1 (05/31/2019)

  • Fix: Wrong type for IMonthOptions.visibleWeeksCount
  • Fix: : fix meridiem in timegridDisplayPrimayTime default template-the Noon is 12 pm
  • Fix: Weekly and Daily views not rendering schedule in few months

v1.12.0 (04/23/2019)

  • Bugfix
  • Refactor: change return value about render position(percent string to number)

v1.11.2 (04/19/2019)

  • Bugfix

v1.11.0 (04/06/2019)

  • Added support current time template on weekly, daily view
  • Change Typescript definition file ‘tui-calendar’ export type to default export

v1.10.1 (03/07/2019)

  • Fix: DST timezone bug

v1.10.0 (01/24/2019)

  • feat: Creation popup open on only double click option if set ‘disableClick’

v1.9.0 (12/18/2018)

  • feat: Display a recurrenceRule and body text

v1.8.1 (12/12/2018)

  • Feat : add declaration file for Typescript

v1.8.0 (11/06/2018)

  • fix: State is always Busy

v1.7.0 (11/06/2018)

  • fix: getDateRangeEnd() error in month view when option.month.isAlways6Week is undefined.
  • feat: Add ‘clickMore’ callback in monthly view
  • fix: Dragging a schedule make wrong time on 24 o’click

v1.6.0 (07/25/2018)

  • Bugfix

v1.5.0 (07/18/2018)

  • fix: getElement return null on month view in case of hidden schedules
  • feat: Support isReadOnly option of Calendar

You Might Be Interested In:

8 thoughts on “Full-featured Calendar JavaScript Library – tui.calendar

  1. shabs

    Is it possible to display calendar multi-column schedule for same day, eg room 1, room 2, room 3 (for appointment book)?

  2. timezone isse

    I need yr help. I am using tui-calendar in PHP. my application is working based on timezone. each user who loggedin can set their timezone in our setting . now tui calender is taking client side time zone so same application I open in chicago it shows chicago date time wise calnder and in india it shows india timewise.I don’t want it. I want to fixed it as per my server’s timezone. can you please help me .


Leave a Reply