问题
I've set up multiple select filters for my Fullcalendar project. I can filter by several event values in my JSON, but I can't get it to filter by className
.
Can someone tell me what I'm doing wrong?
Here is the code I'm using and here is a jsfiddle that replicates the issue.
<select id="type_selector">
<option value="all">All types</option>
<option value="university">University</option>
<option value="polytech">Polytech</option>
<option value="highschool">High School</option>
</select>
<select id="state_selector">
<option value="all">All types</option>
<option value="CA">California</option>
<option value="MI">Michigan</option>
<option value="VT">Vermont</option>
</select>
<select id="color_selector">
<option value="all">All colors</option>
<option value="red">Red schools</option>
<option value="orange">Orange schools</option>
<option value="green">Green schools</option>
</select>
<div>
<div id='calendar'></div>
</div>
<script>
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
defaultView: 'agendaWeek',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: true,
selectHelper: true,
year: 2016,
month: 08,
date: 25,
slotMinutes: 15,
editable: true,
events: [{
title: 'Michigan University',
start: '2016-09-26',
type: 'university',
state: 'MI',
className: 'red'
}, {
title: 'California Polytechnic',
start: '2016-09-27',
type: 'polytech',
state: 'CA',
className: 'orange'
}, {
title: 'Vermont University',
start: '2016-09-28',
type: 'university',
state: 'VT',
className: 'red'
}, {
title: 'Michigan High School',
start: '2016-09-29',
type: 'highschool',
state: 'MI',
className: 'green'
}, {
title: 'Vermont High School',
start: '2016-09-30',
type: 'highschool',
state: 'VT',
className: 'green'
}, {
title: 'California High School',
start: '2016-09-30',
type: 'highschool',
state: 'CA',
className: 'green'
}],
eventRender: function eventRender(event, element, view) {
return ['all', event.type].indexOf($('#type_selector').val()) >= 0
&& ['all', event.state].indexOf($('#state_selector').val()) >= 0
&& ['all', event.className].indexOf($('#color_selector').val()) >= 0
}
});
$('#type_selector').on('change', function() {
$('#calendar').fullCalendar('rerenderEvents');
})
$('#state_selector').on('change', function() {
$('#calendar').fullCalendar('rerenderEvents');
})
$('#color_selector').on('change', function() {
$('#calendar').fullCalendar('rerenderEvents');
})
});
</script>
回答1:
Your issue is the name "className". className is a DOM property so, when you try to access event.className
you're not actually accessing the event's property (the red, orange, etc) but the DOM property, which is returning something like ['red']
.
If you change the className to any other (non-reserved, non-property), that should be fixed (check updated jsfiddle).
Of course, this means the background color of each event now goes back to the default blue. You can fix this by setting the properties backgroundColor
and borderColor
(check the Event Object documentation), as such:
events: [{
title: 'Michigan University',
start: '2016-09-26',
type: 'university',
state: 'MI',
cName: 'red',
backgroundColor: 'red',
borderColor: 'red'
}]
You can simplify all this and simply replace className
for backgroundColor
since this property returns a string with the background color name (which matches your select options).
So you would end up with something like this (fiddle):
<select id="type_selector">
<option value="all">All types</option>
<option value="university">University</option>
<option value="polytech">Polytech</option>
<option value="highschool">High School</option>
</select>
<select id="state_selector">
<option value="all">All types</option>
<option value="CA">California</option>
<option value="MI">Michigan</option>
<option value="VT">Vermont</option>
</select>
<select id="color_selector">
<option value="all">All colors</option>
<option value="red">Red schools</option>
<option value="orange">Orange schools</option>
<option value="green">Green schools</option>
</select>
<div>
<div id='calendar'></div>
</div>
<script>
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
defaultView: 'agendaWeek',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: true,
selectHelper: true,
year: 2016,
month: 8,
date: 25,
slotMinutes: 15,
editable: true,
events: [{
title: 'Michigan University',
start: '2016-09-26',
type: 'university',
state: 'MI',
backgroundColor: 'red',
borderColor: 'red'
}, {
title: 'California Polytechnic',
start: '2016-09-27',
type: 'polytech',
state: 'CA',
backgroundColor: 'orange',
borderColor: 'orange'
}, {
title: 'Vermont University',
start: '2016-09-28',
type: 'university',
state: 'VT',
backgroundColor: 'red',
borderColor: 'red'
}, {
title: 'Michigan High School',
start: '2016-09-29',
type: 'highschool',
state: 'MI',
backgroundColor: 'green',
borderColor: 'green'
}, {
title: 'Vermont High School',
start: '2016-09-30',
type: 'highschool',
state: 'VT',
backgroundColor: 'green',
borderColor: 'green'
}, {
title: 'California High School',
start: '2016-09-30',
type: 'highschool',
state: 'CA',
backgroundColor: 'green',
borderColor: 'green'
}],
eventRender: function eventRender(event, element, view) {
return ['all', event.type].indexOf($('#type_selector').val()) >= 0
&& ['all', event.state].indexOf($('#state_selector').val()) >= 0
&& ['all', event.backgroundColor].indexOf($('#color_selector').val()) >= 0;
}
});
$('#type_selector').on('change', function () {
$('#calendar').fullCalendar('rerenderEvents');
});
$('#state_selector').on('change', function () {
$('#calendar').fullCalendar('rerenderEvents');
});
$('#color_selector').on('change', function () {
$('#calendar').fullCalendar('rerenderEvents');
});
</script>
There is another way, without changing the code too much, but you'll need to be careful with this. Since event.className
is returning an array with the name of the class, you could just change
eventRender: function eventRender(event, element, view) {
return ['all', event.type].indexOf($('#type_selector').val()) >= 0
&& ['all', event.state].indexOf($('#state_selector').val()) >= 0
&& ['all', event.className].indexOf($('#color_selector').val()) >= 0
}
To
eventRender: function eventRender(event, element, view) {
return ['all', event.type].indexOf($('#type_selector').val()) >= 0
&& ['all', event.state].indexOf($('#state_selector').val()) >= 0
&& ['all', event.className[0]].indexOf($('#color_selector').val()) >= 0
}
Note the [0]
in front of event.className
. This way, you'll compare the option value with the first class name.
You'll need to be careful, because if you have more than one class, the first element might not be the value of the select options.
Check this jsfiddle
来源:https://stackoverflow.com/questions/39769761/fullcalendar-filter-by-classname