FullCalendar select multiple events in single filt

2019-09-12 03:53发布

问题:

I am using FullCalendar 3.1.0 plugin to show events. I was able to implement multiple events with a dropdown. But user is only able to select 1 option from a single dropdown filter. My goal is to give the opportunity to select multiple options in a each dropdown filter. I am using dropdown. But when I hold down CTR and click on options, it only shows events for the first option in the list. Any help would be greatly appreciated.

Here is the HTML:

<!-- Main view: Title and calendar -->
<div class="container">
    <div class="row">
        <div class="col-xs-12">
            <h1 id="cal_title">Change Calendar</h1>
            <div class="search_bar">
                <ul id="menu">
                    Search By:
                    <li>
                        <select id="status_selector" multiple>
                            <option value="all" selected="selected">Status Types - All</option>
                        </select>
                    </li>
                    <li>
                        <select id="group_selector" multiple>
                            <option value="all" selected="selected">Group - All</option>
                        </select>
                    </li>
                    <li>
                        <select id="changeType_selector" multiple>
                            <option value="all" selected="selected">Type of Change - All</option>
                            <option value="6250">Emergency Change</option>
                            <option value="6882">Expedited Change</option>
                            <option value="6249">Normal Change</option>
                            <option value="9999">Standard Change</option>
                        </select>
                    </li>
                    <li>
                        <select id="downtime_selector" multiple>
                            <option value="all" selected="selected">Downtime - All</option>
                            <option value="Yes">Yes</option>
                            <option value="No">No</option>
                        </select>
                    </li>
                </ul>
            </div>
            <div id="calendar"></div>
            <div id="footer">To ensure optimal performance, only changes created in the past 90 days are shown. For changes older than 90 days please reference EasyVista. <br />If an issue has been found and/or you have a recommendation, please open a ticket for Service Request/Applications/EasyVista - Other Request, explaining the issue or recommendation.</div>
            <div id="version">SACC v2.0</div>
        </div>
    </div>
</div>

Here is my Javascript:

$(document).ready(function() {

        /* Find all the distinct STATUS_EN and place them into a dropdown list */
// This creates first 2 dropdown dynamically
        $.getJSON('json/events.json',function(json){
            var usedStatus = []; // Array to keep track of all STATUS_EN that have been seen
            var usedGroup = []; // Array to keep track of all group_selector that have been seen

            // For each object, store the status/group in predefined variables
            $.each(json, function(i,v){
                // If STATUS_EN has not been seen
                if (usedStatus.indexOf(v.STATUS_EN) == -1){ 
                    usedStatus.push(v.STATUS_EN); // Add STATUS_EN to usedStatus
                }
                // If responsible_group has not been seen
                if (usedGroup.indexOf(v.responsible_group) == -1){ 
                    usedGroup.push(v.responsible_group); // Add responsible_group to usedStatus
                }
            });

            // Sort both array variables in alphabetical order.
            usedStatus.sort();
            usedGroup.sort();

            // Create the dropdown
            usedStatus.forEach(function(value){
                if (value != undefined){ // If STATUS_EN is not undefined
                    $("#status_selector").append('<option value="'+value+'">'+value+'</option>'); // Create an option for the dropdown list
                }
            });
            usedGroup.forEach(function(value){
                if (value != undefined){ // If responsible_group is not undefined
                    $("#group_selector").append('<option value="'+value+'">'+value+'</option>'); // Create an option for the dropdown list
                }
            });

        });

        /* If end_date is null, return start_date */
        function isNull(end_date,start_date){
            if(end_date !== null){
                return end_date;
            } else {
                return start_date;
            }
        }

        /* Calendar structure */
        $('#calendar').fullCalendar({
            /* Theme enabler */
            theme: false,

            /* Header description */
            header: {
                left: 'prev,today,next',
                center: 'title',
                right: 'month,basicWeek,basicDay'
            },

            /* Set the default view to Day */
            defaultView: 'basicWeek',

            /* Arrow stype (Used when theme is enabled) */
            themeButtonIcons: {
                prev: 'circle-triangle-w',
                next: 'circle-triangle-e'
            },

            /* Text to show in the button */
            buttonText: {
                today: 'Today',
                month: 'Month',
                week: 'Week',
                day: 'Day',
                list: 'Week List'
            },
            navLinks: true, // Can click day/week names to navigate views
            editable: false, // Remove permission to move events
            eventLimit: true, // Allow "more" link when too many events
            businessHours: true, // grayout afterhours
            multiple: true,

            /* Function that allows user to click on event. */
            eventClick: function (event, jsEvent, view) {
                //set the values and open the modal

                $('#modalTitle').html(event.title);
                $('#modalBody').html(event.text);
                $('#eventUrl').attr('href', event.url);
                $('#eventStatus').html("Status: " + event.STATUS_EN);
                $('#fullCalModal').modal('show');

                return false; // prevent from going to EasyVista right away
            },

            /* Function that shows description when hovering over event */
            eventMouseover: function (data, event, view) {
                tooltip = '<div class="tooltiptopicevent">'
                    + '<strong>Request Number:</strong> ' + data.RFC_NUMBER
                    + '<br /><strong>Status:</strong> ' + data.STATUS_EN 
                    + '<br /><strong>Start Date:</strong> ' + moment(data.start).format("MM/D, h:mm:ss a")
                    + '<br /><strong>End Date:</strong> ' + moment(isNull(data.end,data.start)).format("MM/D, h:mm:ss a")
                    + '<br /><strong>Description:</strong> ' + data.text + '</div>';
                $("body").append(tooltip);

                $(this).mousemove(function(event){
                    $(".tooltiptopicevent").position({
                        my: "left+3 bottom-3",
                        of: event,
                        collision: "flipfit"
                    });
                });
            },

            /* Hide description when mouse moves out */
            eventMouseout: function (data, event, view) {
                $(this).css('z-index', 8);
                $('.tooltiptopicevent').remove();
            },

            /* Feed in events from JSON file through PHP */
            events: {
                url: 'php/get-events.php'
            },


            /* Render the events */
            eventRender: function eventRender(event, element, view){
                return['all',event.STATUS_EN].indexOf($('#status_selector option:selected').val()) >= 0 
                    && ['all',event.responsible_group].indexOf($('#group_selector option:selected').val()) >= 0
                    && ['all',event.change_type].indexOf($('#changeType_selector option:selected').val()) >= 0
                    && ['all',event.downtime].indexOf($('#downtime_selector option:selected').val()) >= 0
            },

            /* Show status loading when loading */
            loading: function(bool) {
                $('#loading').toggle(bool);
            }
        });

        /* Call on fullCalendar after selection of dropdown option 
        $('#status_selector, #group_selector, #changeType_selector, #downtime_selector').change(function() {
            $('#calendar').fullCalendar('rerenderEvents');
            //$('#calendar').fullCalendar('refetchEvents'); // this allows the spinner to come up each time filter is changed.
        });*/
        /**/
        $('#status_selector, #group_selector, #changeType_selector, #downtime_selector').on('change',function(){
            $('#calendar').fullCalendar('rerenderEvents');
        });


    });

