Introduction

This article explains how to create a weekly availibility calender in an ASP.NET MVc application using fullcalender.js. Full calender is great for displaying event.user time slots which are easily managed by this. Users can create a new event and asign it to the calender so that he/she can manage their routing shedule.
Generally, routing calender can be used in things like hospital management applications where managing schedules is complicated.
So here we will see how to manage that schedule in an Asp.Net MVc Application.
Step 1
Create full availibility calender. Embed the following into your project:
https://adminlte.io/themes/dev/AdminLTE/pages/calendar.html
  • fullcalendar
  • fullcalendar-daygrid
  • fullcalendar-timegrid
  • fullcalendar-interaction
  • fullcalendar-bootstrap
moment.js is just used for displaying proper datetime formate in js.
Full Calender integration in mvc
Step 2
Create AvailibilityDto.cs used for getting available time slots list.
  1. public class AvailibilityDto
  2. {
  3. public int Id { get; set; }
  4. public string Title { get; set; }
  5. public string Desc { get; set; }
  6. public string Start_Date { get; set; }
  7. public string End_Date { get; set; }
  8. }
Step 3
Create CalanderController.cs for getting time slots list and return it to json.
  1. using MVCAdminLTE3.Models;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Web;
  6. using System.Web.Mvc;
  7. namespace MVCAdminLTE3.Areas.Admin.Controllers
  8. {
  9. public class CalanderController : Controller
  10. {
  11. // GET: Admin/Calander
  12. public ActionResult Index()
  13. {
  14. return View();
  15. }
  16. public ActionResult GetCalendarData()
  17. {
  18. List<AvailibilityDto> data = new List<AvailibilityDto>();
  19. //Statically create list and add data
  20. AvailibilityDto infoObj1 = new AvailibilityDto();
  21. infoObj1.Id = 1;
  22. infoObj1.Title = "I am available";
  23. infoObj1.Desc = "Description 1";
  24. infoObj1.Start_Date = "2020-08-16 22:37:22.467";
  25. infoObj1.End_Date = "2020-08-16 23:30:22.467";
  26. data.Add(infoObj1);
  27. AvailibilityDto infoObj2 = new AvailibilityDto();
  28. infoObj2.Id = 2;
  29. infoObj2.Title = "Available";
  30. infoObj2.Desc = "Description 1";
  31. infoObj2.Start_Date = "2020-08-17 10:00:22.467";
  32. infoObj2.End_Date = "2020-08-17 11:00:22.467";
  33. data.Add(infoObj2);
  34. AvailibilityDto infoObj3 = new AvailibilityDto();
  35. infoObj3.Id = 3;
  36. infoObj3.Title = "Meeting";
  37. infoObj3.Desc = "Description 1";
  38. infoObj3.Start_Date = "2020-08-18 07:30:22.467";
  39. infoObj3.End_Date = "2020-08-18 08:00:22.467";
  40. data.Add(infoObj3);
  41. return Json(data, JsonRequestBehavior.AllowGet);
  42. }
  43. [HttpPost]
  44. public ActionResult UpdateCalanderData(AvailibilityDto model)
  45. {
  46. var id = model.Id;
  47. //Write your update code here
  48. return Json(id, JsonRequestBehavior.AllowGet);
  49. }
  50. }
  51. }
Step 4
Create mycalander.js
  1. $(function () {
  2. /* initialize the external events
  3. -----------------------------------------------------------------*/
  4. function ini_events(ele) {
  5. ele.each(function () {
  6. // create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/)
  7. // it doesn't need to have a start or end
  8. var eventObject = {
  9. title: $.trim($(this).text()) // use the element's text as the event title
  10. }
  11. // store the Event Object in the DOM element so we can get to it later
  12. $(this).data('eventObject', eventObject)
  13. // make the event draggable using jQuery UI
  14. $(this).draggable({
  15. zIndex: 1070,
  16. revert: true, // will cause the event to go back to its
  17. revertDuration: 0 // original position after the drag
  18. })
  19. })
  20. }
  21. ini_events($('#external-events div.external-event'))
  22. /* initialize the calendar
  23. -----------------------------------------------------------------*/
  24. //Date for the calendar events (dummy data)
  25. var date = new Date()
  26. var d = date.getDate(),
  27. m = date.getMonth(),
  28. y = date.getFullYear()
  29. var Calendar = FullCalendar.Calendar;
  30. var Draggable = FullCalendarInteraction.Draggable;
  31. var containerEl = document.getElementById('external-events');
  32. var checkbox = document.getElementById('drop-remove');
  33. var calendarEl = document.getElementById('calendar');
  34. // initialize the external events
  35. // -----------------------------------------------------------------
  36. new Draggable(containerEl, {
  37. itemSelector: '.external-event',
  38. eventData: function (eventEl) {
  39. console.log(eventEl);
  40. return {
  41. title: eventEl.innerText,
  42. backgroundColor: window.getComputedStyle(eventEl, null).getPropertyValue('background-color'),
  43. borderColor: window.getComputedStyle(eventEl, null).getPropertyValue('background-color'),
  44. textColor: window.getComputedStyle(eventEl, null).getPropertyValue('color'),
  45. };
  46. }
  47. });
  48. GetData();
  49. function GenerateCalander(events) {
  50. var calendar = new Calendar(calendarEl, {
  51. //Plugins for full canlender
  52. //plugins: ['bootstrap', 'interaction', 'dayGrid', 'timeGrid'],
  53. //initialView: 'timeGridWeek',
  54. plugins: ['bootstrap', 'interaction', 'timeGrid'],
  55. initialView: 'timeGridWeek',
  56. //select your timeZone as u wish to select
  57. timeZone: 'UTC',
  58. //Slot duration fix to 30 minutes now .......you can chage any slot duration from here.
  59. slotDuration: '00:30:00',
  60. slotLabelInterval: 30,
  61. slotMinutes: 30,
  62. snapDuration: '01:00:00',
  63. header: {
  64. left: 'prev,next today',
  65. center: 'title',
  66. //right: 'dayGridMonth,timeGridWeek,timeGridDay'
  67. right: 'timeGridWeek'
  68. },
  69. //Random default events
  70. events: events
  71. ,
  72. editable: true,
  73. droppable: true, // this allows things to be dropped onto the calendar !!!
  74. drop: function (info) {
  75. // is the "remove after drop" checkbox checked?
  76. if (checkbox.checked) {
  77. // if so, remove the element from the "Draggable Events" list
  78. info.draggedEl.parentNode.removeChild(info.draggedEl);
  79. }
  80. },
  81. nextDayThreshold: "00:00:00",
  82. nowIndicator: true,
  83. eventDrop: function (data) {
  84. UpdateEventDetails(data.event.id, data.event.start, data.event.end);
  85. },
  86. eventResize: function (data) {
  87. //console.log(data.event.id)
  88. //update your event here
  89. UpdateEventDetails(data.event.id, data.event.start, data.event.end);
  90. },
  91. eventClick: function (calEvent, jsEvent, view) {
  92. //Work on click event like delete and view details
  93. alert('Click Event Called')
  94. },
  95. selectHelper: true,
  96. select: function (start, end, jsEvent, view) {
  97. //called when an event is selected
  98. alert('Select Event Called')
  99. },
  100. });
  101. calendar.render();
  102. }
  103. /* ADDING EVENTS */
  104. var currColor = '#3c8dbc' //Red by default
  105. //Color chooser button
  106. var colorChooser = $('#color-chooser-btn')
  107. $('#color-chooser > li > a').click(function (e) {
  108. e.preventDefault()
  109. //Save color
  110. currColor = $(this).css('color')
  111. //Add color effect to button
  112. $('#add-new-event').css({
  113. 'background-color': currColor,
  114. 'border-color': currColor
  115. })
  116. })
  117. $('#add-new-event').click(function (e) {
  118. e.preventDefault()
  119. //Get value and make sure it is not null
  120. var val = $('#new-event').val()
  121. if (val.length == 0) {
  122. return
  123. }
  124. //Create events
  125. var event = $('<div />')
  126. event.css({
  127. 'background-color': currColor,
  128. 'border-color': currColor,
  129. 'color': '#fff'
  130. }).addClass('external-event')
  131. event.html(val)
  132. $('#external-events').prepend(event)
  133. //Add draggable funtionality
  134. ini_events(event)
  135. //Remove event from text input
  136. $('#new-event').val('')
  137. })
  138. function GetData() {
  139. var events = [];
  140. $.ajax({
  141. url: 'http://localhost:3617/admin/Calander/GetCalendarData',
  142. type: "GET",
  143. dataType: "JSON",
  144. success: function (result) {
  145. $.each(result, function (i, data) {
  146. events.push(
  147. {
  148. title: data.Title,
  149. description: data.Desc,
  150. start: moment(data.Start_Date).format('YYYY-MM-DD HH:mm:ss'),
  151. end: moment(data.End_Date).format('YYYY-MM-DD HH:mm:ss'),
  152. backgroundColor: '#00a65a', //Success (green)
  153. borderColor: '#00a65a', //Success (green)
  154. id: data.Id,
  155. allDay: false,
  156. });
  157. });
  158. GenerateCalander(events);
  159. }
  160. })
  161. }
  162. function UpdateEventDetails(eventId, StartDate, EndDate) {
  163. debugger
  164. var object = new Object();
  165. object.Id = parseInt(eventId);
  166. object.Start_Date = StartDate;
  167. object.End_Date = EndDate;
  168. $.ajax({
  169. url: 'http://localhost:3617/admin/Calander/UpdateCalanderData',
  170. type: "POST",
  171. dataType: "JSON",
  172. data: object,
  173. success: function (result) {
  174. debugger;
  175. alert("updated successfully-Id:" + result)
  176. }
  177. });
  178. }
  179. });
