aboutsummaryrefslogtreecommitdiff
path: root/resources/assets/javascripts/studip-ui/date-picker.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/assets/javascripts/studip-ui/date-picker.js')
-rw-r--r--resources/assets/javascripts/studip-ui/date-picker.js166
1 files changed, 108 insertions, 58 deletions
diff --git a/resources/assets/javascripts/studip-ui/date-picker.js b/resources/assets/javascripts/studip-ui/date-picker.js
index a9fc870..0393aac 100644
--- a/resources/assets/javascripts/studip-ui/date-picker.js
+++ b/resources/assets/javascripts/studip-ui/date-picker.js
@@ -1,26 +1,90 @@
// Setup Stud.IP's own datepicker extensions
-export default {
- selector: '.has-date-picker,[data-date-picker]',
+function getValue(element) {
+ if (Datepicker.supportsNativeInput) {
+ return element.value;
+ }
+
+ return $(element).datepicker('getDate');
+}
+
+function setValue(element, value) {
+ if (Datepicker.supportsNativeInput) {
+ element.value = value;
+ return;
+ }
+
+ $(element).datepicker('setDate', value);
+}
+
+function getOption(element, option) {
+ if (Datepicker.supportsNativeInput) {
+ return element.getAttribute(option) ?? null;
+ }
+
+ const mapping = {
+ min: 'minDate',
+ max: 'maxDate',
+ };
+
+ return $(element).datepicker('option', mapping[option] ?? option);
+}
+
+function setOption(element, option, value) {
+ if (Datepicker.supportsNativeInput) {
+ element.setAttribute(option, value);
+ return;
+ }
+
+ const mapping = {
+ min: 'minDate',
+ max: 'maxDate',
+ };
+
+ $(element).datepicker('option', mapping[option] ?? option, value);
+}
+
+const Datepicker = {
+ supportsNativeInput: (function () {
+ let input = document.createElement('input');
+ input.setAttribute('type', 'date');
+
+ const invalid = 'not-a-valid-date';
+ input.setAttribute('value', invalid);
+
+ return input.value !== invalid;
+ })(),
+ selector: [
+ '.has-date-picker',
+ '[data-date-picker]',
+ 'input[type="date"]',
+ ].join(','),
// Initialize all datepickers that not yet been initialized (e.g. in dialogs)
- init: function () {
- $(this.selector).filter(function () {
- return $(this).data('date-picker-init') === undefined;
- }).each(function () {
- $(this).data('date-picker-init', true).datepicker();
+ init() {
+ Array.from(document.querySelectorAll(this.selector)).filter(node => {
+ return node.dataset.datePickerInit === undefined;
+ }).forEach(element => {
+ element.dataset.datePickerInit = true;
+
+ if (!this.supportsNativeInput) {
+ $(element).datepicker();
+ }
+
+ this.refresh(element);
+
+ element.addEventListener('change', event => {
+ this.refresh(event.target);
+ });
});
},
// Apply registered handlers. Take care: This happens upon before a
// picker is shown as well as after a date has been selected.
- refresh: function () {
- $(this.selector).each(function () {
- var element = this,
- options = $(element).data().datePicker;
- if (options) {
- $.each(options, function (key, value) {
- if (this.dataHandlers[key] !== undefined) {
- this.dataHandlers[key].call(element, value);
- }
- });
+ refresh(node) {
+ const options = node.dataset.datePicker !== undefined
+ ? JSON.parse(node.dataset.datePicker)
+ : {};
+ Object.entries(options).forEach(([key, value]) => {
+ if (this.dataHandlers[key] !== undefined) {
+ this.dataHandlers[key](node, value);
}
});
},
@@ -30,16 +94,11 @@ export default {
// the maximum allowed date the other date.
// This will also set this date to the maximum allowed date if it
// currently later than the allowed maximum date.
- '<='(selector, offset) {
- var this_date = $(this).datepicker('getDate'),
- max_date = null,
- temp,
- adjustment = 0;
-
- if ($(this).data().datePicker.offset) {
- temp = $(this).data().datePicker.offset;
- adjustment = parseInt($(temp).val(), 10);
- }
+ '<='(node, selector, offset = null) {
+ let this_date = getValue(node);
+ let max_date = null;
+
+ offset = offset ?? node.dataset.datePicker?.offset ?? 0;
// Get max date by either actual dates or maxDate options on
// all matching elements
@@ -47,7 +106,7 @@ export default {
max_date = new Date();
} else {
$(selector).each(function () {
- var date = $(this).datepicker('getDate') || $(this).datepicker('option', 'maxDate');
+ var date = getValue(this) ?? getOption(this, 'max');
if (date && (!max_date || date < max_date)) {
max_date = new Date(date);
}
@@ -56,49 +115,41 @@ export default {
// Set max date and adjust current date if neccessary
if (max_date) {
- max_date.setTime(max_date.getTime() - (offset || 0) * 24 * 60 * 60 * 1000);
-
- temp = new Date(max_date);
- temp.setDate(temp.getDate() - adjustment);
+ max_date.setTime(max_date.getTime() - offset * 24 * 60 * 60 * 1000);
if (this_date && this_date > max_date) {
- $(this).datepicker('setDate', temp);
+ setValue(node, max_date);
}
- $(this).datepicker('option', 'maxDate', max_date);
+ setOption(node, 'max', max_date);
} else {
- $(this).datepicker('option', 'maxDate', null);
+ setOption(node, 'max', null);
}
},
// Ensure this date is earlier (<) than another date by setting the
// maximum allowed date to the other date - 1 day.
// This will also set this date to the maximum allowed date - 1 day
// if it is currently later than the allowed maximum date.
- '<'(selector) {
- this['<='].call(this, selector, 1);
+ '<'(node, selector) {
+ this['<='](node, selector, 1);
},
// Ensure this date is not earlier (>=) than another date by setting
// the minimum allowed date to the other date.
// This will also set this date to the minimum allowed date if it is
// currently earlier than the allowed minimum date.
- '>='(selector, offset) {
- var this_date = $(this).datepicker('getDate'),
- min_date = null,
- temp,
- adjustment = 0;
-
- if ($(this).data().datePicker.offset) {
- temp = $(this).data().datePicker.offset;
- adjustment = parseInt($(temp).val(), 10);
- }
+ '>='(node, selector, offset = null) {
+ let this_date = getValue(node);
+ let min_date;
+
+ offset = offset ?? node.dataset.datePicker?.offset ?? 0;
// Get min date by either actual dates or minDate options on
// all matching elements
if (selector === 'today') {
min_date = new Date();
} else {
- $(selector).each(function () {
- var date = $(this).datepicker('getDate') || $(this).datepicker('option', 'minDate');
+ document.querySelectorAll(selector).forEach(n => {
+ var date = getValue(n) ?? getOption(n, 'min');
if (date && (!min_date || date > min_date)) {
min_date = new Date(date);
}
@@ -107,26 +158,25 @@ export default {
// Set min date and adjust current date if neccessary
if (min_date) {
- min_date.setTime(min_date.getTime() + (offset || 0) * 24 * 60 * 60 * 1000);
-
- temp = new Date(min_date);
- temp.setDate(temp.getDate() + adjustment);
+ min_date.setTime(min_date.getTime() + offset * 24 * 60 * 60 * 1000);
if (this_date && this_date < min_date) {
- $(this).datepicker('setDate', temp);
+ setValue(node, min_date);
}
- $(this).datepicker('option', 'minDate', min_date);
+ setOption(node, 'min', min_date);
} else {
- $(this).datepicker('option', 'minDate', null);
+ setOption(node, 'min', null);
}
},
// Ensure this date is later (>) than another date by setting the
// minimum allowed date to the other date + 1 day.
// This will also set this date to the minimum allowed date + 1 day
// if it is currently earlier than the allowed minimum date.
- '>'(selector) {
- this['>='].call(this, selector, 1);
+ '>'(node, selector) {
+ this['>='](node, selector, 1);
}
}
};
+
+export default Datepicker;