mirror of
https://github.com/itflow-org/itflow
synced 2026-08-05 07:07:14 +00:00
Feature: Calendars are now exportable shareable so Third Party Calendar services can read them, also added recoccurence to calendar, and all day along with sperating the time fields and click in a box to add calendar event is possible
This commit is contained in:
92
js/app.js
92
js/app.js
@@ -410,3 +410,95 @@ $(document).ready(function() {
|
||||
// Data Tables
|
||||
new DataTable('.dataTables');
|
||||
});
|
||||
|
||||
/*
|
||||
* Calendar event modals - the All day switch shows or hides the time row.
|
||||
*
|
||||
* The form uses four separate fields (date from / date to / time from / time to),
|
||||
* so nothing here rewrites a value or changes an input type. An earlier version
|
||||
* flipped a single datetime-local input to type="date", which a browser answers by
|
||||
* silently discarding a value it now considers invalid - a fragile arrangement that
|
||||
* left the fields empty whenever this handler had not run.
|
||||
*
|
||||
* required tracks visibility: a hidden required field blocks form submission with an
|
||||
* unfocusable-element error that the user cannot act on.
|
||||
*
|
||||
* Delegated on document because the edit event modal is injected by ajax. The
|
||||
* namespaced .off() keeps this to a single handler - modal_footer.php re-loads this
|
||||
* file on every ajax modal open.
|
||||
*/
|
||||
$(document).off('change.itflowAllDay').on('change.itflowAllDay', '.event-all-day-toggle', function () {
|
||||
|
||||
const allDay = this.checked;
|
||||
const timeFields = document.getElementById(this.id.replace(/_all_day$/, '_time_fields'));
|
||||
|
||||
if (!timeFields) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeFields.classList.toggle('d-none', allDay);
|
||||
|
||||
timeFields.querySelectorAll('input').forEach(function (field) {
|
||||
if (allDay) {
|
||||
field.removeAttribute('required');
|
||||
} else {
|
||||
field.setAttribute('required', 'required');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Keep the end date at or after the start date, without shortening a longer span
|
||||
* the user has already chosen.
|
||||
*/
|
||||
$(document).off('change.itflowEventDate').on('change.itflowEventDate', '.event-start-date', function () {
|
||||
|
||||
const endField = document.getElementById(this.id.replace(/_start_date$/, '_end_date'));
|
||||
|
||||
if (!endField || !this.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endField.value || endField.value < this.value) {
|
||||
endField.value = this.value;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Default the end time to an hour after the start, leaving a longer span alone.
|
||||
* A start late in the evening rolls the end onto the following day rather than
|
||||
* wrapping round to an end that precedes the start.
|
||||
*/
|
||||
$(document).off('change.itflowEventTime').on('change.itflowEventTime', '.event-start-time', function () {
|
||||
|
||||
const prefix = this.id.replace(/_start_time$/, '');
|
||||
const endField = document.getElementById(prefix + '_end_time');
|
||||
|
||||
if (!endField || !this.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (endField.value && endField.value > this.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parts = this.value.split(':');
|
||||
const end = new Date(2000, 0, 1, Number(parts[0]), Number(parts[1]));
|
||||
end.setHours(end.getHours() + 1);
|
||||
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
endField.value = pad(end.getHours()) + ':' + pad(end.getMinutes());
|
||||
|
||||
// Crossed midnight - carry the end date forward so the event still ends after
|
||||
// it starts
|
||||
if (end.getDate() !== 1) {
|
||||
const startDate = document.getElementById(prefix + '_start_date');
|
||||
const endDate = document.getElementById(prefix + '_end_date');
|
||||
|
||||
if (startDate && endDate && startDate.value && endDate.value <= startDate.value) {
|
||||
const next = new Date(startDate.value + 'T00:00:00');
|
||||
next.setDate(next.getDate() + 1);
|
||||
endDate.value = next.getFullYear() + '-' + pad(next.getMonth() + 1) + '-' + pad(next.getDate());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Delegated on document rather than bound to the links present at page load, so
|
||||
// that confirm-link also works on markup injected by an ajax modal
|
||||
$(document).ready(function() {
|
||||
$("a.confirm-link").click(function(e) {
|
||||
$(document).off('click.itflowConfirm').on('click.itflowConfirm', 'a.confirm-link', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Save the link reference to use after confirmation
|
||||
|
||||
Reference in New Issue
Block a user