Commit 8069ed9e authored by Mingsong's avatar Mingsong Committed by Mingsong Hu

Issue #3060026 by jberube, providence_matt, ammuench, Mingsong, danflanagan8:...

Issue #3060026 by jberube, providence_matt, ammuench, Mingsong, danflanagan8: Support Multiple Calendars in One View
parent 2d520d4b
......@@ -35,6 +35,8 @@
const start = info.event.start;
let strEnd = '';
let strStart = '';
let viewIndex = parseInt(this.el.getAttribute("calendar-view-index"));
let viewSettings = drupalSettings.fullCalendarView[viewIndex];
const formatSettings = {
month: '2-digit',
year: 'numeric',
......@@ -70,7 +72,7 @@
});
if (
drupalSettings.updateConfirm === 1 &&
viewSettings.updateConfirm === 1 &&
!confirm(msg)
) {
info.revert();
......@@ -85,12 +87,12 @@
"fullcalendar-view-event-update",
{
eid: info.event.id,
entity_type: drupalSettings.entityType,
entity_type: viewSettings.entityType,
start: strStart,
end: strEnd,
start_field: drupalSettings.startField,
end_field: drupalSettings.endField,
token: drupalSettings.token
start_field: viewSettings.startField,
end_field: viewSettings.endField,
token: viewSettings.token
}
)
.done(function(data) {
......@@ -112,20 +114,22 @@
slotDate = null;
info.jsEvent.preventDefault();
let thisEvent = info.event;
let viewIndex = parseInt(this.el.getAttribute("calendar-view-index"));
let viewSettings = drupalSettings.fullCalendarView[viewIndex];
// Show the event detail in a pop up dialog.
if (drupalSettings.dialogWindow) {
if (viewSettings.dialogWindow) {
let dataDialogOptionsDetails = {};
if (thisEvent.url == '') {
return false;
}
const jsFrame = new JSFrame({
parentElement:document.body,//Set the parent element to which the jsFrame is attached here
parentElement:info.el,//Set the parent element to which the jsFrame is attached here
});
// Position offset.
let posOffset = dialogIndex * 20;
// Dialog options.
let dialogOptions = JSON.parse(drupalSettings.dialog_options);
let dialogOptions = JSON.parse(viewSettings.dialog_options);
dialogOptions.left += posOffset;
dialogOptions.top += posOffset;
dialogOptions.title = thisEvent.title.replace(/(<([^>]+)>)/ig,"");
......@@ -140,7 +144,7 @@
}
// Open a new window to show the details of the event.
if (thisEvent.url) {
if (drupalSettings.openEntityInNewTab) {
if (viewSettings.openEntityInNewTab) {
// Open a new window to show the details of the event.
window.open(thisEvent.url);
return false;
......@@ -161,6 +165,8 @@
const start = info.event.start;
let strEnd = '';
let strStart = '';
let viewIndex = parseInt(this.el.getAttribute("calendar-view-index"));
let viewSettings = drupalSettings.fullCalendarView[viewIndex];
const formatSettings = {
month: '2-digit',
year: 'numeric',
......@@ -196,7 +202,7 @@
});
if (
drupalSettings.updateConfirm === 1 &&
viewSettings.updateConfirm === 1 &&
!confirm(msg)
) {
info.revert();
......@@ -211,12 +217,12 @@
"fullcalendar-view-event-update",
{
eid: info.event.id,
entity_type: drupalSettings.entityType,
entity_type: viewSettings.entityType,
start: strStart,
end: strEnd,
start_field: drupalSettings.startField,
end_field: drupalSettings.endField,
token: drupalSettings.token
start_field: viewSettings.startField,
end_field: viewSettings.endField,
token: viewSettings.token
}
)
.done(function(data) {
......@@ -235,43 +241,52 @@
// @see https://www.drupal.org/project/drupal/issues/2367655
Drupal.behaviors.fullcalendarView = {
attach: function(context, settings) {
var calendarOptions = JSON.parse(drupalSettings.calendar_options);
// Bind the render event handler.
calendarOptions.eventRender = eventRender;
// Bind the resize event handler.
calendarOptions.eventResize = eventResize;
// Bind the day click handler.
calendarOptions.dateClick = dayClickCallback;
// Bind the event click handler.
calendarOptions.eventClick = eventClick;
// Bind the drop event handler.
calendarOptions.eventDrop = eventDrop;
// If the BigPipe module is enabled,
// We need to rebuild the Calendar during Drupal.behavior loops,
// In case the DOM has changed.
// @see https://www.drupal.org/project/fullcalendar_view/issues/3136764
if (drupalSettings.calendar && settings.bigPipePlaceholderIds) {
// Rebuild the calendar.
drupalSettings.calendar.destroy();
drupalSettings.calendar.render();
// Rebuild the calendars.
drupalSettings.calendar.forEach(function(calendar) {
calendar.destroy();
calendar.render();
})
}
else {
$('.js-drupal-fullcalendar', context)
.once("fullCalendarBehavior")
.each(function(index) {
.each(function() {
let calendarEl = this;
let viewIndex = parseInt(calendarEl.getAttribute("calendar-view-index"));
let viewSettings = drupalSettings.fullCalendarView[viewIndex];
var calendarOptions = JSON.parse(viewSettings.calendar_options);
// Bind the render event handler.
calendarOptions.eventRender = eventRender;
// Bind the resize event handler.
calendarOptions.eventResize = eventResize;
// Bind the day click handler.
calendarOptions.dateClick = dayClickCallback;
// Bind the event click handler.
calendarOptions.eventClick = eventClick;
// Bind the drop event handler.
calendarOptions.eventDrop = eventDrop;
// Language select element.
var localeSelectorEl = document.getElementById('locale-selector');
var calendarEl = this;
var localeSelectorEl = document.getElementById('locale-selector-' + viewIndex);
// Initial the calendar.
if (calendarEl) {
drupalSettings.calendar = new FullCalendar.Calendar(calendarEl, calendarOptions);
drupalSettings.calendar.render();
if (calendarEl) {
if (drupalSettings.calendar) {
drupalSettings.calendar[viewIndex] = new FullCalendar.Calendar(calendarEl, calendarOptions);
}
else {
drupalSettings.calendar = [];
drupalSettings.calendar[viewIndex] = new FullCalendar.Calendar(calendarEl, calendarOptions);
}
let calendarObj = drupalSettings.calendar[viewIndex];
calendarObj.render();
// Language dropdown box.
if (drupalSettings.languageSelector) {
if (viewSettings.languageSelector) {
// build the locale selector's options
drupalSettings.calendar.getAvailableLocaleCodes().forEach(function(localeCode) {
calendarObj.getAvailableLocaleCodes().forEach(function(localeCode) {
var optionEl = document.createElement('option');
optionEl.value = localeCode;
optionEl.selected = localeCode == calendarOptions.locale;
......@@ -281,7 +296,8 @@
// when the selected option changes, dynamically change the calendar option
localeSelectorEl.addEventListener('change', function() {
if (this.value) {
drupalSettings.calendar.setOption('locale', this.value);
let viewIndex = parseInt(this.getAttribute("calendar-view-index"));
drupalSettings.calendar[viewIndex].setOption('locale', this.value);
}
});
}
......@@ -291,6 +307,8 @@
// Double click event.
calendarEl.addEventListener('dblclick' , function(e) {
let viewIndex = parseInt(this.getAttribute("calendar-view-index"));
let viewSettings = drupalSettings.fullCalendarView[viewIndex];
// New event window can be open if following conditions match.
// * The new event content type are specified.
// * Allow to create a new event by double click.
......@@ -298,18 +316,18 @@
// * The add form for the new event type is known.
if (
slotDate &&
drupalSettings.eventBundleType &&
drupalSettings.dblClickToCreate &&
drupalSettings.addForm !== ""
viewSettings.eventBundleType &&
viewSettings.dblClickToCreate &&
viewSettings.addForm !== ""
) {
// Open a new window to create a new event (content).
window.open(
drupalSettings.path.baseUrl +
drupalSettings.addForm +
drupalSettings.path.baseUrl +
viewSettings.addForm +
"?start=" +
slotDate +
"&start_field=" +
drupalSettings.startField,
viewSettings.startField,
"_blank"
);
}
......
......@@ -7,6 +7,7 @@ use Drupal\Core\Datetime\DrupalDateTime;
class FullcalendarViewPreprocess {
protected static $viewIndex = 0;
/**
* Process the view variable array.
*
......@@ -14,7 +15,10 @@ class FullcalendarViewPreprocess {
* Template variables.
*/
public function process(array &$variables) {
/* @var \Drupal\views\ViewExecutable $view */
$view = $variables['view'];
// View index.
$view_index = self::$viewIndex++;
$style = $view->style_plugin;
$options = $style->options;
$fields = $view->field;
......@@ -29,6 +33,7 @@ class FullcalendarViewPreprocess {
if (!$user->isAnonymous()) {
$token = \Drupal::csrfToken()->get($user->id());
}
//
// New event bundle type.
$event_bundle_type = $options['bundle_type'];
$entity_type = $view->getBaseEntityType();
......@@ -335,8 +340,9 @@ class FullcalendarViewPreprocess {
// Load the JS library for dialog.
$variables['#attached']['library'][] = 'fullcalendar_view/libraries.jsframe';
}
$variables['view_index'] = $view_index;
// Pass data to js file.
$variables['#attached']['drupalSettings'] = [
$variables['#attached']['drupalSettings']['fullCalendarView'][$view_index] = [
// Allow client to select language, if it is 1.
'languageSelector' => $options['languageSelector'],
// Event update confirmation pop-up dialog.
......
......@@ -8,6 +8,9 @@
* - defaultDate: Default date of the calendar
* - start: Field name of start date
* - end: Field name of end date
* - view_index: View index
* - showAddEvent: Show add event button
* - entity_id: The Entity type machine name
*
* @see template_preprocess_views_view_fullcalendar()
*
......@@ -20,7 +23,7 @@
]
%}
<div{{ attributes.addClass(classes) }}>
<div class="js-drupal-fullcalendar"></div>
<div class="js-drupal-fullcalendar" calendar-view-index="{{ view_index }}"></div>
<div id="bottom-buttons fc-button-group">
{% if showAddEvent %}
<div class="fullcalendar-bottom-btn add-event-btn">
......@@ -30,7 +33,7 @@
{% endif %}
<div class="fullcalendar-bottom-btn locale-selector">
<label for="locale-selector">{{ 'Select Language:'|t }}</label>
<select id='locale-selector'></select>
<select id='locale-selector-{{ view_index }}' calendar-view-index="{{ view_index }}"></select>
</div>
</div>
</div>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment