Procházet zdrojové kódy

Merge pull request #4925 from tomudding/fix/datatables-crashing-with-non-english-locale

[WEB] Update DataTables to v1.13.1 and fix crash for non-English locales
Niklas Meyer před 2 roky
rodič
revize
850fd85d4d
2 změnil soubory, kde provedl 267 přidání a 186 odebrání
  1. 26 32
      data/web/css/build/011-datatables.css
  2. 241 154
      data/web/js/build/004-datatables.js

+ 26 - 32
data/web/css/build/011-datatables.css

@@ -4,10 +4,10 @@
  *
  *
  * To rebuild or modify this file with the latest versions of the included
  * To rebuild or modify this file with the latest versions of the included
  * software please visit:
  * software please visit:
- *   https://datatables.net/download/#bs5/dt-1.12.0/r-2.3.0/sl-1.4.0
+ *   https://datatables.net/download/#bs5/dt-1.13.1/r-2.4.0/sl-1.5.0
  *
  *
  * Included libraries:
  * Included libraries:
- *   DataTables 1.12.0, Responsive 2.3.0, Select 1.4.0
+ *   DataTables 1.13.1, Responsive 2.4.0, Select 1.5.0
  */
  */
 
 
 @charset "UTF-8";
 @charset "UTF-8";
@@ -63,7 +63,7 @@ table.dataTable thead > tr > td.sorting_desc_disabled:after {
   opacity: 0.125;
   opacity: 0.125;
   right: 10px;
   right: 10px;
   line-height: 9px;
   line-height: 9px;
-  font-size: 0.9em;
+  font-size: 0.8em;
 }
 }
 table.dataTable thead > tr > th.sorting:before, table.dataTable thead > tr > th.sorting_asc:before, table.dataTable thead > tr > th.sorting_desc:before, table.dataTable thead > tr > th.sorting_asc_disabled:before, table.dataTable thead > tr > th.sorting_desc_disabled:before,
 table.dataTable thead > tr > th.sorting:before, table.dataTable thead > tr > th.sorting_asc:before, table.dataTable thead > tr > th.sorting_desc:before, table.dataTable thead > tr > th.sorting_asc_disabled:before, table.dataTable thead > tr > th.sorting_desc_disabled:before,
 table.dataTable thead > tr > td.sorting:before,
 table.dataTable thead > tr > td.sorting:before,
@@ -72,7 +72,7 @@ table.dataTable thead > tr > td.sorting_desc:before,
 table.dataTable thead > tr > td.sorting_asc_disabled:before,
 table.dataTable thead > tr > td.sorting_asc_disabled:before,
 table.dataTable thead > tr > td.sorting_desc_disabled:before {
 table.dataTable thead > tr > td.sorting_desc_disabled:before {
   bottom: 50%;
   bottom: 50%;
-  content: "";
+  content: "";
 }
 }
 table.dataTable thead > tr > th.sorting:after, table.dataTable thead > tr > th.sorting_asc:after, table.dataTable thead > tr > th.sorting_desc:after, table.dataTable thead > tr > th.sorting_asc_disabled:after, table.dataTable thead > tr > th.sorting_desc_disabled:after,
 table.dataTable thead > tr > th.sorting:after, table.dataTable thead > tr > th.sorting_asc:after, table.dataTable thead > tr > th.sorting_desc:after, table.dataTable thead > tr > th.sorting_asc_disabled:after, table.dataTable thead > tr > th.sorting_desc_disabled:after,
 table.dataTable thead > tr > td.sorting:after,
 table.dataTable thead > tr > td.sorting:after,
@@ -81,7 +81,7 @@ table.dataTable thead > tr > td.sorting_desc:after,
 table.dataTable thead > tr > td.sorting_asc_disabled:after,
 table.dataTable thead > tr > td.sorting_asc_disabled:after,
 table.dataTable thead > tr > td.sorting_desc_disabled:after {
 table.dataTable thead > tr > td.sorting_desc_disabled:after {
   top: 50%;
   top: 50%;
-  content: "";
+  content: "";
 }
 }
 table.dataTable thead > tr > th.sorting_asc:before, table.dataTable thead > tr > th.sorting_desc:after,
 table.dataTable thead > tr > th.sorting_asc:before, table.dataTable thead > tr > th.sorting_desc:after,
 table.dataTable thead > tr > td.sorting_asc:before,
 table.dataTable thead > tr > td.sorting_asc:before,
@@ -287,6 +287,9 @@ table.dataTable > tbody > tr.selected > * {
   box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.9);
   box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.9);
   color: white;
   color: white;
 }
 }
+table.dataTable > tbody > tr.selected a {
+  color: #090a0b;
+}
 table.dataTable.table-striped > tbody > tr.odd > * {
 table.dataTable.table-striped > tbody > tr.odd > * {
   box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.05);
   box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.05);
 }
 }
@@ -335,6 +338,9 @@ div.dataTables_wrapper div.dataTables_paginate ul.pagination {
   white-space: nowrap;
   white-space: nowrap;
   justify-content: flex-end;
   justify-content: flex-end;
 }
 }
