问题
I am building a calendar that will display three types of events: holidays, events and meeting. I would like to be able to filter the events using a series of three checkboxes to show and hide the selected event type.
I have managed to get the events to display when the page loads and am able to hide and show the selected event using the checkboxes.
The issue I am having is when it comes to changing the viewed month.
When either the forward and back month buttons are clicked the calendar will ignore the filters and display the hidden event type. On top of this the calendar will duplicate the events for all types.
Could someone please have a look through the code and tell me where I am going wrong?
$(document).ready(function() {
var windows_size = $(window).width();
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar('removeEvents');
var calendar = $('#calendar').fullCalendar({
events: '<?php echo base_url("calendar/get_events"); ?>',
editable: true, // Set the calendar to be editable, ie, moving the dates and adjusting length of events
windowResize: function(view) {
if ($(window).width() < 768){
$('#calendar').fullCalendar( 'changeView', 'basicDay' );
$('.fc-month-button').hide();
$('.fc-agendaWeek-button').hide();
$('.fc-agendaDay-button').hide();
} else {
$('#calendar').fullCalendar( 'changeView', 'month' );
$('.fc-month-button').show();
$('.fc-agendaWeek-button').show();
$('.fc-agendaDay-button').show();
}
},
timeFormat: "HH:mm", // Format the date that is displayed on the calendar to be 24 hour instead of 3am
header: {
left: 'prev,next today', // Buttons on the left of header of calendar
center: 'title', // Shows the date of the calendar page being viewed
right: 'month,agendaWeek,agendaDay' // Buttons on the right of the calendar
},
selectable: true,
selectHelper: true,
select: function(event, start, end, allDay)
{
var dt = new Date(); // Create a new date from the current one
var hour = dt.getHours(); // Get and store only the hour from the current time
var start_date = moment(start).format('DD-MM-YYYY'); // Format the start and end dates
var end_date = moment(start).format('DD-MM-YYYY');
var start_date_time = moment(start).format('DD-MM-YYYY '+hour+':00'); // Format the start and end dates as well as setting the start time to the current time and the end in an hours time
var end_date_time = moment(start).format('DD-MM-YYYY '+(hour+1)+':00');
$('#start').val(start_date); // Place the formatted dates and times into the form ready for the user
$('#end').val(end_date);
$('#start_date_time').val(start_date_time);
$('#end_date_time').val(end_date_time);
$('#add_event_modal').foundation('reveal', 'open'); // Display the form
},
editable: true,
eventDrop: function(event, delta) {
console.log(event, delta);
$.ajax({
url: '<?php echo base_url("calendar/update_event_drop"); ?>',
data: {id: event.id, milliseconds: delta._milliseconds, days: delta._days, months: delta._months } , // Supplies the controller with the breakdown of the time for which the event should be adjusted
type: "POST",
success: function(json)
{
alert("Updated Successfully");
}
});
},
eventResize: function(event) // Changes the length of the event. The user then uses the eventDrop (moves) event to change the starting time.
{
var start = moment(event.start).format('YYYY-MM-DD HH:mm');
var end = moment(event.end).format('YYYY-MM-DD HH:mm');
$.ajax({
url: '<?php echo base_url("calendar/resize_event"); ?>',
data: { id: event.id, start: start, end: end },
type: "POST",
success: function(json)
{
alert("Updated Successfully");
}
});
},
eventClick: function(event) // When an event is selected display all the information for that event with the option to update or delete.
{
console.log(event);
$.ajax({
url: "<?php echo base_url('calendar/get_event_info'); ?>",
type: "POST",
data: { id: event.id }
}).done(function(resp) {
$('#event_info_modal').foundation('reveal', 'open', '<?php echo base_url("calendar/show_event_info"); ?>');
//
}).fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus + " - Please try again.")
})
}
});
function filter_this(filter)
{
var holidays = $('#holidays').is(':checked');
var events = $('#events').is(':checked');
var meetings = $('#meetings').is(':checked');
if(holidays == true)
{
var holidays_source = '<?php echo base_url("calendar/get_events"); ?>?holidays=' + holidays;
}
if(events == true)
{
var events_source = '<?php echo base_url("calendar/get_events"); ?>?&events='+ events;
}
if(meetings == true)
{
var meetings_source = '<?php echo base_url("calendar/get_events"); ?>?&meetings='+ meetings;
}
$('#calendar').fullCalendar('removeEvents');
$('#calendar').fullCalendar('addEventSource', holidays_source);
$('#calendar').fullCalendar('addEventSource', events_source);
$('#calendar').fullCalendar('addEventSource', meetings_source);
}
<input class="switch-input" id="holidays" type="checkbox" name="holidays" onclick="filter_this('filter');" checked>
<input class="switch-input" id="events" type="checkbox" name="events" onclick="filter_this('filter');" checked>
<input class="switch-input" id="meetings" type="checkbox" name="meetings" onclick="filter_this('filter');" checked>
回答1:
You need to update your filter_this
to something like:
function filter_this() {
var holidays, events, meetings;
if ($('#holidays').is(':checked') == true) {
holidays = { url: '<?= base_url("calendar/get_events"); ?>?holidays=1'};
}
if ($('#events').is(':checked') == true) {
events = { url: '<?= base_url("calendar/get_events"); ?>?&events=1'};
}
if ($('#meetings').is(':checked') == true) {
meetings = {url: '<?= base_url("calendar/get_events"); ?>?&meetings=1'};
}
$('#calendar').fullCalendar('removeEvents');
$('#calendar').fullCalendar('removeEventSources');
$('#calendar').fullCalendar('addEventSource', holidays);
$('#calendar').fullCalendar('addEventSource', events);
$('#calendar').fullCalendar('addEventSource', meetings);
}
And this works even if you change the views or the month / week / day being viewed.
That said, I think you might be overcomplicating things on filter_this
by adding three different sources. Since your URL is always the same, you could just pass custom parameters on the request. For instance, you could instanciate the calendar as such:
$('#calendar').fullCalendar({
events: {
url: '<?= base_url("calendar/get_events"); ?>',
data: {
meetings: "true",
holidays: "true",
events: "true"
}
},
And your filter_this
would be something like:
function filter_this() {
var eventSource = {
url: '<?= base_url("calendar/get_events"); ?>',
data: {
holidays: $('#holidays').is(':checked'),
events: $('#events').is(':checked'),
meetings: $('#meetings').is(':checked')
}
};
$('#calendar').fullCalendar('removeEvents');
$('#calendar').fullCalendar('removeEventSources');
$('#calendar').fullCalendar('addEventSource', eventSource);
}
And on the PHP side, you could just do something like
if ($_GET['holidays'] == "true") {
// fetch holiday events
}
if ($_GET['meetings'] == "true") {
// fetch meeting events
}
Note: This was tested with FullCalendar 3.0.1
来源:https://stackoverflow.com/questions/39748991/filter-events-by-adding-and-removing-multiple-event-sources