Step 5
index.cshtml page
  1. @{
  2. ViewBag.Title = "Index";
  3. Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
  4. }
  5. <link href="~/Areas/Admin/CalanderCssJs/fullcalendar/main.min.css" rel="stylesheet" />
  6. <link href="~/Areas/Admin/CalanderCssJs/fullcalendar-daygrid/main.min.css" rel="stylesheet" />
  7. <link href="~/Areas/Admin/CalanderCssJs/fullcalendar-timegrid/main.min.css" rel="stylesheet" />
  8. <link href="~/Areas/Admin/CalanderCssJs/fullcalendar-bootstrap/main.min.css" rel="stylesheet" />
  9. <!-- Main content -->
  10. <section class="content">
  11. <div class="container-fluid">
  12. <div class="row">
  13. <div class="col-md-3">
  14. <div class="sticky-top mb-3">
  15. <div class="card">
  16. <div class="card-header">
  17. <h4 class="card-title">Draggable Events</h4>
  18. </div>
  19. <div class="card-body">
  20. <!-- the events -->
  21. <div id="external-events">
  22. <div class="external-event bg-success">Lunch</div>
  23. <div class="external-event bg-warning">Go home</div>
  24. <div class="external-event bg-info">Do homework</div>
  25. <div class="external-event bg-primary">Work on UI design</div>
  26. <div class="external-event bg-danger">Sleep tight</div>
  27. <div class="checkbox">
  28. <label for="drop-remove">
  29. <input type="checkbox" id="drop-remove">
  30. remove after drop
  31. </label>
  32. </div>
  33. </div>
  34. </div>
  35. <!-- /.card-body -->
  36. </div>
  37. <!-- /.card -->
  38. <div class="card">
  39. <div class="card-header">
  40. <h3 class="card-title">Create Event</h3>
  41. </div>
  42. <div class="card-body">
  43. <div class="btn-group" style="width: 100%; margin-bottom: 10px;">
  44. <!--<button type="button" id="color-chooser-btn" class="btn btn-info btn-block dropdown-toggle" data-toggle="dropdown">Color <span class="caret"></span></button>-->
  45. <ul class="fc-color-picker" id="color-chooser">
  46. <li><a class="text-primary" href="#"><i class="fas fa-square"></i></a></li>
  47. <li><a class="text-warning" href="#"><i class="fas fa-square"></i></a></li>
  48. <li><a class="text-success" href="#"><i class="fas fa-square"></i></a></li>
  49. <li><a class="text-danger" href="#"><i class="fas fa-square"></i></a></li>
  50. <li><a class="text-muted" href="#"><i class="fas fa-square"></i></a></li>
  51. </ul>
  52. </div>
  53. <!-- /btn-group -->
  54. <div class="input-group">
  55. <input id="new-event" type="text" class="form-control" placeholder="Event Title">
  56. <div class="input-group-append">
  57. <button id="add-new-event" type="button" class="btn btn-primary">Add</button>
  58. </div>
  59. <!-- /btn-group -->
  60. </div>
  61. <!-- /input-group -->
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. <!-- /.col -->
  67. <div class="col-md-9">
  68. <div class="card card-primary">
  69. <div class="card-body p-0">
  70. <!-- THE CALENDAR -->
  71. <div id="calendar"></div>
  72. </div>
  73. <!-- /.card-body -->
  74. </div>
  75. <!-- /.card -->
  76. </div>
  77. <!-- /.col -->
  78. </div>
  79. <!-- /.row -->
  80. </div><!-- /.container-fluid -->
  81. </section>
  82. <!-- /.content -->
  83. @section scripts{
  84. <script src="~/Areas/Admin/CalanderCssJs/jquery-ui/jquery-ui.min.js"></script>
  85. <script src="~/Areas/Admin/CalanderCssJs/moment/moment.min.js"></script>
  86. <script src="~/Areas/Admin/CalanderCssJs/fullcalendar/main.min.js"></script>
  87. <script src="~/Areas/Admin/CalanderCssJs/fullcalendar-daygrid/main.min.js"></script>
  88. <script src="~/Areas/Admin/CalanderCssJs/fullcalendar-timegrid/main.min.js"></script>
  89. <script src="~/Areas/Admin/CalanderCssJs/fullcalendar-interaction/main.min.js"></script>
  90. <script src="~/Areas/Admin/CalanderCssJs/fullcalendar-bootstrap/main.min.js"></script>
  91. <!-- Page specific script -->
  92. <script src="~/Areas/Admin/CalanderCssJs/mycalander.js"></script>
  93. }
