How can I correctly create filters for fullcalender plugin

Viewed 50

I have a working calendar view in one of my ASP.NET MVC application, I am bringing in my data from the my database in json format through the controller into the fullcalendar jquery plugin to create the calendar with this html and javascript code. How do I create a filter using the select #Term dropdowns?


@{
    ViewBag.Title = "Calendar";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="heading" style="width: 100%; float: left; margin-bottom: 15px;">
    <h2 style="float: left">Calendar</h2>
    <select id="Term" style="float: right; margin-top: 20px;">
        <option value="all">All</option>
        <option value="2021-2022">2021-2022</option>
        <option value="2022-2023">2022-2023</option>
        <option value="2023-2024">2023-2024</option>
    </select>
 
</div>

<div id="calender"></div>



<div id="myModal" class="modal fade" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title"><span id="eventTitle"></span></h4>

            </div>
            <div class="modal-body">
                <p id="pDetails"></p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>




<link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.css" rel="stylesheet" />
<link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.print.css" rel="stylesheet" media="print" />

@section Scripts{
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.js"></script>

    <script>
            $(document).ready(function () {
                var events = [];
                $.ajax({
                    type: "GET",
                    url: "/home/GetEvents", 
                    success: function (data) {
                        $.each(data, function (i, v) {
                            events.push({
                                title: v.EventType,
                                description: v.School,
                                start: moment(v.Date),
                                end: v.End != null ? moment(v.Date) : null,
                                color: v.Color,
                                year: v.TermYear,
                                school: v.School
                            });
                        })

                        GenerateCalender(events);

                    },

                    error: function (error) {
                        alert('failed');
                    }
                })


                function GenerateCalender(events) {
                    $('#calender').fullCalendar('render');
                    $('#calender').fullCalendar({
                        contentHeight: 400,
                        defaultDate: new Date(),
                        timeFormat: 'h(:mm)a',
                        header: {
                            left: 'prev,next today',
                            center: 'title',
                            right: 'month,basicWeek,basicDay,agenda'
                        },
                        eventLimit: true,
                        eventColor: '#378006',
                        events: events,
                        eventClick: function (calEvent, jsEvent, view) {
                            $('#myModal #eventTitle').text(calEvent.title);
                            var $description = $('<div/>');
                            $description.append($('<p/>').html('<b>Start:</b>' + calEvent.start.format("DD-MMM-YYYY HH:mm a")));
                            if (calEvent.end != null) {
                                $description.append($('<p/>').html('<b>End:</b>' + calEvent.end.format("DD-MMM-YYYY HH:mm a")));
                            }
                            $description.append($('<p/>').html('<b>School:</b>' + calEvent.description));
                            $('#myModal #pDetails').empty().html($description);

                            $('#myModal').modal();
                        }
                    })



                }

            })
        </script>
    }
1 Answers

As per your request in the comments, I will demonstrate how the event feed should be implemented using fullCalendar 5.

Firstly, it does not make much sense to download the events and then initialise the calendar. That delays the showing of the calendar, and also means that fullCalendar has no way of requesting new events when needed. You should not simply have your server download all possible events in its database at the beginning - once your calendar has existed for a while and you have lots of events, it can slow the process down to fetch lots of historical events which will probably never be viewed. Instead, your server should provide only the events which fall within the time period fullCalendar is currently displaying. If you implement the calendar setup as I show below, fullCalendar can provide these dates to your server for its use. Then, if the user changes the view to display a different time period, only then will the calendar make another request to your server to fetch the needed events. This is usually more efficient because events are only downloaded if they're actually needed.

Since it appears your server doesn't provide JSON data in exactly the format fullCalendar requires, you need to use the events as a function approach shown in the documentation, where you define a custom callback which fullCalendar can execute whenever it needs to fetch events. That callback can then run your AJAX request, get the events from the server and pass them back to fullCalendar (via the provided callback, as shown in the example in the documentation).

Something like this should work for you:

document.addEventListener('DOMContentLoaded', function() {
  var calendarEl = document.getElementById('calendar');
  var calendar = new FullCalendar.Calendar(calendarEl, {
    initialView: 'dayGridMonth',
    headerToolbar: {
      left: "prev,next today",
      center: "title",
      right: "dayGridMonth,timeGridWeek,timeGridDay,listMonth"
    },
    events: function(fetchInfo, successCallback, failureCallback) //function to run whenever the calendar needs events
    {
      $.ajax({
        type: "GET",
        url: "/home/GetEvents", 
        data: { start: fetchInfo.startStr, end: fetchInfo.endStr }, //pass the date range to the server, so it can return only what's needed, not the whole database
        success: function (data) {
          var events = [];
    
          $.each(data, function (i, v) {
            events.push({
              title: v.EventType,
              description: v.School,
              start: moment(v.Date).format("YYYY-MM-DD"),
              end: v.End != null ? moment(v.Date).format("YYYY-MM-DD") : null,
              color: v.Color,
              year: v.TermYear,
              school: v.School
            });
          });
    
          successCallback(events); //pass the events back to fullCalendar
        },
        error: function (error) {
          alert('fetching events failed');
          console.log(error);
          failureCallback(error);
        }
      });
    }
  });

  calendar.render();
});

Relevant documentation:

Related