+div.dataTables_wrapper div.dt-row {
+  position: relative;
+}
 
 
 div.dataTables_scrollHead table.dataTable {
 div.dataTables_scrollHead table.dataTable {
   margin-bottom: 0 !important;
   margin-bottom: 0 !important;
@@ -380,17 +386,6 @@ div.dataTables_wrapper div.dataTables_paginate {
 table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) {
 table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) {
   padding-right: 20px;
   padding-right: 20px;
 }
 }
-table.dataTable.table-sm .sorting:before,
-table.dataTable.table-sm .sorting_asc:before,
-table.dataTable.table-sm .sorting_desc:before {
-  top: 5px;
-  right: 0.85em;
-}
-table.dataTable.table-sm .sorting:after,
-table.dataTable.table-sm .sorting_asc:after,
-table.dataTable.table-sm .sorting_desc:after {
-  top: 5px;
-}
 
 
 table.table-bordered.dataTable {
 table.table-bordered.dataTable {
   border-right-width: 0;
   border-right-width: 0;
@@ -629,13 +624,13 @@ table.dataTable > tbody > tr > .selected {
   background-color: rgba(13, 110, 253, 0.9);
   background-color: rgba(13, 110, 253, 0.9);
   color: white;
   color: white;
 }
 }
-table.dataTable tbody td.select-checkbox,
-table.dataTable tbody th.select-checkbox {
+table.dataTable > tbody > tr > td.select-checkbox,
+table.dataTable > tbody > tr > th.select-checkbox {
   position: relative;
   position: relative;
 }
 }
-table.dataTable tbody td.select-checkbox:before, table.dataTable tbody td.select-checkbox:after,
-table.dataTable tbody th.select-checkbox:before,
-table.dataTable tbody th.select-checkbox:after {
+table.dataTable > tbody > tr > td.select-checkbox:before, table.dataTable > tbody > tr > td.select-checkbox:after,
+table.dataTable > tbody > tr > th.select-checkbox:before,
+table.dataTable > tbody > tr > th.select-checkbox:after {
   display: block;
   display: block;
   position: absolute;
   position: absolute;
   top: 1.2em;
   top: 1.2em;
@@ -644,20 +639,20 @@ table.dataTable tbody th.select-checkbox:after {
   height: 12px;
   height: 12px;
   box-sizing: border-box;
   box-sizing: border-box;
 }
 }
-table.dataTable tbody td.select-checkbox:before,
-table.dataTable tbody th.select-checkbox:before {
+table.dataTable > tbody > tr > td.select-checkbox:before,
+table.dataTable > tbody > tr > th.select-checkbox:before {
   content: " ";
   content: " ";
   margin-top: -5px;
   margin-top: -5px;
   margin-left: -6px;
   margin-left: -6px;
   border: 1px solid black;
   border: 1px solid black;
   border-radius: 3px;
   border-radius: 3px;
 }
 }
-table.dataTable tr.selected td.select-checkbox:before,
-table.dataTable tr.selected th.select-checkbox:before {
+table.dataTable > tbody > tr.selected > td.select-checkbox:before,
+table.dataTable > tbody > tr.selected > th.select-checkbox:before {
   border: 1px solid white;
   border: 1px solid white;
 }
 }
-table.dataTable tr.selected td.select-checkbox:after,
-table.dataTable tr.selected th.select-checkbox:after {
+table.dataTable > tbody > tr.selected > td.select-checkbox:after,
+table.dataTable > tbody > tr.selected > th.select-checkbox:after {
   content: "✓";
   content: "✓";
   font-size: 20px;
   font-size: 20px;
   margin-top: -19px;
   margin-top: -19px;
@@ -665,12 +660,12 @@ table.dataTable tr.selected th.select-checkbox:after {
   text-align: center;
   text-align: center;
   text-shadow: 1px 1px #B0BED9, -1px -1px #B0BED9, 1px -1px #B0BED9, -1px 1px #B0BED9;
   text-shadow: 1px 1px #B0BED9, -1px -1px #B0BED9, 1px -1px #B0BED9, -1px 1px #B0BED9;
 }
 }
-table.dataTable.compact tbody td.select-checkbox:before,
-table.dataTable.compact tbody th.select-checkbox:before {
+table.dataTable.compact > tbody > tr > td.select-checkbox:before,
+table.dataTable.compact > tbody > tr > th.select-checkbox:before {
   margin-top: -12px;
   margin-top: -12px;
 }
 }
-table.dataTable.compact tr.selected td.select-checkbox:after,
-table.dataTable.compact tr.selected th.select-checkbox:after {
+table.dataTable.compact > tbody > tr.selected > td.select-checkbox:after,
+table.dataTable.compact > tbody > tr.selected > th.select-checkbox:after {
   margin-top: -16px;
   margin-top: -16px;
 }
 }
 
 
@@ -690,4 +685,3 @@ table.dataTable.table-sm tbody td.select-checkbox::before {
   margin-top: -9px;
   margin-top: -9px;
 }
 }
 
 
-

+ 241 - 154
data/web/js/build/004-datatables.js

@@ -4,20 +4,20 @@
  *
  *
  * To rebuild or modify this file with the latest versions of the included
  * To rebuild or modify this file with the latest versions of the included
  * software please visit:
  * software please visit:
- *   https://datatables.net/download/#bs5/dt-1.12.0/r-2.3.0/sl-1.4.0
+ *   https://datatables.net/download/#bs5/dt-1.13.1/r-2.4.0/sl-1.5.0
  *
  *
  * Included libraries:
  * Included libraries:
- *   DataTables 1.12.0, Responsive 2.3.0, Select 1.4.0
+ *   DataTables 1.13.1, Responsive 2.4.0, Select 1.5.0
  */
  */
 
 
-/*! DataTables 1.12.0
+/*! DataTables 1.13.1
  * ©2008-2022 SpryMedia Ltd - datatables.net/license
  * ©2008-2022 SpryMedia Ltd - datatables.net/license
  */
  */
 
 
 /**
 /**
  * @summary     DataTables
  * @summary     DataTables
  * @description Paginate, search and order HTML tables
  * @description Paginate, search and order HTML tables
- * @version     1.12.0
+ * @version     1.13.1
  * @author      SpryMedia Ltd
  * @author      SpryMedia Ltd
  * @contact     www.datatables.net
  * @contact     www.datatables.net
  * @copyright   SpryMedia Ltd.
  * @copyright   SpryMedia Ltd.
@@ -1162,6 +1162,10 @@
 				$( rowOne[0] ).children('th, td').each( function (i, cell) {
 				$( rowOne[0] ).children('th, td').each( function (i, cell) {
 					var col = oSettings.aoColumns[i];
 					var col = oSettings.aoColumns[i];
 			
 			
+					if (! col) {
+						_fnLog( oSettings, 0, 'Incorrect column count', 18 );
+					}
+			
 					if ( col.mData === i ) {
 					if ( col.mData === i ) {
 						var sort = a( cell, 'sort' ) || a( cell, 'order' );
 						var sort = a( cell, 'sort' ) || a( cell, 'order' );
 						var filter = a( cell, 'filter' ) || a( cell, 'search' );
 						var filter = a( cell, 'filter' ) || a( cell, 'search' );
@@ -3166,6 +3170,11 @@
 				create = nTrIn ? false : true;
 				create = nTrIn ? false : true;
 	
 	
 				nTd = create ? document.createElement( oCol.sCellType ) : anTds[i];
 				nTd = create ? document.createElement( oCol.sCellType ) : anTds[i];
+	
+				if (! nTd) {
+					_fnLog( oSettings, 0, 'Incorrect column count', 18 );
+				}
+	
 				nTd._DT_CellIndex = {
 				nTd._DT_CellIndex = {
 					row: iRow,
 					row: iRow,
 					column: i
 					column: i
@@ -3316,10 +3325,16 @@
 	
 	
 			for ( i=0, ien=cells.length ; i<ien ; i++ ) {
 			for ( i=0, ien=cells.length ; i<ien ; i++ ) {
 				column = columns[i];
 				column = columns[i];
-				column.nTf = cells[i].cell;
 	
 	
-				if ( column.sClass ) {
-					$(column.nTf).addClass( column.sClass );
+				if (column) {
+					column.nTf = cells[i].cell;
+		
+					if ( column.sClass ) {
+						$(column.nTf).addClass( column.sClass );
+					}
+				}
+				else {
+					_fnLog( oSettings, 0, 'Incorrect column count', 18 );
 				}
 				}
 			}
 			}
 		}
 		}
@@ -5079,6 +5094,10 @@
 				_fnDraw( settings );
 				_fnDraw( settings );
 			}
 			}
 		}
 		}
+		else {
+			// No change event - paging was called, but no change
+			_fnCallbackFire( settings, null, 'page-nc', [settings] );
+		}
 	
 	
 		return changed;
 		return changed;
 	}
 	}
@@ -5348,6 +5367,7 @@
 			footerCopy = footer.clone().prependTo( table );
 			footerCopy = footer.clone().prependTo( table );
 			footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
 			footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
 			footerSrcEls = footerCopy.find('tr');
 			footerSrcEls = footerCopy.find('tr');
+			footerCopy.find('[id]').removeAttr('id');
 		}
 		}
 	
 	
 		// Clone the current header and footer elements and then place it into the inner table
 		// Clone the current header and footer elements and then place it into the inner table
@@ -5355,6 +5375,7 @@
 		headerTrgEls = header.find('tr'); // original header is in its own table
 		headerTrgEls = header.find('tr'); // original header is in its own table
 		headerSrcEls = headerCopy.find('tr');
 		headerSrcEls = headerCopy.find('tr');
 		headerCopy.find('th, td').removeAttr('tabindex');
 		headerCopy.find('th, td').removeAttr('tabindex');
+		headerCopy.find('[id]').removeAttr('id');
 	
 	
 	
 	
 		/*
 		/*
@@ -8332,8 +8353,12 @@
 	
 	
 	$(document).on('plugin-init.dt', function (e, context) {
 	$(document).on('plugin-init.dt', function (e, context) {
 		var api = new _Api( context );
 		var api = new _Api( context );
+		
+		const namespace = 'on-plugin-init';
+		const stateSaveParamsEvent = `stateSaveParams.${namespace}`;
+		const destroyEvent = `destroy.${namespace}`;
 	
 	
-		api.on( 'stateSaveParams', function ( e, settings, d ) {
+		api.on( stateSaveParamsEvent, function ( e, settings, d ) {
 			// This could be more compact with the API, but it is a lot faster as a simple
 			// This could be more compact with the API, but it is a lot faster as a simple
 			// internal loop
 			// internal loop
 			var idFn = settings.rowIdFn;
 			var idFn = settings.rowIdFn;
@@ -8347,7 +8372,11 @@
 			}
 			}
 	
 	
 			d.childRows = ids;
 			d.childRows = ids;
-		})
+		});
+	
+		api.on( destroyEvent, function () {
+			api.off(`${stateSaveParamsEvent} ${destroyEvent}`);
+		});
 	
 	
 		var loaded = api.state.loaded();
 		var loaded = api.state.loaded();
 	
 	
@@ -9668,7 +9697,7 @@
 	 *  @type string
 	 *  @type string
 	 *  @default Version number
 	 *  @default Version number
 	 */
 	 */
-	DataTable.version = "1.12.0";
+	DataTable.version = "1.13.1";
 	
 	
 	/**
 	/**
 	 * Private data store, containing all of the settings objects that are
 	 * Private data store, containing all of the settings objects that are
@@ -14092,7 +14121,7 @@
 		 *
 		 *
 		 *  @type string
 		 *  @type string
 		 */
 		 */
-		build:"bs5/dt-1.12.0/r-2.3.0/sl-1.4.0",
+		build:"bs5/dt-1.13.1/r-2.4.0/sl-1.5.0",
 	
 	
 	
 	
 		/**
 		/**
@@ -14730,7 +14759,7 @@
 				var classes = settings.oClasses;
 				var classes = settings.oClasses;
 				var lang = settings.oLanguage.oPaginate;
 				var lang = settings.oLanguage.oPaginate;
 				var aria = settings.oLanguage.oAria.paginate || {};
 				var aria = settings.oLanguage.oAria.paginate || {};
-				var btnDisplay, btnClass, counter=0;
+				var btnDisplay, btnClass;
 	
 	
 				var attach = function( container, buttons ) {
 				var attach = function( container, buttons ) {
 					var i, ien, node, button, tabIndex;
 					var i, ien, node, button, tabIndex;
@@ -14805,7 +14834,7 @@
 										'class': classes.sPageButton+' '+btnClass,
 										'class': classes.sPageButton+' '+btnClass,
 										'aria-controls': settings.sTableId,
 										'aria-controls': settings.sTableId,
 										'aria-label': aria[ button ],
 										'aria-label': aria[ button ],
-										'data-dt-idx': counter,
+										'data-dt-idx': button,
 										'tabindex': tabIndex,
 										'tabindex': tabIndex,
 										'id': idx === 0 && typeof button === 'string' ?
 										'id': idx === 0 && typeof button === 'string' ?
 											settings.sTableId +'_'+ button :
 											settings.sTableId +'_'+ button :
@@ -14817,8 +14846,6 @@
 								_fnBindAction(
 								_fnBindAction(
 									node, {action: button}, clickHandler
 									node, {action: button}, clickHandler
 								);
 								);
-	
-								counter++;
 							}
 							}
 						}
 						}
 					}
 					}
@@ -15163,7 +15190,7 @@
 			}
 			}
 		}
 		}
 		else if (window.luxon) {
 		else if (window.luxon) {
-			dt = format
+			dt = format && typeof d === 'string'
 				? window.luxon.DateTime.fromFormat( d, format )
 				? window.luxon.DateTime.fromFormat( d, format )
 				: window.luxon.DateTime.fromISO( d );
 				: window.luxon.DateTime.fromISO( d );
 	
 	
@@ -15303,14 +15330,26 @@
 	}
 	}
 	
 	
 	// Based on locale, determine standard number formatting
 	// Based on locale, determine standard number formatting
-	var __thousands = '';
-	var __decimal = '';
+	// Fallback for legacy browsers is US English
+	var __thousands = ',';
+	var __decimal = '.';
 	
 	
 	if (Intl) {
 	if (Intl) {
-		var num = new Intl.NumberFormat().formatToParts(1000.1);
-	
-		__thousands = num[1].value;
-		__decimal = num[3].value;
+		try {
+			var num = new Intl.NumberFormat().formatToParts(100000.1);
+		
+			for (var i=0 ; i<num.length ; i++) {
+				if (num[i].type === 'group') {
+					__thousands = num[i].value;
+				}
+				else if (num[i].type === 'decimal') {
+					__decimal = num[i].value;
+				}
+			}
+		}
+		catch (e) {
+			// noop
+		}
 	}
 	}
 	
 	
 	// Formatted date time detection - use by declaring the formats you are going to use
 	// Formatted date time detection - use by declaring the formats you are going to use
@@ -15379,6 +15418,10 @@
 						return d;
 						return d;
 					}
 					}
 	
 	
+					if (d === '' || d === null) {
+						return d;
+					}
+	
 					var negative = d < 0 ? '-' : '';
 					var negative = d < 0 ? '-' : '';
 					var flo = parseFloat( d );
 					var flo = parseFloat( d );
 	
 	
@@ -15569,7 +15612,7 @@
 	$.each( DataTable, function ( prop, val ) {
 	$.each( DataTable, function ( prop, val ) {
 		$.fn.DataTable[ prop ] = val;
 		$.fn.DataTable[ prop ] = val;
 	} );
 	} );
-	
+
 	return DataTable;
 	return DataTable;
 }));
 }));
 
 
@@ -15578,14 +15621,6 @@
  * 2020 SpryMedia Ltd - datatables.net/license
  * 2020 SpryMedia Ltd - datatables.net/license
  */
  */
 
 
-/**
- * DataTables integration for Bootstrap 4. This requires Bootstrap 5 and
- * DataTables 1.10 or newer.
- *
- * This file sets the defaults and adds options to DataTables to style its
- * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
- * for further information.
- */
 (function( factory ){
 (function( factory ){
 	if ( typeof define === 'function' && define.amd ) {
 	if ( typeof define === 'function' && define.amd ) {
 		// AMD
 		// AMD
@@ -15597,16 +15632,22 @@
 		// CommonJS
 		// CommonJS
 		module.exports = function (root, $) {
 		module.exports = function (root, $) {
 			if ( ! root ) {
 			if ( ! root ) {
+				// CommonJS environments without a window global must pass a
+				// root. This will give an error otherwise
 				root = window;
 				root = window;
 			}
 			}
 
 
-			if ( ! $ || ! $.fn.dataTable ) {
-				// Require DataTables, which attaches to jQuery, including
-				// jQuery if needed and have a $ property so we can access the
-				// jQuery object that is used
-				$ = require('datatables.net')(root, $).$;
+			if ( ! $ ) {
+				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
+					require('jquery') :
+					require('jquery')( root );
+			}
+
+			if ( ! $.fn.dataTable ) {
+				require('datatables.net')(root, $);
 			}
 			}
 
 
+
 			return factory( $, root, root.document );
 			return factory( $, root, root.document );
 		};
 		};
 	}
 	}
@@ -15619,11 +15660,21 @@
 var DataTable = $.fn.dataTable;
 var DataTable = $.fn.dataTable;
 
 
 
 
+
+/**
+ * DataTables integration for Bootstrap 5. This requires Bootstrap 5 and
+ * DataTables 1.10 or newer.
+ *
+ * This file sets the defaults and adds options to DataTables to style its
+ * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
+ * for further information.
+ */
+
 /* Set the defaults for DataTables initialisation */
 /* Set the defaults for DataTables initialisation */
 $.extend( true, DataTable.defaults, {
 $.extend( true, DataTable.defaults, {
 	dom:
 	dom:
 		"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
 		"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
-		"<'row'<'col-sm-12'tr>>" +
+		"<'row dt-row'<'col-sm-12'tr>>" +
 		"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
 		"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
 	renderer: 'bootstrap'
 	renderer: 'bootstrap'
 } );
 } );
@@ -15645,7 +15696,7 @@ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, bu
 	var classes = settings.oClasses;
 	var classes = settings.oClasses;
 	var lang    = settings.oLanguage.oPaginate;
 	var lang    = settings.oLanguage.oPaginate;
 	var aria = settings.oLanguage.oAria.paginate || {};
 	var aria = settings.oLanguage.oAria.paginate || {};
-	var btnDisplay, btnClass, counter=0;
+	var btnDisplay, btnClass;
 
 
 	var attach = function( container, buttons ) {
 	var attach = function( container, buttons ) {
 		var i, ien, node, button;
 		var i, ien, node, button;
@@ -15714,7 +15765,7 @@ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, bu
 								'href': '#',
 								'href': '#',
 								'aria-controls': settings.sTableId,
 								'aria-controls': settings.sTableId,
 								'aria-label': aria[ button ],
 								'aria-label': aria[ button ],
-								'data-dt-idx': counter,
+								'data-dt-idx': button,
 								'tabindex': settings.iTabIndex,
 								'tabindex': settings.iTabIndex,
 								'class': 'page-link'
 								'class': 'page-link'
 							} )
 							} )
@@ -15725,13 +15776,12 @@ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, bu
 					settings.oApi._fnBindAction(
 					settings.oApi._fnBindAction(
 						node, {action: button}, clickHandler
 						node, {action: button}, clickHandler
 					);
 					);
-
-					counter++;
 				}
 				}
 			}
 			}
 		}
 		}
 	};
 	};
 
 
+	var hostEl = $(host);
 	// IE9 throws an 'unknown error' if document.activeElement is used
 	// IE9 throws an 'unknown error' if document.activeElement is used
 	// inside an iframe or frame. 
 	// inside an iframe or frame. 
 	var activeEl;
 	var activeEl;
@@ -15741,17 +15791,26 @@ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, bu
 		// elements, focus is lost on the select button which is bad for
 		// elements, focus is lost on the select button which is bad for
 		// accessibility. So we want to restore focus once the draw has
 		// accessibility. So we want to restore focus once the draw has
 		// completed
 		// completed
-		activeEl = $(host).find(document.activeElement).data('dt-idx');
+		activeEl = hostEl.find(document.activeElement).data('dt-idx');
 	}
 	}
 	catch (e) {}
 	catch (e) {}
 
 
+	var paginationEl = hostEl.children('ul.pagination');
+
+	if (paginationEl.length) {
+		paginationEl.empty();
+	}
+	else {
+		paginationEl = hostEl.html('<ul/>').children('ul').addClass('pagination');
+	}
+
 	attach(
 	attach(
-		$(host).empty().html('<ul class="pagination"/>').children('ul'),
+		paginationEl,
 		buttons
 		buttons
 	);
 	);
 
 
 	if ( activeEl !== undefined ) {
 	if ( activeEl !== undefined ) {
-		$(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus');
+		hostEl.find('[data-dt-idx='+activeEl+']').trigger('focus');
 	}
 	}
 };
 };
 
 
@@ -15760,27 +15819,10 @@ return DataTable;
 }));
 }));
 
 
 
 
-/*! Responsive 2.3.0
+/*! Responsive 2.4.0
  * 2014-2022 SpryMedia Ltd - datatables.net/license
  * 2014-2022 SpryMedia Ltd - datatables.net/license
  */
  */
 
 
-/**
- * @summary     Responsive
- * @description Responsive tables plug-in for DataTables
- * @version     2.3.0
- * @author      SpryMedia Ltd (www.sprymedia.co.uk)
- * @contact     www.sprymedia.co.uk/contact
- * @copyright   SpryMedia Ltd.
- *
- * This source file is free software, available under the following license:
- *   MIT license - http://datatables.net/license/mit
- *
- * This source file is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
- *
- * For details please refer to: http://www.datatables.net
- */
 (function( factory ){
 (function( factory ){
 	if ( typeof define === 'function' && define.amd ) {
 	if ( typeof define === 'function' && define.amd ) {
 		// AMD
 		// AMD
@@ -15792,13 +15834,22 @@ return DataTable;
 		// CommonJS
 		// CommonJS
 		module.exports = function (root, $) {
 		module.exports = function (root, $) {
 			if ( ! root ) {
 			if ( ! root ) {
+				// CommonJS environments without a window global must pass a
+				// root. This will give an error otherwise
 				root = window;
 				root = window;
 			}
 			}
 
 
-			if ( ! $ || ! $.fn.dataTable ) {
-				$ = require('datatables.net')(root, $).$;
+			if ( ! $ ) {
+				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
+					require('jquery') :
+					require('jquery')( root );
+			}
+
+			if ( ! $.fn.dataTable ) {
+				require('datatables.net')(root, $);
 			}
 			}
 
 
+
 			return factory( $, root, root.document );
 			return factory( $, root, root.document );
 		};
 		};
 	}
 	}
@@ -15811,6 +15862,25 @@ return DataTable;
 var DataTable = $.fn.dataTable;
 var DataTable = $.fn.dataTable;
 
 
 
 
+
+/**
+ * @summary     Responsive
+ * @description Responsive tables plug-in for DataTables
+ * @version     2.4.0
+ * @author      SpryMedia Ltd (www.sprymedia.co.uk)
+ * @contact     www.sprymedia.co.uk/contact
+ * @copyright   SpryMedia Ltd.
+ *
+ * This source file is free software, available under the following license:
+ *   MIT license - http://datatables.net/license/mit
+ *
+ * This source file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
+ *
+ * For details please refer to: http://www.datatables.net
+ */
+
 /**
 /**
  * Responsive is a plug-in for the DataTables library that makes use of
  * Responsive is a plug-in for the DataTables library that makes use of
  * DataTables' ability to change the visibility of columns, changing the
  * DataTables' ability to change the visibility of columns, changing the
@@ -15863,9 +15933,10 @@ var Responsive = function ( settings, opts ) {
 	}
 	}
 
 
 	this.s = {
 	this.s = {
-		dt: new DataTable.Api( settings ),
+		childNodeStore: {},
 		columns: [],
 		columns: [],
-		current: []
+		current: [],
+		dt: new DataTable.Api( settings )
 	};
 	};
 
 
 	// Check if responsive has already been initialised on this table
 	// Check if responsive has already been initialised on this table
@@ -16070,6 +16141,63 @@ $.extend( Responsive.prototype, {
 	 * Private methods
 	 * Private methods
 	 */
 	 */
 
 
+	/**
+	 * Get and store nodes from a cell - use for node moving renderers
+	 *
+	 * @param {*} dt DT instance
+	 * @param {*} row Row index
+	 * @param {*} col Column index
+	 */
+	_childNodes: function( dt, row, col ) {
+		var name = row+'-'+col;
+
+		if ( this.s.childNodeStore[ name ] ) {
+			return this.s.childNodeStore[ name ];
+		}
+
+		// https://jsperf.com/childnodes-array-slice-vs-loop
+		var nodes = [];
+		var children = dt.cell( row, col ).node().childNodes;
+		for ( var i=0, ien=children.length ; i<ien ; i++ ) {
+			nodes.push( children[i] );
+		}
+
+		this.s.childNodeStore[ name ] = nodes;
+
+		return nodes;
+	},
+
+	/**
+	 * Restore nodes from the cache to a table cell
+	 *
+	 * @param {*} dt DT instance
+	 * @param {*} row Row index
+	 * @param {*} col Column index
+	 */
+	_childNodesRestore: function( dt, row, col ) {
+		var name = row+'-'+col;
+
+		if ( ! this.s.childNodeStore[ name ] ) {
+			return;
+		}
+
+		var node = dt.cell( row, col ).node();
+		var store = this.s.childNodeStore[ name ];
+		var parent = store[0].parentNode;
+		var parentChildren = parent.childNodes;
+		var a = [];
+
+		for ( var i=0, ien=parentChildren.length ; i<ien ; i++ ) {
+			a.push( parentChildren[i] );
+		}
+
+		for ( var j=0, jen=a.length ; j<jen ; j++ ) {
+			node.appendChild( a[j] );
+		}
+
+		this.s.childNodeStore[ name ] = undefined;
+	},
+
 	/**
 	/**
 	 * Calculate the visibility for the columns in a table for a given
 	 * Calculate the visibility for the columns in a table for a given
 	 * breakpoint. The result is pre-determined based on the class logic if
 	 * breakpoint. The result is pre-determined based on the class logic if
@@ -16399,8 +16527,8 @@ $.extend( Responsive.prototype, {
 				: details.renderer;
 				: details.renderer;
 
 
 			var res = details.display( row, update, function () {
 			var res = details.display( row, update, function () {
-				return renderer(
-					dt, row[0], that._detailsObj(row[0])
+				return renderer.call(
+					that, dt, row[0], that._detailsObj(row[0])
 				);
 				);
 			} );
 			} );
 
 
@@ -16622,9 +16750,11 @@ $.extend( Responsive.prototype, {
 			}
 			}
 		} );
 		} );
 
 
-		if ( changed ) {
-			this._redrawChildren();
+		// Always need to update the display, regardless of if it has changed or not, so nodes
+		// can be re-inserted for listHiddenNodes
+		this._redrawChildren();
 
 
+		if ( changed ) {
 			// Inform listeners of the change
 			// Inform listeners of the change
 			$(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
 			$(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
 
 
@@ -16650,6 +16780,7 @@ $.extend( Responsive.prototype, {
 	{
 	{
 		var dt = this.s.dt;
 		var dt = this.s.dt;
 		var columns = this.s.columns;
 		var columns = this.s.columns;
+		var that = this;
 
 
 		// Are we allowed to do auto sizing?
 		// Are we allowed to do auto sizing?
 		if ( ! this.c.auto ) {
 		if ( ! this.c.auto ) {
@@ -16663,11 +16794,11 @@ $.extend( Responsive.prototype, {
 		}
 		}
 
 
 		// Need to restore all children. They will be reinstated by a re-render
 		// Need to restore all children. They will be reinstated by a re-render
-		if ( ! $.isEmptyObject( _childNodeStore ) ) {
-			$.each( _childNodeStore, function ( key ) {
+		if ( ! $.isEmptyObject( this.s.childNodeStore ) ) {
+			$.each( this.s.childNodeStore, function ( key ) {
 				var idx = key.split('-');
 				var idx = key.split('-');
 
 
-				_childNodesRestore( dt, idx[0]*1, idx[1]*1 );
+				that._childNodesRestore( dt, idx[0]*1, idx[1]*1 );
 			} );
 			} );
 		}
 		}
 
 
@@ -16787,6 +16918,7 @@ $.extend( Responsive.prototype, {
 	 */
 	 */
 	_setColumnVis: function ( col, showHide )
 	_setColumnVis: function ( col, showHide )
 	{
 	{
+		var that = this;
 		var dt = this.s.dt;
 		var dt = this.s.dt;
 		var display = showHide ? '' : 'none'; // empty string will remove the attr
 		var display = showHide ? '' : 'none'; // empty string will remove the attr
 
 
@@ -16803,9 +16935,9 @@ $.extend( Responsive.prototype, {
 			.toggleClass('dtr-hidden', !showHide);
 			.toggleClass('dtr-hidden', !showHide);
 
 
 		// If the are child nodes stored, we might need to reinsert them
 		// If the are child nodes stored, we might need to reinsert them
-		if ( ! $.isEmptyObject( _childNodeStore ) ) {
+		if ( ! $.isEmptyObject( this.s.childNodeStore ) ) {
 			dt.cells( null, col ).indexes().each( function (idx) {
 			dt.cells( null, col ).indexes().each( function (idx) {
-				_childNodesRestore( dt, idx.row, idx.column );
+				that._childNodesRestore( dt, idx.row, idx.column );
 			} );
 			} );
 		}
 		}
 	},
 	},
@@ -16972,52 +17104,6 @@ Responsive.display = {
 };
 };
 
 
 
 
-var _childNodeStore = {};
-
-function _childNodes( dt, row, col ) {
-	var name = row+'-'+col;
-
-	if ( _childNodeStore[ name ] ) {
-		return _childNodeStore[ name ];
-	}
-
-	// https://jsperf.com/childnodes-array-slice-vs-loop
-	var nodes = [];
-	var children = dt.cell( row, col ).node().childNodes;
-	for ( var i=0, ien=children.length ; i<ien ; i++ ) {
-		nodes.push( children[i] );
-	}
-
-	_childNodeStore[ name ] = nodes;
-
-	return nodes;
-}
-
-function _childNodesRestore( dt, row, col ) {
-	var name = row+'-'+col;
-
-	if ( ! _childNodeStore[ name ] ) {
-		return;
-	}
-
-	var node = dt.cell( row, col ).node();
-	var store = _childNodeStore[ name ];
-	var parent = store[0].parentNode;
-	var parentChildren = parent.childNodes;
-	var a = [];
-
-	for ( var i=0, ien=parentChildren.length ; i<ien ; i++ ) {
-		a.push( parentChildren[i] );
-	}
-
-	for ( var j=0, jen=a.length ; j<jen ; j++ ) {
-		node.appendChild( a[j] );
-	}
-
-	_childNodeStore[ name ] = undefined;
-}
-
-
 /**
 /**
  * Display methods - functions which define how the hidden data should be shown
  * Display methods - functions which define how the hidden data should be shown
  * in the table.
  * in the table.
@@ -17029,6 +17115,7 @@ function _childNodesRestore( dt, row, col ) {
 Responsive.renderer = {
 Responsive.renderer = {
 	listHiddenNodes: function () {
 	listHiddenNodes: function () {
 		return function ( api, rowIdx, columns ) {
 		return function ( api, rowIdx, columns ) {
+			var that = this;
 			var ul = $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>');
 			var ul = $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>');
 			var found = false;
 			var found = false;
 
 
@@ -17045,7 +17132,7 @@ Responsive.renderer = {
 							'</span> '+
 							'</span> '+
 						'</li>'
 						'</li>'
 					)
 					)
-						.append( $('<span class="dtr-data"/>').append( _childNodes( api, col.rowIndex, col.columnIndex ) ) )// api.cell( col.rowIndex, col.columnIndex ).node().childNodes ) )
+						.append( $('<span class="dtr-data"/>').append( that._childNodes( api, col.rowIndex, col.columnIndex ) ) )// api.cell( col.rowIndex, col.columnIndex ).node().childNodes ) )
 						.appendTo( ul );
 						.appendTo( ul );
 
 
 					found = true;
 					found = true;
@@ -17229,7 +17316,7 @@ Api.registerPlural( 'columns().responsiveHidden()', 'column().responsiveHidden()
  * @name Responsive.version
  * @name Responsive.version
  * @static
  * @static
  */
  */
-Responsive.version = '2.3.0';
+Responsive.version = '2.4.0';
 
 
 
 
 $.fn.dataTable.Responsive = Responsive;
 $.fn.dataTable.Responsive = Responsive;
@@ -17256,12 +17343,12 @@ $(document).on( 'preInit.dt.dtr', function (e, settings, json) {
 } );
 } );
 
 
 
 
-return Responsive;
+return DataTable;
 }));
 }));
 
 
 
 
 /*! Bootstrap 5 integration for DataTables' Responsive
 /*! Bootstrap 5 integration for DataTables' Responsive
- * ©2021 SpryMedia Ltd - datatables.net/license
+ * © SpryMedia Ltd - datatables.net/license
  */
  */
 
 
 (function( factory ){
 (function( factory ){
@@ -17275,17 +17362,26 @@ return Responsive;
 		// CommonJS
 		// CommonJS
 		module.exports = function (root, $) {
 		module.exports = function (root, $) {
 			if ( ! root ) {
 			if ( ! root ) {
+				// CommonJS environments without a window global must pass a
+				// root. This will give an error otherwise
 				root = window;
 				root = window;
 			}
 			}
 
 
-			if ( ! $ || ! $.fn.dataTable ) {
-				$ = require('datatables.net-bs5')(root, $).$;
+			if ( ! $ ) {
+				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
+					require('jquery') :
+					require('jquery')( root );
+			}
+
+			if ( ! $.fn.dataTable ) {
+				require('datatables.net-bs5')(root, $);
 			}
 			}
 
 
-			if ( ! $.fn.dataTable.Responsive ) {
+			if ( ! $.fn.dataTable ) {
 				require('datatables.net-responsive')(root, $);
 				require('datatables.net-responsive')(root, $);
 			}
 			}
 
 
+
 			return factory( $, root, root.document );
 			return factory( $, root, root.document );
 		};
 		};
 	}
 	}
@@ -17298,6 +17394,7 @@ return Responsive;
 var DataTable = $.fn.dataTable;
 var DataTable = $.fn.dataTable;
 
 
 
 
+
 var _display = DataTable.Responsive.display;
 var _display = DataTable.Responsive.display;
 var _original = _display.modal;
 var _original = _display.modal;
 var _modal = $(
 var _modal = $(
@@ -17359,33 +17456,14 @@ _display.modal = function ( options ) {
 };
 };
 
 
 
 
-return DataTable.Responsive;
+return DataTable;
 }));
 }));
 
 
 
 