plugins: ['bootstrap', 'interaction', 'dayGrid', 'timeGrid'] for displaying full calender
Full Calender integration in mvc
Slot duration fix to 30 minutes now .......you can chage any slot duration from here.
Full Calender integration in mvc
Full Calender integration in mvc
Function for getting slot list,
  1. function GetData() {
  2. var events = [];
  3. $.ajax({
  4. url: 'http://localhost:3617/admin/Calander/GetCalendarData',
  5. type: "GET",
  6. dataType: "JSON",
  7. success: function (result) {
  8. $.each(result, function (i, data) {
  9. events.push(
  10. {
  11. title: data.Title,
  12. description: data.Desc,
  13. start: moment(data.Start_Date).format('YYYY-MM-DD HH:mm:ss'),
  14. end: moment(data.End_Date).format('YYYY-MM-DD HH:mm:ss'),
  15. backgroundColor: '#00a65a', //Success (green)
  16. borderColor: '#00a65a', //Success (green)
  17. id: data.Id,
  18. allDay: false,
  19. });
  20. });
  21. GenerateCalander(events);
  22. }
  23. })
  24. }
Full Calender integration in mvc
Output
So here we see that allocated timing slots are displayed in green color badges and some descriptions can be written there as we want them to be displayed.
Full Calender integration in mvc