3

I am trying to include full calendar to my lwc component. I am using 4 version of the calendar. It renders, but eventClick function does not fire. DateClick works as well, but eventClick nope. Firstly, I thought this problem occurred on lwc, then I did it using aura lightning and I have the same problem. Got some message like:

"TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.invokeGetter (:1:142)"

Here is LWC component .html :

<template>
    <div class="fullcalendar" lwc:dom="manual"></div>
</template>

LWC .js :

import { LightningElement } from 'lwc';
import { loadScript, loadStyle} from 'lightning/platformResourceLoader';
import FullCalendarJSs from '@salesforce/resourceUrl/FullCalendarik';

import XSpectr from '@salesforce/resourceUrl/Spectr';
import getCalendarEvents from '@salesforce/apex/CalendarHelper.getCalendarEvents';

export default class FullCalendarJs extends LightningElement {
connectedCallback() {
    Promise.all([
        loadStyle(this, FullCalendarJSs + '/core/main.css'),
        loadScript(this, FullCalendarJSs + '/core/main.js')
    ]).then(() => {
        Promise.all([
            loadStyle(this, FullCalendarJSs + '/daygrid/main.css'),
            loadScript(this, FullCalendarJSs + '/interaction/main.js'),
            loadScript(this, FullCalendarJSs + '/moment/main.js'),
            loadScript(this, FullCalendarJSs + '/daygrid/main.js'),
            loadStyle(this, FullCalendarJSs + '/timegrid/main.css'),
            loadScript(this, FullCalendarJSs + '/timegrid/main.js'),
            loadStyle(this, FullCalendarJSs + '/list/main.css'),
            loadScript(this, FullCalendarJSs + '/list/main.js'),

            loadStyle(this, XSpectr + '/spectre-0.5.8/dist/spectre.min.css')
        ]).then(() => {
            this.initialiseFullCalendar();
        }).catch(error => {
            // eslint-disable-next-line no-console
            console.error({
                message: 'Error on loading core js and css',
                error
            });
        });
    }).catch(error => {
        // eslint-disable-next-line no-console
        console.error({
            message: 'Error occured on FullCalendarJS',
            error
        });
    });
}

initialiseFullCalendar() {
    const ele = this.template.querySelector('div.fullcalendar');
    let calendarEvents = [];
    getCalendarEvents().then(cEvents => {
        JSON.parse(cEvents).forEach(task => {
            calendarEvents.push({
                'id' : task.id, 
                'start' : task.startDate,
                'end' : task.endDate,
                'title' : task.contact.Name + ', Subject : ' + task.subject
            });
        });
        // eslint-disable-next-line no-undef
        let calendar = new FullCalendar.Calendar(ele, {
            plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list', ],
            defaultView: 'dayGridMonth',
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
            },
            height : 650,
            editable: true,
            navLinks: true,
            weekNumbers: true,
            weekNumbersWithinDays: true,
            weekNumberCalculation: 'ISO',
            eventLimit: true,
            selectable: true,
            eventRender: function(info) {
                info.el.setAttribute('data-tooltip', info.event.title);
                info.el.classList.add('tooltip'); 
                function handler() {
                    alert( info.event.title );
                }

                info.el.addEventListener("click", handler);
            },
            dateClick: function(info) {
                // eslint-disable-next-line no-console
                console.log('dateClec : ', info);
            },
            eventClick: function(info) {
                // eslint-disable-next-line no-console
                console.log('eventClick : ', info);
            },
            events: calendarEvents
        });
        calendar.render();
    }).catch();
}
}

And i fixed two methods in core/main.js (it on 104 line):

var matchesMethod = function (el, selector) {
    var matches = document.querySelectorAll(selector);
    var th = this;
    return Array.prototype.some.call(matches, function(el) {
        return el === th;
    });
};
var closestMethod = function (selector) {
    // polyfill
    var el = this;
    if (!document.documentElement.contains(el)) {
        return null;
    }
    do {
        if (elementMatches(el, selector)) {
            return el;
        }
        el = el.parentElement || el.parentNode;
    } while (el !== null && el.nodeType === 1);
    return null;
};
function elementClosest(el, selector) {
    return closestMethod.call(el, selector);
}
function elementMatches(el, selector) {
    return matchesMethod.call(el, selector);
}

Apex Class to get data:

