6

I am using full calendar to generate dates and show events. everything is working fine but I want an additional feature i.e I want to change the cell color to red if it has more than 3 events. If a date has more than 3 functions/events then the entire cell color should changed to red color. So that user can know the booking is full. I have also pasted the screenshot below

Following is my code :-

 function clickmeforcalender(event) {

    debugger


    $('#calendar').show();
    var events = [];
    $.ajax({
        type: "GET",
        url: "/Booking/GetEvents",
        success: function (data) {
            $.each(data, function (i, a) {

                events.push({

                    title: a.Function_Name,
                    start: a.Function_Date1,
                    url: a.Booking_ID,
                    FSlot: a.Function_Slot,
                    MSlot: a.Marquee_Name,
                    Marquee_Slot: a.Marquee_Slot,
                    BPerson: a.Booking_Person,
                    BookedBy: a.Booking_Name,
                });

                $("#calendar").css("background-color", "WHITE");
            })
            var allEvents = $(".calendar").fullCalendar("clientEvents");

            var exists = 0;
            $.each(allEvents, function (index, value) {

                if (new Date(value.start).toDateString() === new Date(date).toDateString()) {
                    exists++;
                    if (exists == 2) {

                        value.css("background-color", "red");
                    }

                }

            });
            GenerateCalender(events);
        },

        error: function (error) {
            alert('failed');
        }
    });
};
function GenerateCalender(events) {
    debugger
    $('#calendar').fullCalendar({
        height: 550,

        header: {
            left: 'prev,next today',
            center: 'addEventButton',
            right: 'month,agendaWeek,agendaDay,listWeek',

        },

        defaultDate: new Date(),
        navLinks: true,
        editable: true,
        eventLimit: true,
        events: events,



        eventClick: function (calEvent, jsEvent, view) {
            selectedEvent = calEvent;
            //alert('Event: ' + calEvent.title);
            jsEvent.preventDefault();
            $('#myModal #eventTitle').text(calEvent.BookedBy + "-" + calEvent.title).css("font-weight", "Bold");
            var $description = $('<div/>');
            $description.append($('<p/>').html('<b>FucntionDate:</b>' + calEvent.start.format("DD-MMM-YYYY HH:mm")));
            //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>EventName:</b>' + calEvent.title));
            if (calEvent.MSlot == 1) {
                $description.append($('<p/>').html('<b>MaqueeSlot:</b>' + "Full"));
            }
            else if (calEvent.MSlot == 2) {
                $description.append($('<p/>').html('<b>MaqueeSlot:</b>' + "Half"));

            }
            else {
                $description.append($('<p/>').html('<b>MaqueeSlot:</b>' + calEvent.MSlot));
            }
            if (calEvent.FSlot == 1) {
                $description.append($('<p/>').html('<b>FunctionSlot:</b>' + "Morning"));
            }
            else if (calEvent.FSlot == 2) {
                $description.append($('<p/>').html('<b>FunctionSlot:</b>' + "Evening"));
            }
            else {
                $description.append($('<p/>').html('<b>FunctionSlot:</b>' + calEvent.FSlot));
            }
            $description.append($('<p/>').html('<b>Booking Persons:</b>' + calEvent.BPerson));

            $('#myModal #pDetails').empty().html($description);

            var temp = $('#myModal').modal();



        },


    });
}

Screenshot of my fronted is as below:- enter image description here

EternalHour
  • 8,308
  • 6
  • 38
  • 57
