Full Calender Integration In MVC

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