public with sharing class CalendarHelper {
    @AuraEnabled
    public static String getCalendarEvents(){
        Map<Id, Contact> idsToContacts = new Map<ID, Contact>([SELECT Id, Name FROM Contact]);
        List<CalendarEventWrapper> tasks = new List<CalendarEventWrapper>();
        for (Task task : [SELECT Id, WhoId, ActivityDate, Subject FROM Task]) {
            tasks.add(new CalendarEventWrapper( task.Id, 
                                                idsToContacts.get(task.WhoId),
                                                task.ActivityDate,
                                                task.Subject ));
        }
        for (Event event : [SELECT Id, WhoId, StartDateTime, EndDateTime, Subject FROM Event]) {
            tasks.add(new CalendarEventWrapper( event.Id, 
                                                idsToContacts.get(event.WhoId),
                                                event.StartDateTime,
                                                event.EndDateTime,
                                                event.Subject ));
        }
        return JSON.serialize(tasks);
    }

    public class CalendarEventWrapper {
        Id id;
        Contact contact;
        DateTime startDate;
        DateTime endDate;
        String subject;

        public CalendarEventWrapper(Id id, Contact contact, DateTime startDate, String subject) {
            this.id = id;
            this.contact = contact;
            this.startDate = startDate;
            this.subject = subject;
        }

        public CalendarEventWrapper(Id id, Contact contact, DateTime startDate, DateTime endDate, String subject) {
            this.id = id;
            this.contact = contact;
            this.startDate = startDate;
            this.endDate = endDate;
            this.subject = subject;
        }
    }
}
5
  • 1
    This is due to locker services in lightning preventing it .would you mind posting code from which one can reproduce the issue ? Dec 18, 2019 at 7:52
  • 1
    @MohithShrivastava posted code here. Dec 18, 2019 at 8:02
  • @programmer-228 I got stuck with the same problem which landed me on your question. I'm curious did you get it to work in the end and if so, could you post the fix?
    – POZ
    Jan 29, 2020 at 8:22
  • 1
    @POZ i've posted the answer below Jan 29, 2020 at 8:44
  • 1
    It works great, thanks for sharing that. It was real pain.
    – POZ
    Jan 29, 2020 at 9:04

2 Answers 2

5

Here is an answer: Fix methods in core/main.js

 var matchesMethod = Element.prototype.matches ||
    Element.prototype.matchesSelector ||
    Element.prototype.msMatchesSelector;
var closestMethod = Element.prototype.closest || function (selector) {
    var el = this;
    if (!document.documentElement.contains(el)) {
        return null;
    }
    do {
        if (elementMatches(el, selector)) {
            return el;
        }
        el = el.parentElement || el.parentNode;
    } while (el !== null && el.nodeType === 1);
    return null;
};
function elementClosest(el, selector) {
    if (!el.closest) {
        if (!document.documentElement.contains(el)) {
            return null;
        }
        do {
            if (elementMatches(el, selector)) {
                return el;
            }
            el = el.parentElement || el.parentNode;
        } while (el !== null && el.nodeType === 1);
        return null;
    }
    else
        return el.closest(selector);
}
function elementMatches(el, selector) {
    if (!el.matches)
        return el.msMatchesSelector(selector);
    else
        return el.matches(selector);
}
1
  • 1
    Kudos to you for fixing/amending the FullCalendar core library!
    – Robs
    Mar 18, 2020 at 21:43
-2

Try this, i did it and it's working:

var matchesMethod = function ( selector) {
    var matches = document.querySelectorAll(selector);
    var th = this;
    var aux2 = false;
    for (var i = 0; i < matches.length; i++) {
      if(aux2 == false)
          aux2 = matches[i] === th; 
    }
    return aux2;
};
var closestMethod = function (selector) {
    // polyfill
    var el = this;
    if (!document.documentElement.contains(el)) {
        return null;
    }
    do {
        if (elementMatches(el, selector)) {
            return el;
        }
        el = el.parentElement || el.parentNode;
    } while (el !== null && el.nodeType === 1);
    return null;
};
function elementClosest(el, selector) {
    return closestMethod.call(el, selector);
}
function elementMatches(el, selector) {
    return matchesMethod.call(el, selector);
}
1
  • This didn't fix the eventClick event not being fired.
    – POZ
    Jan 29, 2020 at 9:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .