5

I am trying to show calendar view using fullcalender.io v4 in lightning component.

Initially the fullcalender loads without any issue but when I hover over the calender UI, I'm getting the below error:

[Illegal invocation] elementClosest()@https://sg1414-dev-ed.lightning.force.com/resource/1553009393000/FullCalendar/fullcalendar-3.10.0/fullCalendar/fullCalendar4.0.js:125:30 Proxy.realHandler()@https://sg1414-dev-ed.lightning.force.com/resource/1553009393000/FullCalendar/fullcalendar-3.10.0/fullCalendar/fullCalendar4.0.js:379:32

Here's the code:

<aura:component implements="force:appHostable" access="global">
    <aura:attribute name="recId" type="string" />
    <ltng:require scripts="{!join(',', 
                           $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/jquery.min.js', 
                           $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/jquery-ui.min.js',
                           $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/moment.js', 
                           $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/fullCalendar4.0.js',
                           $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/interaction.min.js',
                           $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/timegrid.min.js',
                           $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/daygrid.js' )}"
                  styles="{!join(',',
                             $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/fullCalendar.css',
                          $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/timegrid.css',
                            $Resource.FullCalendar + '/fullcalendarV4/fullCalendar/daygrid.css')}"

                  afterScriptsLoaded="{!c.scriptsLoaded}" />
    <div aura:id='calendar'></div>

</aura:component>    

Controller.js:

({
    scriptsLoaded : function(component, event, helper) {
        console.log('Script loaded succesfully')
        var calendar = new FullCalendar.Calendar(component.find("calendar").getElement(), {
            plugins: [ 'dayGrid'],
            events: data
        });
        calendar.render();
    },

})
2
  • According to the upgrade notes, you shouldn't need jquery or moment when using v4. Do you need them for some other reason? It might be worth cutting your example right back to the bare bones and seeing if that works.
    – Robs
    Apr 30, 2019 at 13:05
  • @gowtham - were you able to get this to work anyhow?
    – VarunC
    Jun 11, 2019 at 7:11

5 Answers 5

1

I know I'm a year late, but I think you're referencing the wrong scripts. FullCalendar works for me and I've imported the following four files from a zip file (static resource): loadScript(this, FullCalendarJS + '/FullCalendarJS/jquery.min.js'), loadScript(this, FullCalendarJS + '/FullCalendarJS/moment.min.js'), loadScript(this, FullCalendarJS + '/FullCalendarJS/fullcalendar.min.js'), loadStyle(this, FullCalendarJS + '/FullCalendarJS/fullcalendar.min.css') I'm using it in a lightning web component rather than a lightning (aura) component, but that shouldn't matter.

0

Have you tried to deep-copy your event array. When proxy error comes out - it tells that issue in lightning wrapped object in some kind of JS proxy that is readonly and prevents to assign new property

var copy = origin.map(function(a){ Object.assign({}, a) });

Or

const copy = origin.map(a => ({...a}));
1
  • Can you provide more information on how this would work? May 7, 2019 at 13:53
0

I'm not a JS expert but - take a look at main.js lines 104 -> 130.. (fullcalendar):

// Querying
// ----------------------------------------------------------------------------------------------------------------
// from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
var matchesMethod = Element.prototype.matches ||
    Element.prototype.matchesSelector ||
    Element.prototype.msMatchesSelector;
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);
}

The usages of the functions variable matchesMethod and closestMethod fails. Try to refacter them.

2
  • How does this answer the question?
    – Adrian Larson
    May 10, 2019 at 13:34
  • The two methods matchesMethod and closestMethod are refering to the element prototype implementation. The issue is shown when they get called with the wrong types.
    – Sigge
    May 13, 2019 at 6:30
0

Element.prototype is not supported (yet) in LWC. I had to tweak their main.js to by-pass these calls. Go in the file and search for "elementClosest()" and just use return element.closest(selector). This should fix your problem.

In addition you will notice that in their framework they are using "document." global which is also not allowed in LWC. You will have to eventually tweaks those too if you want the calendar to work in LWC.

I got mine working and loving it!!!...

:)

0

Lightning Web Component or Lightning Components in Salesforce does not support Element.Prototype.

So replacing the below line of code in the 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
  • This small code change actually resolved the issue for me using the latest version of FullCalendar as of now in a Lightning Web Component I've got in a Community. Interestingly, the problem never did occur using the Local Development Server or outside of the Community for me.
    – SF1Dev
    May 17, 2020 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.