bootstrap-year-calendar icon indicating copy to clipboard operation
bootstrap-year-calendar copied to clipboard

clickDay handler is called as many times as calendar is rendered

Open ptica opened this issue 8 years ago • 3 comments

i use the calendar as a custom view in fullcalendar.io and as it allows to navigate the year displayed the render could be called multiple times, unfortunately in such circumstances the clickDay handler is invoked multiple times as well:

var FC = $.fullCalendar;
var View = FC.View;
var CustomYear;

CustomYear = View.extend({ // make a subclass of View
	render: function() {
		// responsible for displaying the skeleton of the view within the already-defined
		// this.el, a jQuery element.
		var cal = this.el.calendar({
			startYear: this.start.format('YYYY'),
			displayWeekNumber: true,
			displayHeader: false,
			clickDay: function (e) {
				// beware this event will be fired multiple times
				// if user happens to navigate to previous/next years using the arrows
				// as render will be called multiple times as well
			},
			customDayRenderer: function (el, date) {
				el.data('goto', {
					date: FC.moment(date).format('YYYY-MM-DD'),
					type: 'day'
				});
			}
		});
	},
});

FC.views.customYear = {
	'class': CustomYear,
	duration: { years: 1 }
}

ptica avatar Nov 25 '16 09:11 ptica

I'm experiencing the same problem: clickDay event is triggered as many times as I loaded the calendar. I think I should "destroy" the callendar before reloading it but I don't know how to do so.

n0ct avatar May 22 '17 12:05 n0ct

If anyone is still having this problem, I believe I found the issue and a work-around. I believe the problem is that the events are bound to the data 'attributes' of the target element (the element .calendar was called on). If you try to reinitialize the calendar by calling .calendar on this same element, the event bindings are added to the existing ones resulting in multiple handlers per event.

The solution, then is to destroy the element you initially called .calendar on and create a new one. Something like this would do it (where "myTargetDiv" is the id of the div I want the calendar in):

$("#myTargetDiv").html("");
$("#myTargetDiv").append("<div></div>");
$("#myTargetDiv div").calendar();

eanugent avatar Aug 10 '18 15:08 eanugent

As this is still not resolved, I managed to workaround in a similar way:

First, above any functions: calendar_iteration = 0; Then, in the function where you call the calendar (for example inside an AJAX call): calendar_iteration++; $(".calendar").html("<div class='iteration_"+calendar_iteration+"'></div>"); $('.calendar .iteration_'+calendar_iteration).calendar({});

Simple hack. Works fine.

ghost avatar Jun 24 '19 10:06 ghost