codingnighter2000
codingnighter2000

Reputation: 529

fullcalendar: trouble rendering events with ajax when pressing 'prev' or 'next'

I am building a calendar via fullcalendar.

I get my data for the month via external ajax request. here are the main variables of data i use to render the fullcalendar:

when i first start my calendar - everything is ok. all of the data and events are being displayed in the calendar perfectly. but when i press 'prev' or 'next', only the 'json_backgrundColor' and the 'json_iconstring' are being updated and displayed in the calendar.(i guess because they are in the dayRender Function)
the events and the alternative title names do not update and are not being displayed.

here is the code:

    <script>
    var date = new Date();
    var d = date.getDate();
    var m = date.getMonth();
    m = m + 1;
    var y = date.getFullYear();
    var ajaxData;
    var eventsJsonArray;
    var json_backgrundColor;
    var json_iconstring;
    var DefaulteDateForFullCalendarISO8601;
    var MonthDisplayTitle_GetAlternativeMonthDisplay;
    var MonthDisplayTitle_GetAlternativeYearDisplay;
    var MonthDisplayTitle_GetGregorianYear;
    getMonthData(m, y);
    function getMonthData(m, y) {
        //getting Month data
        $.ajax({
            url: '$getMonthDataUrl',
            type: 'GET',
            data: {
                gregorianMonth: m,
                gregorianYear: y
            },
            error: function () {
                alert('there was an error while fetching events!');
            },
            success: function (data) {
                ajaxData = data;
                eventsJsonArray = ajaxData['all_The_Events_For_The_Month'];
                json_iconstring = ajaxData['iconString'];
                json_backgrundColor = ajaxData['Big_Calendar_cell_background_color'];
                MonthDisplayTitle_GetAlternativeMonthDisplay = ajaxData['fullMonthDetails']['MonthEngDisplay'];
                MonthDisplayTitle_GetAlternativeYearDisplay = ajaxData['fullMonthDetails']['YearDisplay'];
                MonthDisplayTitle_GetGregorianYear = ajaxData['fullMonthDetails']['GregorianYear'];
                DefaulteDateForFullCalendarISO8601 = ajaxData['fullMonthDetails']['DefaulteDateForFullCalendarISO8601'];
                alert('ajax works! nicee!');
                //console.log(ajaxData);
                //console.log(DefaulteDateForFullCalendarISO8601);

            }
        });
    }

    //oridinal place for getmonthdate
    alert('Hello! 1!');
    $(document).ready(function () {
        console.log(eventsJsonArray);
        $('#calendar').fullCalendar({
            header: {
                left: 'prev',
                center: 'title',
                right: 'next'
            },
            events: eventsJsonArray,
            fixedWeekCount: false,
            monthNamesShort: ['January ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'February ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'March ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'April ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'May ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'June ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'July ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'August ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'September ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'October ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'November ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay, 'December ' + MonthDisplayTitle_GetGregorianYear + ' : ' + MonthDisplayTitle_GetAlternativeMonthDisplay + ' ' + MonthDisplayTitle_GetAlternativeYearDisplay],
            titleFormat: 'MMM',
            dayRender: function (date, cell) {
                var cellDate = date.format('D');
                if (!cell.hasClass('fc-other-month')) {
                    //if this if is true that means that the day belongs to the current relevant month (and not to the prev \ next month)
                    cell.css('background-color', json_backgrundColor[cellDate]);

//from here: cheking which icons to show

                    if (json_iconstring[cellDate].includes('HAV')) {
                        cell.prepend('<img src=\' /havdala2.png \'>');
                    }

                    //until here:: cheking which icons to show

                } else {
                    //this days belongs to the prev \ next months. so we give them opacity)        
                    cell.css('background-color', '#ffffff');
                }

            }
        })

    });
    alert('Hello!2 !');

    $('body').on('click', 'button.fc-prev-button', function () {
//do something
        alert('whatupppp!prev !');
//console.log(m,y);
        if (m === 1) {
            m = 12;
            y = y - 1;
        }
        else {
            m = m - 1;
        }
        getMonthData(m, y);
        console.log(eventsJsonArray);
    });

    $('body').on('click', 'button.fc-next-button', function () {
//do something
        alert('whatupppp!next !');
        //console.log(m,y);
        if (m === 12) {
            m = 1;
            y = y + 1;
        }
        else {
            m = m + 1;
        }
        getMonthData(m, y);
        console.log(eventsJsonArray);
    });
</script>

anybody knows what is wrong with my code? and how can i fix it so when i'll press 'next' / 'prev' the events and alternative titles will get updated and displayed?

many thanks!!

Upvotes: 1

Views: 1299

Answers (1)

ADyson
ADyson

Reputation: 61849

Your events are entirely static.

events: eventsJsonArray

This points to a single array. When your page loads, you run "getMonthData" and populate eventsJsonArray. This is passed to fullCalendar once. Even though you may update eventsJsonArray itself afterwards, you never tell fullCalendar that it has changed.

Anyway, there's no need for all this convoluted trickery, handling the next/previous events etc. You're fighting fullCalendar, when it wants to help you. Read the documentation more carefully about the types of event sources you can have - a static array, as you've done, is just one option. You can also define a custom function, which could call your ajax, or, if you implement your server-side in a compatible way, you can just point fullCalendar directly at your server endpoint. Using either of these methods, whenever the view changes, fullCalendar automatically queries the server again to fetch events which match the time period displayed in the new view.

The correct option for you is the events-as-a-function style, because you've got some extra custom functionality in there: https://fullcalendar.io/docs/event_data/events_function/

Your entire code can look like this:

var json_iconstring; //this needs to have a higher scope
var gregorianMonths = [];// you need to pre-load this data - see below

$(document).ready(function () {

    $('#calendar').fullCalendar({
        header: {
            left: 'prev',
            center: 'title',
            right: 'next'
        },
        events: function( start, end, timezone, callback ) { //custom events function to be called every time the view changes
          $.ajax({
            url: '$getMonthDataUrl',
            type: 'GET',
            data: {
              gregorianMonth: start.month() + 1,
              gregorianYear: start.year()
            },
            error: function (jqXHR, textStatus, errorThrown) {
              alert('Error loading events: ' + textStatus + " - " + errorThrown);
            },
            success: function (data) {
              json_iconstring = data['iconString'];
              callback(data['all_The_Events_For_The_Month']); //pass the event data to fullCalendar via the supplied callback function
            }
          });
        },
        fixedWeekCount: false,
        monthNamesShort: gregorianMonths, //you need to pre-load this, not via ajax - see below
        titleFormat: 'MMM',
        showNonCurrentDates: false, //this built-in option replaces your test for jsonbackgroundcolour in the dayRender method
        dayRender: function (date, cell) {
            var cellDate = date.format('D');
            if (json_iconstring[cellDate].includes('HAV')) {
                cell.prepend('<img src=\' /havdala2.png \'>');
            }
        }
    });
});

As an extra task, you should consider changing your server-side code to accept full "start" and "end" dates instead of just months. The advantage of this is that, if your user selects the "day" or "week" view, it only downloads data for that day or week which is more efficient and uses less bandwidth.

P.S. You also need to find a different way to set your month display names - I would just pre-inject a list into the page via your server code, rather than trying to fetch via ajax. These options are pre-set when the load the calendar and fullCalendar will ignore attempts to update them after that, unless you explicitly reset the entire monthNamesShort option, but that would just be inefficient.

P.P.S. I replaced some code in your dayRender function with a built-in option - https://fullcalendar.io/docs/display/showNonCurrentDates/ . I suggest you make a more careful study of the documentation in future before attempting to create workarounds for features which may actually be available already.

Upvotes: 1

Related Questions