-/*! Select for DataTables 1.4.0
+/*! Select for DataTables 1.5.0
  * 2015-2021 SpryMedia Ltd - datatables.net/license/mit
  * 2015-2021 SpryMedia Ltd - datatables.net/license/mit
  */
  */
 
 
-/**
- * @summary     Select for DataTables
- * @description A collection of API methods, events and buttons for DataTables
- *   that provides selection options of the items in a DataTable
- * @version     1.4.0
- * @file        dataTables.select.js
- * @author      SpryMedia Ltd (www.sprymedia.co.uk)
- * @contact     datatables.net/forums
- * @copyright   Copyright 2015-2021 SpryMedia Ltd.
- *
- * This source file is free software, available under the following license:
- *   MIT license - http://datatables.net/license/mit
- *
- * This source file is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
- *
- * For details please refer to: http://www.datatables.net/extensions/select
- */
 (function( factory ){
 (function( factory ){
 	if ( typeof define === 'function' && define.amd ) {
 	if ( typeof define === 'function' && define.amd ) {
 		// AMD
 		// AMD
@@ -17397,13 +17475,22 @@ return DataTable.Responsive;
 		// CommonJS
 		// CommonJS
 		module.exports = function (root, $) {
 		module.exports = function (root, $) {
 			if ( ! root ) {
 			if ( ! root ) {
+				// CommonJS environments without a window global must pass a
+				// root. This will give an error otherwise
 				root = window;
 				root = window;
 			}
 			}
 
 
-			if ( ! $ || ! $.fn.dataTable ) {
-				$ = require('datatables.net')(root, $).$;
+			if ( ! $ ) {
+				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
+					require('jquery') :
+					require('jquery')( root );
 			}
 			}
 
 
+			if ( ! $.fn.dataTable ) {
+				require('datatables.net')(root, $);
+			}
+
+
 			return factory( $, root, root.document );
 			return factory( $, root, root.document );
 		};
 		};
 	}
 	}
@@ -17416,10 +17503,11 @@ return DataTable.Responsive;
 var DataTable = $.fn.dataTable;
 var DataTable = $.fn.dataTable;
 
 
 
 
+
 // Version information for debugger
 // Version information for debugger
 DataTable.select = {};
 DataTable.select = {};
 
 
-DataTable.select.version = '1.4.0';
+DataTable.select.version = '1.5.0';
 
 
 DataTable.select.init = function ( dt ) {
 DataTable.select.init = function ( dt ) {
 	var ctx = dt.settings()[0];
 	var ctx = dt.settings()[0];
@@ -18688,7 +18776,6 @@ $(document).on( 'preInit.dt.dtSelect', function (e, ctx) {
 } );
 } );
 
 
 
 
-return DataTable.select;
+return DataTable;
 }));
 }));
 
 
-