'How do I bring FullCalendar(v5) into Ember.js(v4) to render within a component?
I'm trying to integrate FullCalendar (v5) with an Ember.JS (4.2) app, and am able to get things to work if I just import the library via CDN and inline / hard code it -- however if I attempt to break it out into a component, I get an empty page.
Inline Works
I'm able to render the calendar and an example event if I import FullCalendar via CDN links, and bind it an html element with the id of "calendar" on page load, as follows:
<!-- Filename: index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Client</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{{content-for "head"}}
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css" />
<!-- TODO: Replace with npm/yarn package initiated within app config -->
<link
href="https://cdn.jsdelivr.net/npm/[email protected]/main.min.css"
rel="stylesheet"
/>
{{content-for "head-footer"}}
</head>
<body>
<!-- TODO: Move into component -->
<div id="calendar"></div>
{{content-for "body"}}
<!-- TODO: Remove once replacing import via npm/yarn package -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/main.min.js"></script>
<!-- TODO: Move into component -->
<script>
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
events: [
{
title: 'Kayak Tour',
start: '2022-03-09T14:30:00',
end: '2022-03-09T19:30:00',
},
],
});
calendar.render();
});
</script>
{{content-for "body-footer"}}
</body>
</html>
But How to Refactor into Component?
However, which I can't seem to understand a solution via Ember docs, is that if I try and setup the calendar within a component (see TODO's above), I only get a blank page and can't get the calendar to display.
For example, if I move the <div id="calendar"></div> into a component: event-calendar.hbs:
<!-- Filename: components/event-calendar.hbs -->
<div id="calendar"></div>
But I'm not sure in its associated data file, how I am to bind to the div as I did in the index example above? E,g:
// Filname: components/event-calendar.js
import Component from '@glimmer/component';
export default class EventCalendarComponent extends Component {
// how do I bind to `#calendar` like I did in the index file above?
}
I've even tried keeping the JS in index.html, and moving the div into my component, which doesn't seem to render.
Ideally, in my primary view, I want to inject my calendar as a component as follows (and later pass in an events object):
<!-- Filename: templates/index.hbs -->
{{page-title 'Home'}}
<div>
<EventCalendar />
</div>
{{outlet}}
I suspect that the <div id="calendar"></div> does not exist in the DOM yet? Does anyone have any suggestions how I might get this basic example to work?
Solution 1:[1]
I don't think you'd want a component -- maybe a modifier -- because this is a behavior to add to an element specifically?
For example, using: https://github.com/ember-modifier/ember-modifier and these docs: https://fullcalendar.io/docs/initialize-es6
// app/modifiers/calendar.js
import { modifier } from 'ember-modifier';
import { Calendar } from '@fullcalendar/core';
export default modifier((element, [overrideOptions]) => {
let calendar = new Calendar(element, {
initialView: 'dayGridMonth',
...overrideOptions,
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay',
...(overrideOptions.headerToolbar || {})
},
events: overrideOptions.events
? overrideOptions.events
: [{
title: 'Kayak Tour',
start: '2022-03-09T14:30:00',
end: '2022-03-09T19:30:00',
}],
});
calendar.render();
return () => {
// if the calendar has a teardown function, you'd want to call that here
}
}
and then anywhere in your app you can do:
<div {{calendar}}></div>
or
{{!-- defining assumed to exist on whichever 'this' is--}}
<div {{calendar this.calendarOptions}}></div>
Be sure to install ember-modifier and @fullcalendar/core and restart your dev server
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | NullVoxPopuli |