Khizar Nayyar
  • 378
  • 1
  • 14
  • 1
    You may find the following callbacks and methods useful to you in pursuing this: [eventAfterAllRender](https://fullcalendar.io/docs/v3/eventAfterAllRender), [clientEvents](https://fullcalendar.io/docs/v3/clientEvents) and [these articles](https://www.google.com/search?q=fullcalendar+highlight+certain+days). – ADyson Sep 09 '19 at 22:20
  • 1
    I also strongly recommend you change your code to use the [events as JSON feed pattern](https://fullcalendar.io/docs/v3/events-json-feed) which will a) simplify your code, and b) allow you to download only the events you actually need for the time period being dislpayed (because your server can filter them by the start/end dates provided automatically by fullCalendar). That will in turn help with your requirement above, because you'll have less events to search through, and the highlighting can update more dynamically as events are added/removed/updated. – ADyson Sep 09 '19 at 22:21
  • Hopefully using the above you can make a better attempt to solve your issue. If you are still stuck after some more attempts, please show your updated code so we can help a bit further. Thanks. – ADyson Sep 09 '19 at 22:22
  • I have tried several solutions but no result. Just want to encountered in which dates more than three events are occurring, so I can make the entire cell background-color change – Khizar Nayyar Sep 10 '19 at 14:13
  • Ok but we can't fix your attempts if you don't show us. Show us your best attempt please. And study those links I gave - like I said, it should give you a clue what to do. (Hint: wait for all events to render. Then get a list of all events on the page. Group those events by date. For any single date having 3 events or more, change the background colour for the corresponding date cell. This logic is not complicated.) – ADyson Sep 10 '19 at 14:24
  • Sir I have used the stack overflow solutions/answers provided on those link's you mentioned I'm mentioning below the last closed one in which I am eventRender: function (event, element, view) { / var dateString = moment(event.start).format('YYYY-MM-DD'); $('#calendar').find('.fc-day[data-date="' + dateString + '"]').css('background-color', '#FAA732'); }, It changes the color of all dates which have events. I even check your solution http://jsfiddle.net/3hw4852y/21/ and made several changes – Khizar Nayyar Sep 10 '19 at 14:37
  • Ok so in that JSFiddle code you got the error `dateString is not defined` in your console. Did you notice that? You need to set a suitable date to be amended. Also you are only doing this in eventReceive, so it will only work when an event is dragged onto the calendar. It will not apply to other events. If you look back at my last comment, you'll see how you can apply it to all situations. – ADyson Sep 10 '19 at 15:03
  • Here I'm with my code Used the eventAfterAllRender and ClientEvents I am trying to get the dates from all events in date format but its returning me [object]. eventAfterAllRender: function (view) { debugger var allEvents = $("#calendar").fullCalendar("clientEvents"); var array = $('#calendar').fullCalendar('clientEvents', function (events) { return (moment(allEvents).format('YYYY-MM-DD')); }); alert(array) }, – Khizar Nayyar Sep 11 '19 at 12:05
  • that's because you can't alert an array. You're basically telling Javascript to display the array as a string on screen. But it has no idea of how you want to present the data, so it just says "object" instead. It doesn't mean there's anything wrong with your code or data. If you want to check the data you've got, a better way is to a) log it to the console (so you can see multiple logs at once, copy/paste it, etc) and b) format it as JSON for readability. So replace `alert(array);` with `console.log(JSON.stringify(array));` and open your console. You should get some more useful output. – ADyson Sep 11 '19 at 12:22
  • I'm getting on console " VM520 Booking:597 Uncaught TypeError: Converting circular structure to JSON " – Khizar Nayyar Sep 11 '19 at 12:32
  • Ok. Just noticed that your code for "clientEvents" does not make any sense at all. You call clientEvents once, which gets you all events. Then for some reason you call it again, but providing a callback and inside the callback you try to convert the "allEvents" list into a momentJS object. I'm surprised that doesn't throw an error for one thing, but also it's totally illogical. – ADyson Sep 11 '19 at 12:37
  • The point of the callback in clientEvents is that it will run once for each event in the list, giving you an opportunity to decide whether to return it in the final list, or not. – ADyson Sep 11 '19 at 12:38
  • But for this you don't need that - you need to return all the events. And then you need your own loop to look at each event, look at its date, and then update your counters showing how many events are happening on each day you find. – ADyson Sep 11 '19 at 12:39
  • Sir I'm unable to do any solution, Thank you for your so much time and concern – Khizar Nayyar Sep 11 '19 at 13:52

1 Answers1

3

I can see you have made some effort to try and solve this (as per the comments) but you appear to have had some problems implementing the suggested algorithm in JavaScript.

To recap, the basic process for doing what you want is as follows:

1) wait for all events to finish loading in the calendar

2) get a list of all events currently visible

3) Keep a list of counters which record how many events occur on a particular day. Then check the start date of each event, and increase the counter for the date by one for each matching event.

4) Once all the events are checked, look at each counter. If any of them records more than 3 events, then change the background colour of the cell for that day in the calendar.

This is not complicated logic, but I can see that you struggled to apply your JavaScript knowledge to turn it into code.

Here is a simple solution for doing it:

eventAfterAllRender: function(view) { //wait till all events have loaded and rendered
  //get all events
  var events = $("#calendar").fullCalendar("clientEvents");
  var dates = {}; //this object will hold the list of dates on which events occur, and the number of events occurring on those dates

  //loop through all the events
  events.forEach(function(ev, index) {
    var startDateStr = ev.start.format("YYYY-MM-DD");
    //either 
    //a) create a new entry for the event's start date and set it to 1, OR
    //b) increase the count of the entry for that date, if it already exists
    // this will build up a list of all dates on which events start, and record how many events start on each of those days
    //it does this by using an empty object, and then adding keys to that object - the key is the date, and the value is the count of events for that date
    dates[startDateStr] = (dates[startDateStr] + 1 || 1);
  });

  //log for debugging / illustration
  console.log(dates);

  //loop through the list of dates which contain events
  for (var dt in dates) {
    //check the count of events for that date. If the count is 3 or more, then change the cell colour for that date in fullCalendar
    if (dates[dt] > 3) {
      $('#calendar').find('.fc-day[data-date="' + dt + '"]').css('background-color', '#FAA732');
    }
  }
}

Live demo: http://jsfiddle.net/9zupvcfo/2/

ADyson
  • 57,178
  • 14
  • 51
  • 63