Sample of how my .json file looks like:

[
{
    "start":  "2016-12-2T17:0:00",
    "end":  "2016-12-2T17:0:00",
    "title":  "12/2/2016 5:00 PM - group1",
    "url":  "https://sample.com",
    "text":  "some needed text",
    "description":  "description of event",
    "REQUEST_ID":  462820,
    "STATUS_EN":  "Open",
    "downtime":  "No",
    "change_type":  "9999",
    "responsible_group":  "group1",
    "RFC_NUMBER":  "C201612_09454"
},
{
    "start":  "2017-2-1T21:0:00",
    "end":  "2017-2-1T21:0:00",
    "title":  "2/1/2017 9:00 PM - group2",
    "url":  "https://samplesite.com",
    "text":  "some text",
    "description":  "description of event",
    "REQUEST_ID":  521157,
    "STATUS_EN":  "Closed",
    "downtime":  "No",
    "change_type":  "6250",
    "responsible_group":  "group2",
    "RFC_NUMBER":  "C201702_00976"
}
]

回答1:

Doing .val() on a group of selected elements (e.g. your $('#status_selector option:selected').val()) will only return the value from the first matched element - as per the very first line of the docs: http://api.jquery.com/val/

So you need to loop through and check the values of all the selected options, and test for them individually. Something like this (untested):

          eventRender: function eventRender(event, element, view){
            var statusMatch = false;
            var statusArr = ['all',event.STATUS_EN];

            $('#status_selector option:selected').each(function(index, el)
            {
                if (statusArr.indexOf($(this).val()) > = 0) statusMatch = true;
            });

            var groupMatch = false;
            var groupArr = ['all',event.responsible_group];

            $('#group_selector option:selected').each(function(index, el)
            {
                if (groupArr.indexOf($(this).val()) > = 0) groupMatch = true;
            });

            var changeMatch = false;
            var changeArr = ['all',event.change_type];

            $('#changeType_selector option:selected').each(function(index, el)
            {
                if (changeArr.indexOf($(this).val()) > = 0) changeMatch = true;
            });

            var downtimeMatch = false;
            var downtimeArr = ['all',event.downtime];

            $('#downtime_selector option:selected').each(function(index, el)
            {
                if (downtimeArr.indexOf($(this).val()) > = 0) downtimeMatch = true;
            });

            return (statusMatch && groupMatch && changeMatch && downtimeMatch);
        }