Reputation: 529
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:
eventsJsonArray - i use this variable to load all of the events of the month
json_backgrundColor - i use this variable in order to change the background color of each day of the relevant month
json_iconstring - i use this variable to show an icon in some days
MonthDisplayTitle_GetAlternativeMonthDisplay & etc - i use this variables in order to change the calendar title
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
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