aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlackDex <[email protected]>2021-09-18 19:49:44 +0200
committerBlackDex <[email protected]>2021-09-18 19:49:44 +0200
commitb0a411b7333a5cf68fc3e78b67a61427c01d18fd (patch)
treeaa54ddb460235599c418ad952e22456a03a3fdf6
parent8c10de3eddd8349264074c3aa3a7d955862275a6 (diff)
downloadvaultwarden-b0a411b7333a5cf68fc3e78b67a61427c01d18fd.tar.gz
vaultwarden-b0a411b7333a5cf68fc3e78b67a61427c01d18fd.zip
Update some JS Libraries and fix small issues
- Updated JS Libraries - Downgraded bootstrap.css to v5.0.2 which works with Bootstrap-Native. - Fixed issue with settings being able to open/collapse on some systems. - Added .js and .css to the exclude list for the end-of-file-fixer pre-commit
-rw-r--r--.pre-commit-config.yaml1
-rw-r--r--src/static/scripts/bootstrap-native.js101
-rw-r--r--src/static/scripts/bootstrap.css870
-rw-r--r--src/static/scripts/datatables.css110
-rw-r--r--src/static/scripts/datatables.js810
-rw-r--r--src/static/templates/admin/settings.hbs15
6 files changed, 757 insertions, 1150 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index f9dfcbf4..b26d8445 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -7,6 +7,7 @@ repos:
- id: check-json
- id: check-toml
- id: end-of-file-fixer
+ exclude: "(.*js$|.*css$)"
- id: check-case-conflict
- id: check-merge-conflict
- id: detect-private-key
diff --git a/src/static/scripts/bootstrap-native.js b/src/static/scripts/bootstrap-native.js
index 82e63f27..2159b3db 100644
--- a/src/static/scripts/bootstrap-native.js
+++ b/src/static/scripts/bootstrap-native.js
@@ -1,5 +1,5 @@
/*!
- * Native JavaScript for Bootstrap v4.0.4 (https://thednp.github.io/bootstrap.native/)
+ * Native JavaScript for Bootstrap v4.0.6 (https://thednp.github.io/bootstrap.native/)
* Copyright 2015-2021 © dnp_theme
* Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE)
*/
@@ -1467,19 +1467,26 @@
}
}
- const modalOpenClass = 'modal-open';
const modalBackdropClass = 'modal-backdrop';
+ const offcanvasBackdropClass = 'offcanvas-backdrop';
const modalActiveSelector = `.modal.${showClass}`;
const offcanvasActiveSelector = `.offcanvas.${showClass}`;
-
const overlay = document.createElement('div');
- overlay.setAttribute('class', `${modalBackdropClass}`);
function getCurrentOpen() {
return queryElement(`${modalActiveSelector},${offcanvasActiveSelector}`);
}
- function appendOverlay(hasFade) {
+ function toggleOverlayType(isModal) {
+ const targetClass = isModal ? modalBackdropClass : offcanvasBackdropClass;
+ [modalBackdropClass, offcanvasBackdropClass].forEach((c) => {
+ removeClass(overlay, c);
+ });
+ addClass(overlay, targetClass);
+ }
+
+ function appendOverlay(hasFade, isModal) {
+ toggleOverlayType(isModal);
document.body.appendChild(overlay);
if (hasFade) addClass(overlay, fadeClass);
}
@@ -1499,7 +1506,6 @@
if (!currentOpen) {
removeClass(overlay, fadeClass);
- removeClass(bd, modalOpenClass);
bd.removeChild(overlay);
resetScrollbar();
}
@@ -1518,7 +1524,6 @@
const modalString = 'modal';
const modalComponent = 'Modal';
const modalSelector = `.${modalString}`;
- // const modalActiveSelector = `.${modalString}.${showClass}`;
const modalToggleSelector = `[${dataBsToggle}="${modalString}"]`;
const modalDismissSelector = `[${dataBsDismiss}="${modalString}"]`;
const modalStaticClass = `${modalString}-static`;
@@ -1567,8 +1572,11 @@
}
function afterModalHide(self) {
- const { triggers } = self;
- removeOverlay();
+ const { triggers, options } = self;
+ if (!getCurrentOpen()) {
+ if (options.backdrop) removeOverlay();
+ resetScrollbar();
+ }
self.element.style.paddingRight = '';
self.isAnimating = false;
@@ -1594,9 +1602,8 @@
element.style.display = 'block';
setModalScrollbar(self);
- if (!queryElement(modalActiveSelector)) {
+ if (!getCurrentOpen()) {
document.body.style.overflow = 'hidden';
- addClass(document.body, modalOpenClass);
}
addClass(element, showClass);
@@ -1609,16 +1616,15 @@
function beforeModalHide(self, force) {
const {
- element, relatedTarget, hasFade,
+ element, options, relatedTarget, hasFade,
} = self;
- const currentOpen = getCurrentOpen();
element.style.display = '';
// force can also be the transitionEvent object, we wanna make sure it's not
// call is not forced and overlay is visible
- if (!force && hasFade && hasClass(overlay, showClass)
- && !currentOpen) { // AND no modal is visible
+ if (options.backdrop && !force && hasFade && hasClass(overlay, showClass)
+ && !getCurrentOpen()) { // AND no modal is visible
hideOverlay();
emulateTransitionEnd(overlay, () => afterModalHide(self));
} else {
@@ -1666,7 +1672,8 @@
if (self.isAnimating) return;
- const { isStatic, modalDialog } = self;
+ const { options, isStatic, modalDialog } = self;
+ const { backdrop } = options;
const { target } = e;
const selectedText = document.getSelection().toString().length;
const targetInsideDialog = modalDialog.contains(target);
@@ -1676,7 +1683,7 @@
addClass(element, modalStaticClass);
self.isAnimating = true;
emulateTransitionEnd(modalDialog, () => staticTransitionEnd(self));
- } else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog)) {
+ } else if (dismiss || (!selectedText && !isStatic && !targetInsideDialog && backdrop)) {
self.relatedTarget = dismiss || null;
self.hide();
e.preventDefault();
@@ -1734,8 +1741,9 @@
show() {
const self = this;
const {
- element, isAnimating, hasFade, relatedTarget,
+ element, options, isAnimating, hasFade, relatedTarget,
} = self;
+ const { backdrop } = options;
let overlayDelay = 0;
if (hasClass(element, showClass) && !isAnimating) return;
@@ -1744,8 +1752,6 @@
element.dispatchEvent(showModalEvent);
if (showModalEvent.defaultPrevented) return;
- self.isAnimating = true;
-
// we elegantly hide any opened modal/offcanvas
const currentOpen = getCurrentOpen();
if (currentOpen && currentOpen !== element) {
@@ -1755,18 +1761,24 @@
that.hide();
}
- if (!queryElement(`.${modalBackdropClass}`)) {
- appendOverlay(hasFade);
- }
- overlayDelay = getElementTransitionDuration(overlay);
+ self.isAnimating = true;
- if (!hasClass(overlay, showClass)) {
- showOverlay();
- }
+ if (backdrop) {
+ if (!currentOpen && !hasClass(overlay, showClass)) {
+ appendOverlay(hasFade, 1);
+ } else {
+ toggleOverlayType(1);
+ }
+ overlayDelay = getElementTransitionDuration(overlay);
- if (!currentOpen) {
+ if (!hasClass(overlay, showClass)) showOverlay();
setTimeout(() => beforeModalShow(self), overlayDelay);
- } else beforeModalShow(self);
+ } else {
+ beforeModalShow(self);
+ if (currentOpen && hasClass(overlay, showClass)) {
+ hideOverlay();
+ }
+ }
}
hide(force) {
@@ -1863,7 +1875,6 @@
const { element, options } = self;
if (!options.scroll) {
- addClass(document.body, modalOpenClass);
document.body.style.overflow = 'hidden';
setOffCanvasScrollbar(self);
}
@@ -1909,15 +1920,15 @@
const self = element[offcanvasComponent];
if (!self) return;
- const { options, open, triggers } = self;
+ const { options, triggers } = self;
const { target } = e;
const trigger = target.closest(offcanvasToggleSelector);
if (trigger && trigger.tagName === 'A') e.preventDefault();
- if (open && ((!element.contains(target) && options.backdrop
+ if ((!element.contains(target) && options.backdrop
&& (!trigger || (trigger && !triggers.includes(trigger))))
- || offCanvasDismiss.contains(target))) {
+ || offCanvasDismiss.contains(target)) {
self.relatedTarget = target === offCanvasDismiss ? offCanvasDismiss : null;
self.hide();
}
@@ -1965,7 +1976,6 @@
element.removeAttribute(ariaModal);
element.removeAttribute('role');
element.style.visibility = '';
- self.open = false;
self.isAnimating = false;
if (triggers.length) {
@@ -1979,7 +1989,6 @@
if (options.backdrop) removeOverlay();
if (!options.scroll) {
resetScrollbar();
- removeClass(document.body, modalOpenClass);
}
}
@@ -2005,7 +2014,6 @@
.filter((btn) => getTargetElement(btn) === element);
// additional instance property
- self.open = false;
self.isAnimating = false;
self.scrollbarWidth = measureScrollbar();
@@ -2017,7 +2025,8 @@
// ========================
toggle() {
const self = this;
- return self.open ? self.hide() : self.show();
+ if (hasClass(self.element, showClass)) self.hide();
+ else self.show();
}
show() {
@@ -2027,7 +2036,7 @@
} = self;
let overlayDelay = 0;
- if (self.open || isAnimating) return;
+ if (hasClass(element, showClass) || isAnimating) return;
showOffcanvasEvent.relatedTarget = relatedTarget || null;
element.dispatchEvent(showOffcanvasEvent);
@@ -2043,12 +2052,13 @@
that.hide();
}
- self.open = true;
self.isAnimating = true;
if (options.backdrop) {
- if (!queryElement(`.${modalBackdropClass}`)) {
+ if (!currentOpen) {
appendOverlay(1);
+ } else {
+ toggleOverlayType();
}
overlayDelay = getElementTransitionDuration(overlay);
@@ -2056,14 +2066,19 @@
if (!hasClass(overlay, showClass)) showOverlay();
setTimeout(() => beforeOffcanvasShow(self), overlayDelay);
- } else beforeOffcanvasShow(self);
+ } else {
+ beforeOffcanvasShow(self);
+ if (currentOpen && hasClass(overlay, showClass)) {
+ hideOverlay();
+ }
+ }
}
hide(force) {
const self = this;
const { element, isAnimating, relatedTarget } = self;
- if (!self.open || isAnimating) return;
+ if (!hasClass(element, showClass) || isAnimating) return;
hideOffcanvasEvent.relatedTarget = relatedTarget || null;
element.dispatchEvent(hideOffcanvasEvent);
@@ -3483,7 +3498,7 @@
constructor: Tooltip,
};
- var version = "4.0.4";
+ var version = "4.0.6";
// import { alertInit } from '../components/alert-native.js';
// import { buttonInit } from '../components/button-native.js';
diff --git a/src/static/scripts/bootstrap.css b/src/static/scripts/bootstrap.css
index da83b00f..892302a6 100644
--- a/src/static/scripts/bootstrap.css
+++ b/src/static/scripts/bootstrap.css
@@ -1,6 +1,6 @@
@charset "UTF-8";
/*!
- * Bootstrap v5.1.0 (https://getbootstrap.com/)
+ * Bootstrap v5.0.2 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
@@ -19,15 +19,6 @@
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
- --bs-gray-100: #f8f9fa;
- --bs-gray-200: #e9ecef;
- --bs-gray-300: #dee2e6;
- --bs-gray-400: #ced4da;
- --bs-gray-500: #adb5bd;
- --bs-gray-600: #6c757d;
- --bs-gray-700: #495057;
- --bs-gray-800: #343a40;
- --bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
@@ -36,26 +27,9 @@
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
- --bs-primary-rgb: 13, 110, 253;
- --bs-secondary-rgb: 108, 117, 125;
- --bs-success-rgb: 25, 135, 84;
- --bs-info-rgb: 13, 202, 240;
- --bs-warning-rgb: 255, 193, 7;
- --bs-danger-rgb: 220, 53, 69;
- --bs-light-rgb: 248, 249, 250;
- --bs-dark-rgb: 33, 37, 41;
- --bs-white-rgb: 255, 255, 255;
- --bs-black-rgb: 0, 0, 0;
- --bs-body-rgb: 33, 37, 41;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
- --bs-body-font-family: var(--bs-font-sans-serif);
- --bs-body-font-size: 1rem;
- --bs-body-font-weight: 400;
- --bs-body-line-height: 1.5;
- --bs-body-color: #212529;
- --bs-body-bg: #fff;
}
*,
@@ -72,13 +46,12 @@
body {
margin: 0;
- font-family: var(--bs-body-font-family);
- font-size: var(--bs-body-font-size);
- font-weight: var(--bs-body-font-weight);
- line-height: var(--bs-body-line-height);
- color: var(--bs-body-color);
- text-align: var(--bs-body-text-align);
- background-color: var(--bs-body-bg);
+ font-family: var(--bs-font-sans-serif);
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #212529;
+ background-color: #fff;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
@@ -712,6 +685,206 @@ progress {
width: 16.6666666667%;
}
+@media (min-width: 576px) {
+ .col-sm {
+ flex: 1 0 0%;
+ }
+
+ .row-cols-sm-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-sm-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-sm-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-sm-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-sm-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-sm-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-sm-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+}
+@media (min-width: 768px) {
+ .col-md {
+ flex: 1 0 0%;
+ }
+
+ .row-cols-md-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-md-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-md-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-md-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-md-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-md-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-md-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+}
+@media (min-width: 992px) {
+ .col-lg {
+ flex: 1 0 0%;
+ }
+
+ .row-cols-lg-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-lg-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-lg-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-lg-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-lg-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-lg-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-lg-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+}
+@media (min-width: 1200px) {
+ .col-xl {
+ flex: 1 0 0%;
+ }
+
+ .row-cols-xl-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-xl-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-xl-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-xl-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-xl-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-xl-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-xl-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+}
+@media (min-width: 1400px) {
+ .col-xxl {
+ flex: 1 0 0%;
+ }
+
+ .row-cols-xxl-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-xxl-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-xxl-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-xxl-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-xxl-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-xxl-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-xxl-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+}
.col-auto {
flex: 0 0 auto;
width: auto;
@@ -882,45 +1055,6 @@ progress {
}
@media (min-width: 576px) {
- .col-sm {
- flex: 1 0 0%;
- }
-
- .row-cols-sm-auto > * {
- flex: 0 0 auto;
- width: auto;
- }
-
- .row-cols-sm-1 > * {
- flex: 0 0 auto;
- width: 100%;
- }
-
- .row-cols-sm-2 > * {
- flex: 0 0 auto;
- width: 50%;
- }
-
- .row-cols-sm-3 > * {
- flex: 0 0 auto;
- width: 33.3333333333%;
- }
-
- .row-cols-sm-4 > * {
- flex: 0 0 auto;
- width: 25%;
- }
-
- .row-cols-sm-5 > * {
- flex: 0 0 auto;
- width: 20%;
- }
-
- .row-cols-sm-6 > * {
- flex: 0 0 auto;
- width: 16.6666666667%;
- }
-
.col-sm-auto {
flex: 0 0 auto;
width: auto;
@@ -1095,45 +1229,6 @@ progress {
}
}
@media (min-width: 768px) {
- .col-md {
- flex: 1 0 0%;
- }
-
- .row-cols-md-auto > * {
- flex: 0 0 auto;
- width: auto;
- }
-
- .row-cols-md-1 > * {
- flex: 0 0 auto;
- width: 100%;
- }
-
- .row-cols-md-2 > * {
- flex: 0 0 auto;
- width: 50%;
- }
-
- .row-cols-md-3 > * {
- flex: 0 0 auto;
- width: 33.3333333333%;
- }
-
- .row-cols-md-4 > * {
- flex: 0 0 auto;
- width: 25%;
- }
-
- .row-cols-md-5 > * {
- flex: 0 0 auto;
- width: 20%;
- }
-
- .row-cols-md-6 > * {
- flex: 0 0 auto;
- width: 16.6666666667%;
- }
-
.col-md-auto {
flex: 0 0 auto;
width: auto;
@@ -1308,45 +1403,6 @@ progress {
}
}
@media (min-width: 992px) {
- .col-lg {
- flex: 1 0 0%;
- }
-
- .row-cols-lg-auto > * {
- flex: 0 0 auto;
- width: auto;
- }
-
- .row-cols-lg-1 > * {
- flex: 0 0 auto;
- width: 100%;
- }
-
- .row-cols-lg-2 > * {
- flex: 0 0 auto;
- width: 50%;
- }
-
- .row-cols-lg-3 > * {
- flex: 0 0 auto;
- width: 33.3333333333%;
- }
-
- .row-cols-lg-4 > * {
- flex: 0 0 auto;
- width: 25%;
- }
-
- .row-cols-lg-5 > * {
- flex: 0 0 auto;
- width: 20%;
- }
-
- .row-cols-lg-6 > * {
- flex: 0 0 auto;
- width: 16.6666666667%;
- }
-
.col-lg-auto {
flex: 0 0 auto;
width: auto;
@@ -1521,45 +1577,6 @@ progress {
}
}
@media (min-width: 1200px) {
- .col-xl {
- flex: 1 0 0%;
- }
-
- .row-cols-xl-auto > * {
- flex: 0 0 auto;
- width: auto;
- }
-
- .row-cols-xl-1 > * {
- flex: 0 0 auto;
- width: 100%;
- }
-
- .row-cols-xl-2 > * {
- flex: 0 0 auto;
- width: 50%;
- }
-
- .row-cols-xl-3 > * {
- flex: 0 0 auto;
- width: 33.3333333333%;
- }
-
- .row-cols-xl-4 > * {
- flex: 0 0 auto;
- width: 25%;
- }
-
- .row-cols-xl-5 > * {
- flex: 0 0 auto;
- width: 20%;
- }
-
- .row-cols-xl-6 > * {
- flex: 0 0 auto;
- width: 16.6666666667%;
- }
-
.col-xl-auto {
flex: 0 0 auto;
width: auto;
@@ -1734,45 +1751,6 @@ progress {
}
}
@media (min-width: 1400px) {
- .col-xxl {
- flex: 1 0 0%;
- }
-
- .row-cols-xxl-auto > * {
- flex: 0 0 auto;
- width: auto;
- }
-
- .row-cols-xxl-1 > * {
- flex: 0 0 auto;
- width: 100%;
- }
-
- .row-cols-xxl-2 > * {
- flex: 0 0 auto;
- width: 50%;
- }
-
- .row-cols-xxl-3 > * {
- flex: 0 0 auto;
- width: 33.3333333333%;
- }
-
- .row-cols-xxl-4 > * {
- flex: 0 0 auto;
- width: 25%;
- }
-
- .row-cols-xxl-5 > * {
- flex: 0 0 auto;
- width: 20%;
- }
-
- .row-cols-xxl-6 > * {
- flex: 0 0 auto;
- width: 16.6666666667%;
- }
-
.col-xxl-auto {
flex: 0 0 auto;
width: auto;
@@ -2288,7 +2266,7 @@ progress {
}
.form-control-sm {
- min-height: calc(1.5em + 0.5rem + 2px);
+ min-height: calc(1.5em + (0.5rem + 2px));
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
border-radius: 0.2rem;
@@ -2307,7 +2285,7 @@ progress {
}
.form-control-lg {
- min-height: calc(1.5em + 1rem + 2px);
+ min-height: calc(1.5em + (1rem + 2px));
padding: 0.5rem 1rem;
font-size: 1.25rem;
border-radius: 0.3rem;
@@ -2326,17 +2304,17 @@ progress {
}
textarea.form-control {
- min-height: calc(1.5em + 0.75rem + 2px);
+ min-height: calc(1.5em + (0.75rem + 2px));
}
textarea.form-control-sm {
- min-height: calc(1.5em + 0.5rem + 2px);
+ min-height: calc(1.5em + (0.5rem + 2px));
}
textarea.form-control-lg {
- min-height: calc(1.5em + 1rem + 2px);
+ min-height: calc(1.5em + (1rem + 2px));
}
.form-control-color {
- width: 3rem;
+ max-width: 3rem;
height: auto;
padding: 0.375rem;
}
@@ -3452,16 +3430,6 @@ textarea.form-control-lg {
transition: none;
}
}
-.collapsing.collapse-horizontal {
- width: 0;
- height: auto;
- transition: width 0.35s ease;
-}
-@media (prefers-reduced-motion: reduce) {
- .collapsing.collapse-horizontal {
- transition: none;
- }
-}
.dropup,
.dropend,
@@ -4079,33 +4047,6 @@ textarea.form-control-lg {
.navbar-expand-sm .navbar-toggler {
display: none;
}
- .navbar-expand-sm .offcanvas-header {
- display: none;
- }
- .navbar-expand-sm .offcanvas {
- position: inherit;
- bottom: 0;
- z-index: 1000;
- flex-grow: 1;
- visibility: visible !important;
- background-color: transparent;
- border-right: 0;
- border-left: 0;
- transition: none;
- transform: none;
- }
- .navbar-expand-sm .offcanvas-top,
-.navbar-expand-sm .offcanvas-bottom {
- height: auto;
- border-top: 0;
- border-bottom: 0;
- }
- .navbar-expand-sm .offcanvas-body {
- display: flex;
- flex-grow: 0;
- padding: 0;
- overflow-y: visible;
- }
}
@media (min-width: 768px) {
.navbar-expand-md {
@@ -4132,33 +4073,6 @@ textarea.form-control-lg {
.navbar-expand-md .navbar-toggler {
display: none;
}
- .navbar-expand-md .offcanvas-header {
- display: none;
- }
- .navbar-expand-md .offcanvas {
- position: inherit;
- bottom: 0;
- z-index: 1000;
- flex-grow: 1;
- visibility: visible !important;
- background-color: transparent;
- border-right: 0;
- border-left: 0;
- transition: none;
- transform: none;
- }
- .navbar-expand-md .offcanvas-top,
-.navbar-expand-md .offcanvas-bottom {
- height: auto;
- border-top: 0;
- border-bottom: 0;
- }
- .navbar-expand-md .offcanvas-body {
- display: flex;
- flex-grow: 0;
- padding: 0;
- overflow-y: visible;
- }
}
@media (min-width: 992px) {
.navbar-expand-lg {
@@ -4185,33 +4099,6 @@ textarea.form-control-lg {
.navbar-expand-lg .navbar-toggler {
display: none;
}
- .navbar-expand-lg .offcanvas-header {
- display: none;
- }
- .navbar-expand-lg .offcanvas {
- position: inherit;
- bottom: 0;
- z-index: 1000;
- flex-grow: 1;
- visibility: visible !important;
- background-color: transparent;
- border-right: 0;
- border-left: 0;
- transition: none;
- transform: none;
- }
- .navbar-expand-lg .offcanvas-top,
-.navbar-expand-lg .offcanvas-bottom {
- height: auto;
- border-top: 0;
- border-bottom: 0;
- }
- .navbar-expand-lg .offcanvas-body {
- display: flex;
- flex-grow: 0;
- padding: 0;
- overflow-y: visible;
- }
}
@media (min-width: 1200px) {
.navbar-expand-xl {
@@ -4238,33 +4125,6 @@ textarea.form-control-lg {
.navbar-expand-xl .navbar-toggler {
display: none;
}
- .navbar-expand-xl .offcanvas-header {
- display: none;
- }
- .navbar-expand-xl .offcanvas {
- position: inherit;
- bottom: 0;
- z-index: 1000;
- flex-grow: 1;
- visibility: visible !important;
- background-color: transparent;
- border-right: 0;
- border-left: 0;
- transition: none;
- transform: none;
- }
- .navbar-expand-xl .offcanvas-top,
-.navbar-expand-xl .offcanvas-bottom {
- height: auto;
- border-top: 0;
- border-bottom: 0;
- }
- .navbar-expand-xl .offcanvas-body {
- display: flex;
- flex-grow: 0;
- padding: 0;
- overflow-y: visible;
- }
}
@media (min-width: 1400px) {
.navbar-expand-xxl {
@@ -4291,33 +4151,6 @@ textarea.form-control-lg {
.navbar-expand-xxl .navbar-toggler {
display: none;
}
- .navbar-expand-xxl .offcanvas-header {
- display: none;
- }
- .navbar-expand-xxl .offcanvas {
- position: inherit;
- bottom: 0;
- z-index: 1000;
- flex-grow: 1;
- visibility: visible !important;
- background-color: transparent;
- border-right: 0;
- border-left: 0;
- transition: none;
- transform: none;
- }
- .navbar-expand-xxl .offcanvas-top,
-.navbar-expand-xxl .offcanvas-bottom {
- height: auto;
- border-top: 0;
- border-bottom: 0;
- }
- .navbar-expand-xxl .offcanvas-body {
- display: flex;
- flex-grow: 0;
- padding: 0;
- overflow-y: visible;
- }
}
.navbar-expand {
flex-wrap: nowrap;
@@ -4343,33 +4176,6 @@ textarea.form-control-lg {
.navbar-expand .navbar-toggler {
display: none;
}
-.navbar-expand .offcanvas-header {
- display: none;
-}
-.navbar-expand .offcanvas {
- position: inherit;
- bottom: 0;
- z-index: 1000;
- flex-grow: 1;
- visibility: visible !important;
- background-color: transparent;
- border-right: 0;
- border-left: 0;
- transition: none;
- transform: none;
-}
-.navbar-expand .offcanvas-top,
-.navbar-expand .offcanvas-bottom {
- height: auto;
- border-top: 0;
- border-bottom: 0;
-}
-.navbar-expand .offcanvas-body {
- display: flex;
- flex-grow: 0;
- padding: 0;
- overflow-y: visible;
-}
.navbar-light .navbar-brand {
color: rgba(0, 0, 0, 0.9);
@@ -4493,6 +4299,9 @@ textarea.form-control-lg {
margin-bottom: 0;
}
+.card-link:hover {
+ text-decoration: none;
+}
.card-link + .card-link {
margin-left: 1rem;
}
@@ -5368,10 +5177,10 @@ textarea.form-control-lg {
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
border-radius: 0.25rem;
}
-.toast.showing {
+.toast:not(.showing):not(.show) {
opacity: 0;
}
-.toast:not(.show) {
+.toast.hide {
display: none;
}
@@ -5411,7 +5220,7 @@ textarea.form-control-lg {
position: fixed;
top: 0;
left: 0;
- z-index: 1055;
+ z-index: 1060;
display: none;
width: 100%;
height: 100%;
@@ -5476,7 +5285,7 @@ textarea.form-control-lg {
position: fixed;
top: 0;
left: 0;
- z-index: 1050;
+ z-index: 1040;
width: 100vw;
height: 100vh;
background-color: #000;
@@ -6201,7 +6010,7 @@ textarea.form-control-lg {
.offcanvas {
position: fixed;
bottom: 0;
- z-index: 1045;
+ z-index: 1050;
display: flex;
flex-direction: column;
max-width: 100%;
@@ -6217,22 +6026,6 @@ textarea.form-control-lg {
}
}
-.offcanvas-backdrop {
- position: fixed;
- top: 0;
- left: 0;
- z-index: 1040;
- width: 100vw;
- height: 100vh;
- background-color: #000;
-}
-.offcanvas-backdrop.fade {
- opacity: 0;
-}
-.offcanvas-backdrop.show {
- opacity: 0.5;
-}
-
.offcanvas-header {
display: flex;
align-items: center;
@@ -6296,69 +6089,6 @@ textarea.form-control-lg {
transform: none;
}
-.placeholder {
- display: inline-block;
- min-height: 1em;
- vertical-align: middle;
- cursor: wait;
- background-color: currentColor;
- opacity: 0.5;
-}
-.placeholder.btn::before {
- display: inline-block;
- content: "";
-}
-
-.placeholder-xs {
- min-height: 0.6em;
-}
-
-.placeholder-sm {
- min-height: 0.8em;
-}
-
-.placeholder-lg {
- min-height: 1.2em;
-}
-
-.placeholder-glow .placeholder {
- -webkit-animation: placeholder-glow 2s ease-in-out infinite;
- animation: placeholder-glow 2s ease-in-out infinite;
-}
-
-@-webkit-keyframes placeholder-glow {
- 50% {
- opacity: 0.2;
- }
-}
-
-@keyframes placeholder-glow {
- 50% {
- opacity: 0.2;
- }
-}
-.placeholder-wave {
- -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);
- mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);
- -webkit-mask-size: 200% 100%;
- mask-size: 200% 100%;
- -webkit-animation: placeholder-wave 2s linear infinite;
- animation: placeholder-wave 2s linear infinite;
-}
-
-@-webkit-keyframes placeholder-wave {
- 100% {
- -webkit-mask-position: -200% 0%;
- mask-position: -200% 0%;
- }
-}
-
-@keyframes placeholder-wave {
- 100% {
- -webkit-mask-position: -200% 0%;
- mask-position: -200% 0%;
- }
-}
.clearfix::after {
display: block;
clear: both;
@@ -6517,20 +6247,6 @@ textarea.form-control-lg {
z-index: 1020;
}
}
-.hstack {
- display: flex;
- flex-direction: row;
- align-items: center;
- align-self: stretch;
-}
-
-.vstack {
- display: flex;
- flex: 1 1 auto;
- flex-direction: column;
- align-self: stretch;
-}
-
.visually-hidden,
.visually-hidden-focusable:not(:focus):not(:focus-within) {
position: absolute !important;
@@ -6560,15 +6276,6 @@ textarea.form-control-lg {
white-space: nowrap;
}
-.vr {
- display: inline-block;
- align-self: stretch;
- width: 1px;
- min-height: 1em;
- background-color: currentColor;
- opacity: 0.25;
-}
-
.align-baseline {
vertical-align: baseline !important;
}
@@ -6605,26 +6312,6 @@ textarea.form-control-lg {
float: none !important;
}
-.opacity-0 {
- opacity: 0 !important;
-}
-
-.opacity-25 {
- opacity: 0.25 !important;
-}
-
-.opacity-50 {
- opacity: 0.5 !important;
-}
-
-.opacity-75 {
- opacity: 0.75 !important;
-}
-
-.opacity-100 {
- opacity: 1 !important;
-}
-
.overflow-auto {
overflow: auto !important;
}
@@ -7648,176 +7335,105 @@ textarea.form-control-lg {
/* rtl:end:remove */
.text-primary {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;
+ color: #0d6efd !important;
}
.text-secondary {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;
+ color: #6c757d !important;
}
.text-success {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;
+ color: #198754 !important;
}
.text-info {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;
+ color: #0dcaf0 !important;
}
.text-warning {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;
+ color: #ffc107 !important;
}
.text-danger {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;
+ color: #dc3545 !important;
}
.text-light {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;
+ color: #f8f9fa !important;
}
.text-dark {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;
-}
-
-.text-black {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;
+ color: #212529 !important;
}
.text-white {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;
+ color: #fff !important;
}
.text-body {
- --bs-text-opacity: 1;
- color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important;
+ color: #212529 !important;
}
.text-muted {
- --bs-text-opacity: 1;
color: #6c757d !important;
}
.text-black-50 {
- --bs-text-opacity: 1;
color: rgba(0, 0, 0, 0.5) !important;
}
.text-white-50 {
- --bs-text-opacity: 1;
color: rgba(255, 255, 255, 0.5) !important;
}
.text-reset {
- --bs-text-opacity: 1;
color: inherit !important;
}
-.text-opacity-25 {
- --bs-text-opacity: 0.25;
-}
-
-.text-opacity-50 {
- --bs-text-opacity: 0.5;
-}
-
-.text-opacity-75 {
- --bs-text-opacity: 0.75;
-}
-
-.text-opacity-100 {
- --bs-text-opacity: 1;
-}
-
.bg-primary {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #0d6efd !important;
}
.bg-secondary {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #6c757d !important;
}
.bg-success {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #198754 !important;
}
.bg-info {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #0dcaf0 !important;
}
.bg-warning {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #ffc107 !important;
}
.bg-danger {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #dc3545 !important;
}
.bg-light {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #f8f9fa !important;
}
.bg-dark {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #212529 !important;
}
-.bg-black {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;
+.bg-body {
+ background-color: #fff !important;
}
.bg-white {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;
-}
-
-.bg-body {
- --bs-bg-opacity: 1;
- background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important;
+ background-color: #fff !important;
}
.bg-transparent {
- --bs-bg-opacity: 1;
background-color: transparent !important;
}
-.bg-opacity-10 {
- --bs-bg-opacity: 0.1;
-}
-
-.bg-opacity-25 {
- --bs-bg-opacity: 0.25;
-}
-
-.bg-opacity-50 {
- --bs-bg-opacity: 0.5;
-}
-
-.bg-opacity-75 {
- --bs-bg-opacity: 0.75;
-}
-
-.bg-opacity-100 {
- --bs-bg-opacity: 1;
-}
-
.bg-gradient {
background-image: var(--bs-gradient) !important;
}
@@ -11218,4 +10834,4 @@ textarea.form-control-lg {
}
}
-/*# sourceMappingURL=bootstrap.css.map */
+/*# sourceMappingURL=bootstrap.css.map */ \ No newline at end of file
diff --git a/src/static/scripts/datatables.css b/src/static/scripts/datatables.css
index db60b110..585f9390 100644
--- a/src/static/scripts/datatables.css
+++ b/src/static/scripts/datatables.css
@@ -4,13 +4,94 @@
*
* To rebuild or modify this file with the latest versions of the included
* software please visit:
- * https://datatables.net/download/#bs5/dt-1.10.25
+ * https://datatables.net/download/#bs5/dt-1.11.2
*
* Included libraries:
- * DataTables 1.10.25
+ * DataTables 1.11.2
*/
@charset "UTF-8";
+td.dt-control {
+ background: url("https://www.datatables.net/examples/resources/details_open.png") no-repeat center center;
+ cursor: pointer;
+}
+
+tr.dt-hasChild td.dt-control {
+ background: url("https://www.datatables.net/examples/resources/details_close.png") no-repeat center center;
+}
+
+table.dataTable th.dt-left,
+table.dataTable td.dt-left {
+ text-align: left;
+}
+table.dataTable th.dt-center,
+table.dataTable td.dt-center,
+table.dataTable td.dataTables_empty {
+ text-align: center;
+}
+table.dataTable th.dt-right,
+table.dataTable td.dt-right {
+ text-align: right;
+}
+table.dataTable th.dt-justify,
+table.dataTable td.dt-justify {
+ text-align: justify;
+}
+table.dataTable th.dt-nowrap,
+table.dataTable td.dt-nowrap {
+ white-space: nowrap;
+}
+table.dataTable thead th.dt-head-left,
+table.dataTable thead td.dt-head-left,
+table.dataTable tfoot th.dt-head-left,
+table.dataTable tfoot td.dt-head-left {
+ text-align: left;
+}
+table.dataTable thead th.dt-head-center,
+table.dataTable thead td.dt-head-center,
+table.dataTable tfoot th.dt-head-center,
+table.dataTable tfoot td.dt-head-center {
+ text-align: center;
+}
+table.dataTable thead th.dt-head-right,
+table.dataTable thead td.dt-head-right,
+table.dataTable tfoot th.dt-head-right,
+table.dataTable tfoot td.dt-head-right {
+ text-align: right;
+}
+table.dataTable thead th.dt-head-justify,
+table.dataTable thead td.dt-head-justify,
+table.dataTable tfoot th.dt-head-justify,
+table.dataTable tfoot td.dt-head-justify {
+ text-align: justify;
+}
+table.dataTable thead th.dt-head-nowrap,
+table.dataTable thead td.dt-head-nowrap,
+table.dataTable tfoot th.dt-head-nowrap,
+table.dataTable tfoot td.dt-head-nowrap {
+ white-space: nowrap;
+}
+table.dataTable tbody th.dt-body-left,
+table.dataTable tbody td.dt-body-left {
+ text-align: left;
+}
+table.dataTable tbody th.dt-body-center,
+table.dataTable tbody td.dt-body-center {
+ text-align: center;
+}
+table.dataTable tbody th.dt-body-right,
+table.dataTable tbody td.dt-body-right {
+ text-align: right;
+}
+table.dataTable tbody th.dt-body-justify,
+table.dataTable tbody td.dt-body-justify {
+ text-align: justify;
+}
+table.dataTable tbody th.dt-body-nowrap,
+table.dataTable tbody td.dt-body-nowrap {
+ white-space: nowrap;
+}
+
/*! Bootstrap 5 integration for DataTables
*
* ©2020 SpryMedia Ltd, all rights reserved.
@@ -143,21 +224,21 @@ div.dataTables_scrollHead table.dataTable {
margin-bottom: 0 !important;
}
-div.dataTables_scrollBody table {
+div.dataTables_scrollBody > table {
border-top: none;
margin-top: 0 !important;
margin-bottom: 0 !important;
}
-div.dataTables_scrollBody table thead .sorting:before,
-div.dataTables_scrollBody table thead .sorting_asc:before,
-div.dataTables_scrollBody table thead .sorting_desc:before,
-div.dataTables_scrollBody table thead .sorting:after,
-div.dataTables_scrollBody table thead .sorting_asc:after,
-div.dataTables_scrollBody table thead .sorting_desc:after {
+div.dataTables_scrollBody > table > thead .sorting:before,
+div.dataTables_scrollBody > table > thead .sorting_asc:before,
+div.dataTables_scrollBody > table > thead .sorting_desc:before,
+div.dataTables_scrollBody > table > thead .sorting:after,
+div.dataTables_scrollBody > table > thead .sorting_asc:after,
+div.dataTables_scrollBody > table > thead .sorting_desc:after {
display: none;
}
-div.dataTables_scrollBody table tbody tr:first-child th,
-div.dataTables_scrollBody table tbody tr:first-child td {
+div.dataTables_scrollBody > table > tbody tr:first-child th,
+div.dataTables_scrollBody > table > tbody tr:first-child td {
border-top: none;
}
@@ -235,4 +316,11 @@ div.table-responsive > div.dataTables_wrapper > div.row > div[class^=col-]:last-
padding-right: 0;
}
+table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1) {
+ --bs-table-accent-bg: transparent;
+}
+table.dataTable.table-striped > tbody > tr.odd {
+ --bs-table-accent-bg: var(--bs-table-striped-bg);
+}
+
diff --git a/src/static/scripts/datatables.js b/src/static/scripts/datatables.js
index f8f1f3d2..93bbe80b 100644
--- a/src/static/scripts/datatables.js
+++ b/src/static/scripts/datatables.js
@@ -4,20 +4,20 @@
*
* To rebuild or modify this file with the latest versions of the included
* software please visit:
- * https://datatables.net/download/#bs5/dt-1.10.25
+ * https://datatables.net/download/#bs5/dt-1.11.2
*
* Included libraries:
- * DataTables 1.10.25
+ * DataTables 1.11.2
*/
-/*! DataTables 1.10.25
+/*! DataTables 1.11.2
* ©2008-2021 SpryMedia Ltd - datatables.net/license
*/
/**
* @summary DataTables
* @description Paginate, search and order HTML tables
- * @version 1.10.25
+ * @version 1.11.2
* @file jquery.dataTables.js
* @author SpryMedia Ltd
* @contact www.datatables.net
@@ -65,7 +65,7 @@
}
else {
// Browser
- factory( jQuery, window, document );
+ window.DataTable = factory( jQuery, window, document );
}
}
(function( $, window, document, undefined ) {
@@ -103,8 +103,17 @@
* } );
* } );
*/
- var DataTable = function ( options )
+ var DataTable = function ( selector, options )
{
+ // When creating with `new`, create a new DataTable, returning the API instance
+ if (this instanceof DataTable) {
+ return $(selector).DataTable(options);
+ }
+ else {
+ // Argument switching
+ options = selector;
+ }
+
/**
* Perform a jQuery selector action on the table's TR elements (from the tbody) and
* return the resulting jQuery object.
@@ -1097,8 +1106,8 @@
dataType: 'json',
url: oLanguage.sUrl,
success: function ( json ) {
- _fnLanguageCompat( json );
_fnCamelToHungarian( defaults.oLanguage, json );
+ _fnLanguageCompat( json );
$.extend( true, oLanguage, json );
_fnCallbackFire( oSettings, null, 'i18n', [oSettings]);
@@ -1313,10 +1322,11 @@
};
/* Must be done after everything which can be overridden by the state saving! */
+ _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
+
if ( oInit.bStateSave )
{
features.bStateSave = true;
- _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
_fnLoadState( oSettings, oInit, loadedInit );
}
else {
@@ -1687,6 +1697,227 @@
*/
escapeRegex: function ( val ) {
return val.replace( _re_escape_regex, '\\$1' );
+ },
+
+ /**
+ * Create a function that will write to a nested object or array
+ * @param {*} source JSON notation string
+ * @returns Write function
+ */
+ set: function ( source ) {
+ if ( $.isPlainObject( source ) ) {
+ /* Unlike get, only the underscore (global) option is used for for
+ * setting data since we don't know the type here. This is why an object
+ * option is not documented for `mData` (which is read/write), but it is
+ * for `mRender` which is read only.
+ */
+ return DataTable.util.set( source._ );
+ }
+ else if ( source === null ) {
+ // Nothing to do when the data source is null
+ return function () {};
+ }
+ else if ( typeof source === 'function' ) {
+ return function (data, val, meta) {
+ source( data, 'set', val, meta );
+ };
+ }
+ else if ( typeof source === 'string' && (source.indexOf('.') !== -1 ||
+ source.indexOf('[') !== -1 || source.indexOf('(') !== -1) )
+ {
+ // Like the get, we need to get data from a nested object
+ var setData = function (data, val, src) {
+ var a = _fnSplitObjNotation( src ), b;
+ var aLast = a[a.length-1];
+ var arrayNotation, funcNotation, o, innerSrc;
+
+ for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ ) {
+ // Protect against prototype pollution
+ if (a[i] === '__proto__' || a[i] === 'constructor') {
+ throw new Error('Cannot set prototype values');
+ }
+
+ // Check if we are dealing with an array notation request
+ arrayNotation = a[i].match(__reArray);
+ funcNotation = a[i].match(__reFn);
+
+ if ( arrayNotation ) {
+ a[i] = a[i].replace(__reArray, '');
+ data[ a[i] ] = [];
+
+ // Get the remainder of the nested object to set so we can recurse
+ b = a.slice();
+ b.splice( 0, i+1 );
+ innerSrc = b.join('.');
+
+ // Traverse each entry in the array setting the properties requested
+ if ( Array.isArray( val ) ) {
+ for ( var j=0, jLen=val.length ; j<jLen ; j++ ) {
+ o = {};
+ setData( o, val[j], innerSrc );
+ data[ a[i] ].push( o );
+ }
+ }
+ else {
+ // We've been asked to save data to an array, but it
+ // isn't array data to be saved. Best that can be done
+ // is to just save the value.
+ data[ a[i] ] = val;
+ }
+
+ // The inner call to setData has already traversed through the remainder
+ // of the source and has set the data, thus we can exit here
+ return;
+ }
+ else if ( funcNotation ) {
+ // Function call
+ a[i] = a[i].replace(__reFn, '');
+ data = data[ a[i] ]( val );
+ }
+
+ // If the nested object doesn't currently exist - since we are
+ // trying to set the value - create it
+ if ( data[ a[i] ] === null || data[ a[i] ] === undefined ) {
+ data[ a[i] ] = {};
+ }
+ data = data[ a[i] ];
+ }
+
+ // Last item in the input - i.e, the actual set
+ if ( aLast.match(__reFn ) ) {
+ // Function call
+ data = data[ aLast.replace(__reFn, '') ]( val );
+ }
+ else {
+ // If array notation is used, we just want to strip it and use the property name
+ // and assign the value. If it isn't used, then we get the result we want anyway
+ data[ aLast.replace(__reArray, '') ] = val;
+ }
+ };
+
+ return function (data, val) { // meta is also passed in, but not used
+ return setData( data, val, source );
+ };
+ }
+ else {
+ // Array or flat object mapping
+ return function (data, val) { // meta is also passed in, but not used
+ data[source] = val;
+ };
+ }
+ },
+
+ /**
+ * Create a function that will read nested objects from arrays, based on JSON notation
+ * @param {*} source JSON notation string
+ * @returns Value read
+ */
+ get: function ( source ) {
+ if ( $.isPlainObject( source ) ) {
+ // Build an object of get functions, and wrap them in a single call
+ var o = {};
+ $.each( source, function (key, val) {
+ if ( val ) {
+ o[key] = DataTable.util.get( val );
+ }
+ } );
+
+ return function (data, type, row, meta) {
+ var t = o[type] || o._;
+ return t !== undefined ?
+ t(data, type, row, meta) :
+ data;
+ };
+ }
+ else if ( source === null ) {
+ // Give an empty string for rendering / sorting etc
+ return function (data) { // type, row and meta also passed, but not used
+ return data;
+ };
+ }
+ else if ( typeof source === 'function' ) {
+ return function (data, type, row, meta) {
+ return source( data, type, row, meta );
+ };
+ }
+ else if ( typeof source === 'string' && (source.indexOf('.') !== -1 ||
+ source.indexOf('[') !== -1 || source.indexOf('(') !== -1) )
+ {
+ /* If there is a . in the source string then the data source is in a
+ * nested object so we loop over the data for each level to get the next
+ * level down. On each loop we test for undefined, and if found immediately
+ * return. This allows entire objects to be missing and sDefaultContent to
+ * be used if defined, rather than throwing an error
+ */
+ var fetchData = function (data, type, src) {
+ var arrayNotation, funcNotation, out, innerSrc;
+
+ if ( src !== "" ) {
+ var a = _fnSplitObjNotation( src );
+
+ for ( var i=0, iLen=a.length ; i<iLen ; i++ ) {
+ // Check if we are dealing with special notation
+ arrayNotation = a[i].match(__reArray);
+ funcNotation = a[i].match(__reFn);
+
+ if ( arrayNotation ) {
+ // Array notation
+ a[i] = a[i].replace(__reArray, '');
+
+ // Condition allows simply [] to be passed in
+ if ( a[i] !== "" ) {
+ data = data[ a[i] ];
+ }
+ out = [];
+
+ // Get the remainder of the nested object to get
+ a.splice( 0, i+1 );
+ innerSrc = a.join('.');
+
+ // Traverse each entry in the array getting the properties requested
+ if ( Array.isArray( data ) ) {
+ for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
+ out.push( fetchData( data[j], type, innerSrc ) );
+ }
+ }
+
+ // If a string is given in between the array notation indicators, that
+ // is used to join the strings together, otherwise an array is returned
+ var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
+ data = (join==="") ? out : out.join(join);
+
+ // The inner call to fetchData has already traversed through the remainder
+ // of the source requested, so we exit from the loop
+ break;
+ }
+ else if ( funcNotation ) {
+ // Function call
+ a[i] = a[i].replace(__reFn, '');
+ data = data[ a[i] ]();
+ continue;
+ }
+
+ if ( data === null || data[ a[i] ] === undefined ) {
+ return undefined;
+ }
+
+ data = data[ a[i] ];
+ }
+ }
+
+ return data;
+ };
+
+ return function (data, type) { // row and meta also passed, but not used
+ return fetchData( data, type, source );
+ };
+ }
+ else {
+ // Array or flat object mapping
+ return function (data, type) { // row and meta also passed, but not used
+ return data[source];
+ };
+ }
}
};
@@ -2201,7 +2432,7 @@
/**
- * Covert the index of a visible column to the index in the data array (take account
+ * Convert the index of a visible column to the index in the data array (take account
* of hidden columns)
* @param {object} oSettings dataTables settings object
* @param {int} iMatch Visible column index to lookup
@@ -2219,7 +2450,7 @@
/**
- * Covert the index of an index in the data array and convert it to the visible
+ * Convert the index of an index in the data array and convert it to the visible
* column index (take account of hidden columns)
* @param {int} iMatch Column index to lookup
* @param {object} oSettings dataTables settings object
@@ -2533,12 +2764,19 @@
* @param {object} settings dataTables settings object
* @param {int} rowIdx aoData row id
* @param {int} colIdx Column index
- * @param {string} type data get type ('display', 'type' 'filter' 'sort')
+ * @param {string} type data get type ('display', 'type' 'filter|search' 'sort|order')
* @returns {*} Cell data
* @memberof DataTable#oApi
*/
function _fnGetCellData( settings, rowIdx, colIdx, type )
{
+ if (type === 'search') {
+ type = 'filter';
+ }
+ else if (type === 'order') {
+ type = 'sort';
+ }
+
var draw = settings.iDraw;
var col = settings.aoColumns[colIdx];
var rowData = settings.aoData[rowIdx]._aData;
@@ -2622,122 +2860,7 @@
* @returns {function} Data get function
* @memberof DataTable#oApi
*/
- function _fnGetObjectDataFn( mSource )
- {
- if ( $.isPlainObject( mSource ) )
- {
- /* Build an object of get functions, and wrap them in a single call */
- var o = {};
- $.each( mSource, function (key, val) {
- if ( val ) {
- o[key] = _fnGetObjectDataFn( val );
- }
- } );
-
- return function (data, type, row, meta) {
- var t = o[type] || o._;
- return t !== undefined ?
- t(data, type, row, meta) :
- data;
- };
- }
- else if ( mSource === null )
- {
- /* Give an empty string for rendering / sorting etc */
- return function (data) { // type, row and meta also passed, but not used
- return data;
- };
- }
- else if ( typeof mSource === 'function' )
- {
- return function (data, type, row, meta) {
- return mSource( data, type, row, meta );
- };
- }
- else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
- {
- /* If there is a . in the source string then the data source is in a
- * nested object so we loop over the data for each level to get the next
- * level down. On each loop we test for undefined, and if found immediately
- * return. This allows entire objects to be missing and sDefaultContent to
- * be used if defined, rather than throwing an error
- */
- var fetchData = function (data, type, src) {
- var arrayNotation, funcNotation, out, innerSrc;
-
- if ( src !== "" )
- {
- var a = _fnSplitObjNotation( src );
-
- for ( var i=0, iLen=a.length ; i<iLen ; i++ )
- {
- // Check if we are dealing with special notation
- arrayNotation = a[i].match(__reArray);
- funcNotation = a[i].match(__reFn);
-
- if ( arrayNotation )
- {
- // Array notation
- a[i] = a[i].replace(__reArray, '');
-
- // Condition allows simply [] to be passed in
- if ( a[i] !== "" ) {
- data = data[ a[i] ];
- }
- out = [];
-
- // Get the remainder of the nested object to get
- a.splice( 0, i+1 );
- innerSrc = a.join('.');
-
- // Traverse each entry in the array getting the properties requested
- if ( Array.isArray( data ) ) {
- for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
- out.push( fetchData( data[j], type, innerSrc ) );
- }
- }
-
- // If a string is given in between the array notation indicators, that
- // is used to join the strings together, otherwise an array is returned
- var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
- data = (join==="") ? out : out.join(join);
-
- // The inner call to fetchData has already traversed through the remainder
- // of the source requested, so we exit from the loop
- break;
- }
- else if ( funcNotation )
- {
- // Function call
- a[i] = a[i].replace(__reFn, '');
- data = data[ a[i] ]();
- continue;
- }
-
- if ( data === null || data[ a[i] ] === undefined )
- {
- return undefined;
- }
- data = data[ a[i] ];
- }
- }
-
- return data;
- };
-
- return function (data, type) { // row and meta also passed, but not used
- return fetchData( data, type, mSource );
- };
- }
- else
- {
- /* Array or flat object mapping */
- return function (data, type) { // row and meta also passed, but not used
- return data[mSource];
- };
- }
- }
+ var _fnGetObjectDataFn = DataTable.util.get;
/**
@@ -2747,122 +2870,7 @@
* @returns {function} Data set function
* @memberof DataTable#oApi
*/
- function _fnSetObjectDataFn( mSource )
- {
- if ( $.isPlainObject( mSource ) )
- {
- /* Unlike get, only the underscore (global) option is used for for
- * setting data since we don't know the type here. This is why an object
- * option is not documented for `mData` (which is read/write), but it is
- * for `mRender` which is read only.
- */
- return _fnSetObjectDataFn( mSource._ );
- }
- else if ( mSource === null )
- {
- /* Nothing to do when the data source is null */
- return function () {};
- }
- else if ( typeof mSource === 'function' )
- {
- return function (data, val, meta) {
- mSource( data, 'set', val, meta );
- };
- }
- else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
- {
- /* Like the get, we need to get data from a nested object */
- var setData = function (data, val, src) {
- var a = _fnSplitObjNotation( src ), b;
- var aLast = a[a.length-1];
- var arrayNotation, funcNotation, o, innerSrc;
-
- for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
- {
- // Protect against prototype pollution
- if (a[i] === '__proto__' || a[i] === 'constructor') {
- throw new Error('Cannot set prototype values');
- }
-
- // Check if we are dealing with an array notation request
- arrayNotation = a[i].match(__reArray);
- funcNotation = a[i].match(__reFn);
-
- if ( arrayNotation )
- {
- a[i] = a[i].replace(__reArray, '');
- data[ a[i] ] = [];
-
- // Get the remainder of the nested object to set so we can recurse
- b = a.slice();
- b.splice( 0, i+1 );
- innerSrc = b.join('.');
-
- // Traverse each entry in the array setting the properties requested
- if ( Array.isArray( val ) )
- {
- for ( var j=0, jLen=val.length ; j<jLen ; j++ )
- {
- o = {};
- setData( o, val[j], innerSrc );
- data[ a[i] ].push( o );
- }
- }
- else
- {
- // We've been asked to save data to an array, but it
- // isn't array data to be saved. Best that can be done
- // is to just save the value.
- data[ a[i] ] = val;
- }
-
- // The inner call to setData has already traversed through the remainder
- // of the source and has set the data, thus we can exit here
- return;
- }
- else if ( funcNotation )
- {
- // Function call
- a[i] = a[i].replace(__reFn, '');
- data = data[ a[i] ]( val );
- }
-
- // If the nested object doesn't currently exist - since we are
- // trying to set the value - create it
- if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
- {
- data[ a[i] ] = {};
- }
- data = data[ a[i] ];
- }
-
- // Last item in the input - i.e, the actual set
- if ( aLast.match(__reFn ) )
- {
- // Function call
- data = data[ aLast.replace(__reFn, '') ]( val );
- }
- else
- {
- // If array notation is used, we just want to strip it and use the property name
- // and assign the value. If it isn't used, then we get the result we want anyway
- data[ aLast.replace(__reArray, '') ] = val;
- }
- };
-
- return function (data, val) { // meta is also passed in, but not used
- return setData( data, val, mSource );
- };
- }
- else
- {
- /* Array or flat object mapping */
- return function (data, val) { // meta is also passed in, but not used
- data[mSource] = val;
- };
- }
- }
+ var _fnSetObjectDataFn = DataTable.util.set;
/**
@@ -3291,9 +3299,6 @@
if ( createHeader ) {
_fnDetectHeader( oSettings.aoHeader, thead );
}
-
- /* ARIA role for the rows */
- $(thead).children('tr').attr('role', 'row');
/* Deal with the footer - add classes if required */
$(thead).children('tr').children('th, td').addClass( classes.sHeaderTH );
@@ -3912,6 +3917,22 @@
var ajax = oSettings.ajax;
var instance = oSettings.oInstance;
var callback = function ( json ) {
+ var status = oSettings.jqXhr
+ ? oSettings.jqXhr.status
+ : null;
+
+ if ( json === null || (typeof status === 'number' && status == 204 ) ) {
+ json = {};
+ _fnAjaxDataSrc( oSettings, json, [] );
+ }
+
+ var error = json.error || json.sError;
+ if ( error ) {
+ _fnLog( oSettings, 0, error );
+ }
+
+ oSettings.json = json;
+
_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
fn( json );
};
@@ -3936,15 +3957,7 @@
var baseAjax = {
"data": data,
- "success": function (json) {
- var error = json.error || json.sError;
- if ( error ) {
- _fnLog( oSettings, 0, error );
- }
-
- oSettings.json = json;
- callback( json );
- },
+ "success": callback,
"dataType": "json",
"cache": false,
"type": oSettings.sServerMethod,
@@ -4166,6 +4179,11 @@
settings.iDraw = draw * 1;
}
+ // No data in returned object, so rather than an array, we show an empty table
+ if ( ! data ) {
+ data = [];
+ }
+
_fnClearTable( settings );
settings._iRecordsTotal = parseInt(recordsTotal, 10);
settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
@@ -4193,21 +4211,26 @@
* @param {object} json Data source object / array from the server
* @return {array} Array of data to use
*/
- function _fnAjaxDataSrc ( oSettings, json )
- {
+ function _fnAjaxDataSrc ( oSettings, json, write )
+ {
var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
oSettings.ajax.dataSrc :
oSettings.sAjaxDataProp; // Compatibility with 1.9-.
- // Compatibility with 1.9-. In order to read from aaData, check if the
- // default has been changed, if not, check for aaData
- if ( dataSrc === 'data' ) {
- return json.aaData || json[dataSrc];
+ if ( ! write ) {
+ if ( dataSrc === 'data' ) {
+ // If the default, then we still want to support the old style, and safely ignore
+ // it if possible
+ return json.aaData || json[dataSrc];
+ }
+
+ return dataSrc !== "" ?
+ _fnGetObjectDataFn( dataSrc )( json ) :
+ json;
}
- return dataSrc !== "" ?
- _fnGetObjectDataFn( dataSrc )( json ) :
- json;
+ // set
+ _fnSetObjectDataFn( dataSrc )( json, write );
}
/**
@@ -4236,18 +4259,21 @@
} )
.append( $('<label/>' ).append( str ) );
- var searchFn = function() {
+ var searchFn = function(event) {
/* Update all other filter input elements for the new display */
var n = features.f;
var val = !this.value ? "" : this.value; // mental IE8 fix :-(
-
+ if(previousSearch.return && event.key !== "Enter") {
+ return;
+ }
/* Now do the filter */
if ( val != previousSearch.sSearch ) {
_fnFilterComplete( settings, {
"sSearch": val,
"bRegex": previousSearch.bRegex,
"bSmart": previousSearch.bSmart ,
- "bCaseInsensitive": previousSearch.bCaseInsensitive
+ "bCaseInsensitive": previousSearch.bCaseInsensitive,
+ "return": previousSearch.return
} );
// Need to redraw, without resorting
@@ -4276,7 +4302,7 @@
// on the clear icon (Edge bug 17584515). This is safe in other browsers as `searchFn`
// checks the value to see if it has changed. In other browsers it won't have.
setTimeout( function () {
- searchFn.call(jqFilter[0]);
+ searchFn.call(jqFilter[0], e);
}, 10);
} )
.on( 'keypress.DT', function(e) {
@@ -4322,6 +4348,7 @@
oPrevSearch.bRegex = oFilter.bRegex;
oPrevSearch.bSmart = oFilter.bSmart;
oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
+ oPrevSearch.return = oFilter.return;
};
var fnRegex = function ( o ) {
// Backwards compatibility with the bEscapeRegex option
@@ -4336,7 +4363,7 @@
if ( _fnDataSource( oSettings ) != 'ssp' )
{
/* Global filter */
- _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
+ _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive, oInput.return );
fnSaveFilter( oInput );
/* Now do the individual column filter */
@@ -4399,7 +4426,7 @@
* @param {int} iColumn column to filter
* @param {bool} bRegex treat search string as a regular expression or not
* @param {bool} bSmart use smart filtering or not
- * @param {bool} bCaseInsensitive Do case insenstive matching or not
+ * @param {bool} bCaseInsensitive Do case insensitive matching or not
* @memberof DataTable#oApi
*/
function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
@@ -4432,7 +4459,7 @@
* @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
* @param {bool} regex treat as a regular expression or not
* @param {bool} smart perform smart filtering or not
- * @param {bool} caseInsensitive Do case insenstive matching or not
+ * @param {bool} caseInsensitive Do case insensitive matching or not
* @memberof DataTable#oApi
*/
function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
@@ -5093,9 +5120,6 @@
{
var table = $(settings.nTable);
- // Add the ARIA grid role to the table
- table.attr( 'role', 'grid' );
-
// Scrolling from here on in
var scroll = settings.oScroll;
@@ -5383,17 +5407,17 @@
// Read all widths in next pass
_fnApplyToChildren( function(nSizer) {
+ var style = window.getComputedStyle ?
+ window.getComputedStyle(nSizer).width :
+ _fnStringToCss( $(nSizer).width() );
+
headerContent.push( nSizer.innerHTML );
- headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
+ headerWidths.push( style );
}, headerSrcEls );
// Apply all widths in final pass
_fnApplyToChildren( function(nToSize, i) {
- // Only apply widths to the DataTables detected header cells - this
- // prevents complex headers from having contradictory sizes applied
- if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
- nToSize.style.width = headerWidths[i];
- }
+ nToSize.style.width = headerWidths[i];
}, headerTrgEls );
$(headerSrcEls).height(0);
@@ -6350,11 +6374,6 @@
*/
function _fnSaveState ( settings )
{
- if ( !settings.oFeatures.bStateSave || settings.bDestroying )
- {
- return;
- }
-
/* Store the interesting variables */
var state = {
time: +new Date(),
@@ -6370,10 +6389,13 @@
} )
};
- _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
-
settings.oSavedState = state;
- settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
+ _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
+
+ if ( settings.oFeatures.bStateSave && !settings.bDestroying )
+ {
+ settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
+ }
}
@@ -7872,7 +7894,7 @@
_range( 0, displayMaster.length );
}
else if ( page == 'current' ) {
- // Current page implies that order=current and fitler=applied, since it is
+ // Current page implies that order=current and filter=applied, since it is
// fairly senseless otherwise, regardless of what order and search actually
// are
for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
@@ -8253,6 +8275,24 @@
} );
+ $(document).on('plugin-init.dt', function (e, context) {
+ var api = new _Api( context );
+ api.on( 'stateSaveParams', function ( e, settings, data ) {
+ var indexes = api.rows().iterator( 'row', function ( settings, idx ) {
+ return settings.aoData[idx]._detailsShow ? idx : undefined;
+ });
+
+ data.childRows = api.rows( indexes ).ids( true ).toArray();
+ })
+
+ var loaded = api.state.loaded();
+
+ if ( loaded && loaded.childRows ) {
+ api.rows( loaded.childRows ).every( function () {
+ _fnCallbackFire( context, null, 'requestChild', [ this ] )
+ })
+ }
+ })
var __details_add = function ( ctx, row, data, klass )
{
@@ -8311,6 +8351,8 @@
row._detailsShow = undefined;
row._details = undefined;
+ $( row.nTr ).removeClass( 'dt-hasChild' );
+ _fnSaveState( ctx[0] );
}
}
};
@@ -8327,12 +8369,17 @@
if ( show ) {
row._details.insertAfter( row.nTr );
+ $( row.nTr ).addClass( 'dt-hasChild' );
}
else {
row._details.detach();
+ $( row.nTr ).removeClass( 'dt-hasChild' );
}
+ _fnCallbackFire( ctx[0], null, 'childRow', [ show, api.row( api[0] ) ] )
+
__details_events( ctx[0] );
+ _fnSaveState( ctx[0] );
}
}
};
@@ -9543,7 +9590,7 @@
* @type string
* @default Version number
*/
- DataTable.version = "1.10.25";
+ DataTable.version = "1.11.2";
/**
* Private data store, containing all of the settings objects that are
@@ -9603,7 +9650,15 @@
* @type boolean
* @default true
*/
- "bSmart": true
+ "bSmart": true,
+
+ /**
+ * Flag to indicate if DataTables should only trigger a search when
+ * the return key is pressed.
+ * @type boolean
+ * @default false
+ */
+ "return": false
};
@@ -12499,7 +12554,7 @@
* "data": function ( source, type, val ) {
* if (type === 'set') {
* source.price = val;
- * // Store the computed dislay and filter values for efficiency
+ * // Store the computed display and filter values for efficiency
* source.price_display = val=="" ? "" : "$"+numberFormat(val);
* source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
* return;
@@ -13048,7 +13103,7 @@
* Delay the creation of TR and TD elements until they are actually
* needed by a driven page draw. This can give a significant speed
* increase for Ajax source and Javascript source data, but makes no
- * difference at all fro DOM and server-side processing tables.
+ * difference at all for DOM and server-side processing tables.
* Note that this parameter will be set by the initialisation routine. To
* set a default use {@link DataTable.defaults}.
* @type boolean
@@ -13960,7 +14015,7 @@
*
* @type string
*/
- build:"bs5/dt-1.10.25",
+ build:"bs5/dt-1.11.2",
/**
@@ -14406,7 +14461,7 @@
//
// Depreciated
- // The following properties are retained for backwards compatiblity only.
+ // The following properties are retained for backwards compatibility only.
// The should not be used in new projects and will be removed in a future
// version
//
@@ -15226,170 +15281,7 @@
$.fn.DataTable[ prop ] = val;
} );
-
- // Information about events fired by DataTables - for documentation.
- /**
- * Draw event, fired whenever the table is redrawn on the page, at the same
- * point as fnDrawCallback. This may be useful for binding events or
- * performing calculations when the table is altered at all.
- * @name DataTable#draw.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- */
-
- /**
- * Search event, fired when the searching applied to the table (using the
- * built-in global search, or column filters) is altered.
- * @name DataTable#search.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- */
-
- /**
- * Page change event, fired when the paging of the table is altered.
- * @name DataTable#page.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- */
-
- /**
- * Order event, fired when the ordering applied to the table is altered.
- * @name DataTable#order.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- */
-
- /**
- * DataTables initialisation complete event, fired when the table is fully
- * drawn, including Ajax data loaded, if Ajax data is required.
- * @name DataTable#init.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} oSettings DataTables settings object
- * @param {object} json The JSON object request from the server - only
- * present if client-side Ajax sourced data is used</li></ol>
- */
-
- /**
- * State save event, fired when the table has changed state a new state save
- * is required. This event allows modification of the state saving object
- * prior to actually doing the save, including addition or other state
- * properties (for plug-ins) or modification of a DataTables core property.
- * @name DataTable#stateSaveParams.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} oSettings DataTables settings object
- * @param {object} json The state information to be saved
- */
-
- /**
- * State load event, fired when the table is loading state from the stored
- * data, but prior to the settings object being modified by the saved state
- * - allowing modification of the saved state is required or loading of
- * state for a plug-in.
- * @name DataTable#stateLoadParams.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} oSettings DataTables settings object
- * @param {object} json The saved state information
- */
-
- /**
- * State loaded event, fired when state has been loaded from stored data and
- * the settings object has been modified by the loaded data.
- * @name DataTable#stateLoaded.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} oSettings DataTables settings object
- * @param {object} json The saved state information
- */
-
- /**
- * Processing event, fired when DataTables is doing some kind of processing
- * (be it, order, search or anything else). It can be used to indicate to
- * the end user that there is something happening, or that something has
- * finished.
- * @name DataTable#processing.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} oSettings DataTables settings object
- * @param {boolean} bShow Flag for if DataTables is doing processing or not
- */
-
- /**
- * Ajax (XHR) event, fired whenever an Ajax request is completed from a
- * request to made to the server for new data. This event is called before
- * DataTables processed the returned data, so it can also be used to pre-
- * process the data returned from the server, if needed.
- *
- * Note that this trigger is called in `fnServerData`, if you override
- * `fnServerData` and which to use this event, you need to trigger it in you
- * success function.
- * @name DataTable#xhr.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- * @param {object} json JSON returned from the server
- *
- * @example
- * // Use a custom property returned from the server in another DOM element
- * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
- * $('#status').html( json.status );
- * } );
- *
- * @example
- * // Pre-process the data returned from the server
- * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
- * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
- * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
- * }
- * // Note no return - manipulate the data directly in the JSON object.
- * } );
- */
-
- /**
- * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
- * or passing the bDestroy:true parameter in the initialisation object. This
- * can be used to remove bound events, added DOM nodes, etc.
- * @name DataTable#destroy.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- */
-
- /**
- * Page length change event, fired when number of records to show on each
- * page (the length) is changed.
- * @name DataTable#length.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- * @param {integer} len New length
- */
-
- /**
- * Column sizing has changed.
- * @name DataTable#column-sizing.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- */
-
- /**
- * Column visibility has changed.
- * @name DataTable#column-visibility.dt
- * @event
- * @param {event} e jQuery event object
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
- * @param {int} column Column index
- * @param {bool} vis `false` if column now hidden, or `true` if visible
- */
-
- return $.fn.dataTable;
+ return DataTable;
}));
diff --git a/src/static/templates/admin/settings.hbs b/src/static/templates/admin/settings.hbs
index 03a1575e..b257326b 100644
--- a/src/static/templates/admin/settings.hbs
+++ b/src/static/templates/admin/settings.hbs
@@ -12,9 +12,7 @@
{{#each config}}
{{#if groupdoc}}
<div class="card bg-light mb-3">
- <div class="card-header" role="button" data-bs-toggle="collapse" data-bs-target="#g_{{group}}">
- <button type="button" class="btn btn-link text-decoration-none collapsed" data-bs-toggle="collapse" data-bs-target="#g_{{group}}">{{groupdoc}}</button>
- </div>
+ <button id="b_{{group}}" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_{{group}}" data-bs-toggle="collapse" data-bs-target="#g_{{group}}">{{groupdoc}}</button>
<div id="g_{{group}}" class="card-body collapse">
{{#each elements}}
{{#if editable}}
@@ -61,10 +59,8 @@
{{/each}}
<div class="card bg-light mb-3">
- <div class="card-header" role="button" data-bs-toggle="collapse" data-bs-target="#g_readonly">
- <button type="button" class="btn btn-link text-decoration-none collapsed" data-bs-toggle="collapse" data-bs-target="#g_readonly">Read-Only Config</button>
- </div>
-
+ <button id="b_readonly" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_readonly"
+ data-bs-toggle="collapse" data-bs-target="#g_readonly">Read-Only Config</button>
<div id="g_readonly" class="card-body collapse">
<div class="small mb-3">
NOTE: These options can't be modified in the editor because they would require the server
@@ -109,9 +105,8 @@
{{#if can_backup}}
<div class="card bg-light mb-3">
- <div class="card-header" role="button" data-bs-toggle="collapse" data-bs-target="#g_database">
- <button type="button" class="btn btn-link text-decoration-none collapsed" data-bs-toggle="collapse" data-bs-target="#g_database">Backup Database</button>
- </div>
+ <button id="b_database" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_database"
+ data-bs-toggle="collapse" data-bs-target="#g_database">Backup Database</button>
<div id="g_database" class="card-body collapse">
<div class="small mb-3">
WARNING: This function only creates a backup copy of the SQLite database.