FullCalendar Web Component (Vaadin 10)
FullCalendar integration
FullCalendar integration
This addon is an integration of the FullCalendar (v3.10.0) as Flow component for Vaadin Platform / Vaadin 10-13 (and 14 in Bower compatibility mode).
This version is not maintained any more. I recommend you to use the latest version for Vaadin 14+. It can be found here: https://vaadin.com/directory/component/full-calendar-flow
For information about the FullCalendar (functionality, features, license information, etc.) visit https://fullcalendar.io/
If you want to use the Scheduler, please have a look here: https://vaadin.com/directory/component/full-calendar-scheduler-extension-vaadin10
Addon Functionality
The following functions are implemented and available to use from server side:
adding / updating / removing calendar items,
switching between shown intervals (next month, previous month, etc.),
goto a specific date or today,
switch the calendar view (month, basic views for days and weeks, agenda views for days and weeks, list views for day to year),
setting a locale to be used for displaying week days, formatting values, calculating the first day of the week, etc. (supported locales are provided as constant list)
setting the first day of week to be shown (overrides the locale setting),
setting the height of the calendar instance (calculated by parent, aspect ratio or fixed pixel size)
show of week numbers
limit max shown entries per day (except basic views)
showing now indicator
activating day / week numbers / names to be links
styles are overridable via custom properties
setting a eventRender JS function from server side
setting business hours (multiple instances possible)
timezone support
Event handling for
- clicking an empty time spot in the calendar,
- selecting a block of empty time spots in the calendar,
- clicking an entry,
- moving an entry via drag and drop (event is fired on drop + changed time),
- resizing an entry (event is fired after resize + changed time),
- view rendered (i. e. to update a label of the shown interval)
- clicking on limited entries link "+ X more"
- clicking on a day's or week's number link (when activated)
Model supports setting
- title,
- start / end / all day flag,
- color (html colors, like "#f00" or "red"),
- description (not shown via FC),
- editable / read only
- rendering mode (normal, background, inversed background)
Timezones
Starting with 1.6.0 FC supports setting timezones. From this version, entries and some events work with Instant to represent the time based on UTC. You may set a custom timezone to display events for a user's timezone while the entries themselves still work with UTC based times.
Feedback and co.
If there are bugs or you need more features (and I'm not fast enough) feel free to contribute on GitHub. :) I'm also happy for feedback or suggestions about improvements.
Sample code
// Create a new calendar instance and attach it to our layout FullCalendar calendar = FullCalendarBuilder.create().build(); container.add(calendar); container.setFlexGrow(1, calendar); // Create a initial sample entry Entry entry = new Entry(); entry.setTitle("Some event"); entry.setStart(LocalDate.now().withDayOfMonth(3).atTime(10, 0)); entry.setEnd(entry.getStart().plusHours(2)); entry.setColor("#ff3333"); calendar.add(entry);
/* * The day click event listener is called when a user clicks in an empty space inside of the * calendar. Depending of if the clicked point was a day or time slot the event will provide the * time details of the clicked point. With this info you can show a dialog to create a new entry. */ calendar.addDayClickListener(event -> { Optional<LocalDateTime> optionalDateTime = event.getClickedDateTime(); Optional<LocalDate> optionalDate = event.getClickedDate(); Entry entry = new Entry(); if (optionalDateTime.isPresent()) { // check if user clicked a time slot LocalDateTime time = optionalDateTime.get(); entry.setStart(time); entry.setEnd(time.plusHours(FullCalendar.DEFAULT_TIMED_EVENT_DURATION)); entry.setAllDay(false); } else if (optionalDate.isPresent()) { // check if user clicked a day slot LocalDateTime date = optionalDate.get().atStartOfDay(); entry.setStart(date); entry.setEnd(date.plusDays(FullCalendar.DEFAULT_DAY_EVENT_DURATION)); entry.setAllDay(true); } new EntryDialog(calendar, entry, true).open(); }); /* * The entry click event listener is called when the user clicks on an existing entry. * The event provides the clicked event which might be then opened in a dialog. */ calendar.addEntryClickListener(event -> new DemoDialog(calendar, event.getEntry(), false).open());
// ... create a form and binder to provide editable components to the user HorizontalLayout buttons = new HorizontalLayout(); Button buttonSave; if (newInstance) { buttonSave = new Button("Create", e -> { if (binder.validate().isOk()) { // add the entry to the calendar instance calendar.addEntry(entry); } }); } else { buttonSave = new Button("Save", e -> { if (binder.validate().isOk()) { // update an existing entry in the client side calendar.updateEntry(entry); } }); } buttons.add(buttonSave); if (!newInstance) { Button buttonRemove = new Button("Remove", e -> calendar.removeEntry(entry)); buttons.add(buttonRemove); }
private void init() { // The element that should show the current interval. HasText intervalLabel = new Span(); // combo box to select a view for the calendar, like "monthly", "weekly", ... ComboBox<CalendarView> viewBox = new ComboBox<>("", CalendarViewImpl.values()); viewBox.addValueChangeListener(e -> { CalendarView value = e.getValue(); calendar.changeView(value == null ? CalendarViewImpl.MONTH : value); }); viewBox.setValue(CalendarViewImpl.MONTH); /* * The view rendered listener is called when the view has been rendererd on client side * and FC is aware of the current shown interval. Might be accessible more directly in * future. */ calendar.addViewRenderedListener(event -> LocalDate intervalStart = event.getIntervalStart(); CalendarView cView = viewBox.getValue(); String formattedInterval = ... // format the intervalStart based on cView intervalLabel.setText(formattedInterval); }); }
// #1 setting a fixed height calendar.setHeight(500); // #2 setting a auto height - this is calculated by the w-h-ratio of the calendar calendar.setHeightAuto(); // #3 calculate height by parent. parent is a block container. calendar.setHeightByParent(); calendar.setSizeFull(); // #4 calculate height by parent + usage of css calc(). parent is a block container. calendar.setHeightByParent(); calendar.getElement().getStyle().set("height", "calc(100vh - 450px)"); // #5 calculate height by parent. parent is a flex container. calendar.setHeightByParent(); calendar.getElement().getStyle().set("flex-grow", "1");
1. Copy the styles.html from the github demo or create your own custom style file and place it in your applications webapp/frontend folder (e. g. webapp/frontend/styles/styles /my-custom-full-calendar-styles.html) The github demo file can be obtained from here: https://github.com/stefanuebe/vaadin_fullcalendar/blob/master /demo/src/main/webapp/frontend/styles.html 2. Modify the styles as needed. <custom-style> <style> html{ /* light blue to be used instead of default light yellow*/ --fc-unthemed_tdfc-today-background: #81DAF5 !important; /* and some fancy border */ --fc_td-border-style: dotted !important; --fc_td-border-width: 2px !important; } </style> </custom-style> 3. Use the styles file in your application. @HtmlImport("frontend://styles/my-custom-full-calendar-styles.html") public class FullCalendarApplication extends Div { // ... }
// The given string will be interpreted as js function on client side // and attached as eventRender callback. // Make sure, that it does not contain any harmful code. calendar.setEntryRenderCallback("" + "function(event, element) {" + " console.log(event.title + 'X');" + " element.css('color', 'red');" + " return element; " + "}");
1. Create a new polymer template (e.g. webapp/frontend/my-full-calendar.html): <link rel="import" href="bower_components/fullcalendar/full-calendar.html"> <dom-module id="my-full-calendar"> <script> class MyFullCalendar extends FullCalendar { static get is() { return 'my-full-calendar'; } _createInitOptions() { var options = super._createInitOptions(); options.eventRender = function (event, element) { element.css('color', 'red'); return element; }; return options; } } customElements.define(MyFullCalendar.is, MyFullCalendar); </script> </dom-module> 2. Create a subclass of FullCalendar import com.vaadin.flow.component.Tag; import com.vaadin.flow.component.dependency.HtmlImport; import org.vaadin.stefan.fullcalendar.FullCalendar; @Tag("my-full-calendar") @HtmlImport("frontend://my-full-calendar.html") public class MyFullCalendar extends FullCalendar { MyFullCalendar(int entryLimit) { super(entryLimit); } } 3. Use this class in your code calendar = new MyFullCalendar(5);
Entry entry = new Entry(); // ... setup entry details entry.setRenderingMode(Entry.RenderingMode.BACKGROUND); calendar.addEntry(entry);
// Single instance for "normal" business week (mo-fr) calendar.setBusinessHours(new BusinessHours(LocalTime.of(9, 0), LocalTime.of(17, 0),BusinessHours.DEFAULT_BUSINESS_WEEK)); // Multiple instances calendar.setBusinessHours( new BusinessHours(LocalTime.of(9, 0), LocalTime.of(17, 0),BusinessHours.DEFAULT_BUSINESS_WEEK), new BusinessHours(LocalTime.of(12, 0), LocalTime.of(15, 0), DayOfWeek.SATURDAY) ); // Single instance for "each day from 9am to midnight" calendar.setBusinessHours(new BusinessHours(LocalTime.of(9, 0)));
// Per default, our FC works with UTC. You can set a custom timezone to be shown for the user. // This will automatically update all entries on the client side. Timezone tzBerlinGermany = new Timezone("Europe/Berlin"); calendar.setTimezone(tzBerlinGermany); // We can also reset the timezone to default. calendar.setTimezone(Timezone.UTC); // We can also read the browsers timezone, after the component has been attached to the client side. // There are other ways to obtain the browser's timezone, so you are not obliged to use the listener. calendar.addBrowserTimezoneObtainedListener(event -> calendar.setTimezone(event.getTimezone())); // When using timezones, entries can calculate their start and end in different ways. entry.setStart(Instant.now()); // UTC entry.setStart(LocalDateTime.now(), tzBerlinGermany); // timezone is used to calculate the UTC value entry.setCalendar(calendar); // is done automatically, when using calendar.addEntry(entry); entry.setStart(LocalDateTime.now()); // Uses the calendars timezone (or UTC as fallback) // Timezone provides some convenient methods to work with the two different temporal types tzBerlinGermany.convertToUTC(LocalDateTime.of(2018, 10, 1, 10, 0, 0)) // Standard time, returns Instant for 9:00 UTC this day. tzBerlinGermany.convertToUTC(LocalDateTime.of(2018, 8, 1, 10, 0, 0)) // Summer time, returns Instant for 8:00 UTC this day. tzBerlinGermany.convertToLocalDateTime(Instant.now()) // returns a date time with +1/+2 hours (depending on summer time).
Create a custom component, that extends FullCalendar or FullCalendarScheduler. Add a style element and your custom css stylings. Override the static template method and let it insert your template with the style node into the parents template DOM. The following example sets a beautiful green background for empty lists (.fc-list-empty). Please note, that the id of your component inside of the template method needs to be updated to your component's id. <link rel="import" href="bower_components/fullcalendar/full-calendar-scheduler.html"> <dom-module id="my-full-calendar"> <template> <style id="styles"> .fc-list-empty { background-color: green !important; } </style> </template> <script> class MyFullCalendar extends FullCalendarScheduler { static get is() { return 'my-full-calendar'; } // example of adding / overriding styles static get template() { const parentTemplate = FullCalendarScheduler.template.cloneNode(true); const childTemplate = Polymer.DomModule.import('my-full-calendar', 'template'); parentTemplate.content.insertBefore(childTemplate.content, parentTemplate.content.firstChild); return parentTemplate; } } customElements.define(MyFullCalendar.is, MyFullCalendar); </script> </dom-module>
Links
Compatibility
Was this helpful? Need more help?
Leave a comment or a question below. You can also join
the chat on Discord or
ask questions on StackOverflow.
Version
- Business hours now maps DayOfWeek.SUNDAY to 0
- Released
- 2019-07-22
- Maturity
- STABLE
- License
- MIT License
Compatibility
- Framework
- Vaadin 10
- Vaadin 10+
- Vaadin 11
- Vaadin 11+
- Vaadin 12
- Vaadin 13
- Vaadin 12+ in 1.8.0
- Browser
- Firefox
- Opera
- Safari
- Google Chrome
- iOS Browser
- Android Browser
- Windows Phone
- Microsoft Edge
FullCalendar Web Component (Vaadin 10) - Vaadin Add-on Directory
FullCalendar integrationIssue tracker
Source Code
FullCalendar Web Component (Vaadin 10) version 1.0.0.alpha1
FullCalendar Web Component (Vaadin 10) version 1.0.0.alpha2
Added methods to set the height of the calendar. Please also have a look at the demo to see some examples of how to combine container's and calendar's height settings.
FullCalendar Web Component (Vaadin 10) version 1.0.0.alpha3
- added locale support (see demo for details)
- renamed events and listeners so that all of them follow one naming convention
- renamed DayClickEvent to TimeslotClickedEvent to show that also sub day timeslots react on that
- former day click event now provides time information with one locale date time object + all day boolean (were locale date and locale date time optionals before)
- added event handling for timeslot selection (e. g. for adding a larger entry)
- added a method to show week numbers
- added a render() method to force re-rendering
- refactored option handling (internal)
Demo has been updated to show the added functionalities.
FullCalendar Web Component (Vaadin 10) version 1.0.0.alpha4
- Added support for list views (day, week, month, year).
- Extended FC constructor to limit max entries shown per day (except for basic views).
- Fix for locales sent to client. They are now sent lowercase to be fetched correctly by FC.
- Added function to show current time indicator.
- Added function to activate day/week numbers/names as links and define the detail view target.
- Added a constants list of supported locales.
The demo has also been updated to represent the added / changed features.
FullCalendar Web Component (Vaadin 10) version 1.0.0
First official non-alpha release.
- API changes / clean ups
- EntryChangeEvent subclasses now do not apply changes automatically to the entry (but provides a method now to do that conveniently by dev)
- added JUnit tests for all classes
FullCalendar Web Component (Vaadin 10) version 1.1.0
Handling of clicking on a day's or week's number changed. Fires now events instead of simply forwarding to a view, so that server side can handle the event, too. Includes removal of a few deprecated methods.
FullCalendar Web Component (Vaadin 10) version 1.2.0
- added method to set / get options by string key (thanks to marty-buly for the hint)
- added (generated) custom css properties to provide styling of existing options
Please have a look at the github demo. There you'll find a full set of custom variables as styles that you can use for your application. Please be aware, that they are generated, so a lot of these attributes might be nonsense to configure (but some are, so have a look ;)).
https://github.com/stefanuebe/vaadin_fullcalendar/blob/master/demo/src/main/webapp/frontend/styles.html
FullCalendar Web Component (Vaadin 10) version 1.3.0
- added a builder class for FullCalendar instances (and Scheduler derivate)
- bugfixes and smaller needed changes for Scheduler extension integration
Might be that there will be some methods / classes broken, sorry for the needed refactoring. Should be an exception :)
FullCalendar Web Component (Vaadin 10) version 1.3.1
Fixed version for usage in a Vaadin application in production mode.
FullCalendar Web Component (Vaadin 10) version 1.3.2
FullCalendar constructors are now protected instead of package-private for being extensible.
FullCalendar Web Component (Vaadin 10) version 1.3.3
Added a method `setEntryRenderCallback(String)` to set a JS function for client side callback "eventRender" from server side.
Updated also the demo code with an example of how to extend the calendar for own custom mods.
FullCalendar Web Component (Vaadin 10) version 1.4.0
Added support for background /inversed background rendering of entries.
FullCalendar Web Component (Vaadin 10) version 1.5.0
- added support for business hours. You may set multiple instances to have represent different workhours per day.
- (internal) added JsonUtils for some conversion stuff
FullCalendar Web Component (Vaadin 10) version 1.5.1
Added a workaround for https://github.com/stefanuebe/vaadin_fullcalendar/issues/8 and https://github.com/vaadin/flow/issues/4755.
FullCalendar Web Component (Vaadin 10) version 1.6.0
- added timezone support
- some smaller API changes due to timezone support
- some smaller API changes due to false naming (e. g. addXyzEvent() instead of addXyzListener() for a event listener registration method).
- some bugfixes
With this version, entries (and some events) now work on `Instant` as internal time storage. The main API still supports `LocalDate(Time)` with conversion between `Instant` and `LocalDate(Time)` based on the used timezone. If no timezone is set, the calendar uses UTC based times internally only.
Please also have a look at the demo source code, if you need examples, on how to work with Instant and LocalDateTime.
Also I want to thank **Giovanni Lovato** for supporting me at the integration of the timezone support. :)
FullCalendar Web Component (Vaadin 10) version 1.7.0
- added batch methods for adding / updating / removing entries and resources.
- add entry does not anymore return boolean value due to internal api changes.
- add entry does not anymore remove the entry from the previous calendar, this is now to be done by the developer manually (to allow copying entries, e.g.)
- some bugfixes
Thanks to **Martin Israelsen** for the support at this version. :)
FullCalendar Web Component (Vaadin 10) version 1.7.1
ViewRenderEvent now provides first / last shown date (most times not identical to inverval start / end). Thanks to Martin Israelsen for the support here. :)
FullCalendar Web Component (Vaadin 10) version 1.7.2
- FullCalendar.removeAllEntries() now also removes the entry's reference to the calendar
FullCalendar Web Component (Vaadin 10) version 1.8.0
Day click and select event now also transport resource information (client side). This is only relevant when using the scheduler extension. API for FC's methods to add day click or select event listener changed minimal (should not have impacts on normal usage with lambdas, etc.).
FullCalendar Web Component (Vaadin 10) version 1.9.0
- updated used version of FullCalendar to 3.10.0 to fix a bug regarding missing delta values when resizing a event in specific cases
- set constructors to public visibility
FullCalendar Web Component (Vaadin 10) version 1.9.1
Fix for https://github.com/stefanuebe/vaadin_fullcalendar/issues/14.
Before the FCs toolbar was empty, but took some space. Now this space is automatically removed.
FullCalendar Web Component (Vaadin 10) version 1.9.2
- Business hours now maps DayOfWeek.SUNDAY to 0