Drewy
Drewy

Reputation: 61

FullCalendar Event Popover Button Click Not Working

I am using FullCalendar to show events. When an event is clicked a popover is shown with information of the event and a button to open a page to view more details. I have the popover setup with the details and the button works but the id from the fullcalendar event number needed is always the last one on the calendar and not the one from the clicked event.

I need to click the event, open the popover and then click the view button to open the new page with the id from the event clicked.

$('.fullcalendar-event').fullCalendar({
    header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay'
    },
    defaultDate: today,
    editable: false,
    eventOverlap: false,
    displayEventTime: false,
    eventSources: {
        type: "POST",
        url: 'php_files/calender_php_files/populate_calender.php',
        data: {
            client_id: sessionStorage.getItem('client_id'),
            access_id: sessionStorage.getItem('access_id')
        }
    },
    eventRender: function (event, element) {
        var event_popover = element.popover({
            title: function () {
                return "<B>" + event.event_title + "</B>";
            },
            placement: 'auto',
            html: true,
            trigger: 'click',
            animation: 'false',
            content: function () {
                if (event.event_type === 'embargo') {
                    return "<div>" +
                        "<b>Site: </b>" + event.event_site +
                        "<br />" +
                        "<b>Start: </b>" + moment(event.event_start_date).format('DD/MM/YYYY') + ", " +
                        moment(event.event_start_time, 'HHmmss').format('HH:mm') +
                        "<br />" +
                        "<b>End: </b>" + moment(event.event_end_date).format('DD/MM/YYYY') + ", " +
                        moment(event.event_end_time, 'HHmmss').format('HH:mm') +
                        "<br />" +
                        "<br />" +
                        "<button id='view' class='btn btn-primary btn-xs view'>View</button>" +
                        "</div>"
                } else if (event.event_type === 'permit') {
                    return "<div>" +
                        "<b>Site: </b>" + event.event_site +
                        "<br />" +
                        "<b>Start: </b>" + moment(event.event_start_date).format('DD/MM/YYYY') + ", " +
                        moment(event.event_start_time, 'HHmmss').format('HH:mm') +
                        "<br />" +
                        "<b>End: </b>" + moment(event.event_end_date).format('DD/MM/YYYY') + ", " +
                        moment(event.event_end_time, 'HHmmss').format('HH:mm') +
                        "<br />" +
                        "<br />" +
                        "<button class='btn btn-primary btn-xs view'>View</button>" +
                        "<button style='margin-left: 8px;' class='btn btn-warning btn-xs clear'>Clear</button>" +
                        "<button style='margin-left: 8px;' class='btn btn-danger btn-xs cancel'>Cancel</button>" +
                        "</div>"
                }
            },
            container: 'body'
        }).popover('show');
        $('body').on('click', function (e) {
            if (!element.is(e.target) && element.has(e.target).length === 0 && $('.popover').has(e.target).length === 0)
                element.popover('hide');
        });
        $(document).on("click", ".view", function() {
            window.location.replace('edit_site_embargo.php?embargo_id=' + event.event_number)
        })
    }
});

Upvotes: 0

Views: 1665

Answers (1)

ADyson
ADyson

Reputation: 61904

Your block $(document).on("click", ".view", function() {, is executed once for each calendar event. So if you have 20 calendar events, you get 20 "click" event handlers on the "view" class. However, what this structure means is that all your "view" buttons will trigger all the 20 click handlers, since they were all bound to the same thing. Therefore when you click one of the buttons, the window.location.replace command is running 20 times, but doing it so fast that in effect only the last copy of the command appears to execute, and that will be the copy which refers to the last calendar event. This explains the behaviour you're currently seeing.

What you need to do is:

1) move the click event handler code outside the eventRender function, so that it only runs once, and creates one handler. This is fine because you've used delegated event handling, and so it'll still bind to all the buttons which get created.

2) define a data-attribute on the button which you can retrieve at the point where the button is clicked, which contains the event ID to use.

So, move this block outside your calendar setup code entirely, and re-define it slightly:

    $(document).on("click", ".view", function() {
        window.location.replace('edit_site_embargo.php?embargo_id=' + $(this).data("event-number")); //get the event number from the button's data-attribute
    })

And also change your popover creation code so that it defines your "view" button with an extra attribute containing the event number:

"<button class='btn btn-primary btn-xs view' data-event-number='" + event.event_number + "'>View</button>" +

(By the way, I suggest you remove "id="view" from the "embargo" version of the button, because this could create multiple elements with the same ID, which is not valid HTML.)

Upvotes: 0

Related Questions