From a305362aedfcfacf98908591c5736b1eb92ccd85 Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Fri, 22 Nov 2024 21:33:51 -0500 Subject: [PATCH 1/5] Use orthogonal data for DataTables Instead of assigning HTML directly as data, we can use assign an object with the following keys: - display - The display value of the data (same as what we had) - filter - Value used for filtering (e.g. SearchBuilder) - order - Value used for sorting This will make DataTables easier to expand in the long run. Since we can assign different attributes to the data. Also fixes #831 --- formats/datatables/DataTables.php | 10 ++++- formats/datatables/SearchPanes.php | 4 +- .../resources/ext.srf.formats.datatables.js | 37 ++++++++++--------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/formats/datatables/DataTables.php b/formats/datatables/DataTables.php index 9aafae43..fb64214f 100644 --- a/formats/datatables/DataTables.php +++ b/formats/datatables/DataTables.php @@ -573,7 +573,7 @@ protected function getResultText( QueryResult $res, $outputmode ) { foreach ( $rows as $cell ) { $this->htmlTable->cell( - ( $cell === '' ? ' ' : $cell ), + ( $cell['display'] === '' ? ' ' : $cell['display'] ), [] ); } @@ -993,7 +993,13 @@ public function getCellContent( $label, $dataValues, $outputMode, $isSubject, $p $html = implode( $this->params['sep'], $values ); } - return $html; + $sortKey = $dataValues[0]->getDataItem()->getSortKey(); + + return [ + 'display' => $html, + 'filter' => $sortKey, + 'order' => $sortKey + ]; } /** diff --git a/formats/datatables/SearchPanes.php b/formats/datatables/SearchPanes.php index eddaabcf..c4fd20d1 100644 --- a/formats/datatables/SearchPanes.php +++ b/formats/datatables/SearchPanes.php @@ -384,7 +384,7 @@ private function getPanesOptions( $printRequest, $canonicalLabel, $searchPanesOp $outputMode, $isSubject, $propTypeid - ); + )['display']; if ( !array_key_exists( $cellContent, $groups ) ) { $groups[$cellContent] = [ 'count' => 0, 'value' => '' ]; @@ -710,7 +710,7 @@ private function searchPanesMainlabel( $printRequest, $searchPanesOptions, $sear [ $dataValue ], $outputMode, $isSubject - ); + )['display']; if ( !array_key_exists( $cellContent, $groups ) ) { $groups[$cellContent] = [ 'count' => 0, 'value' => '' ]; diff --git a/formats/datatables/resources/ext.srf.formats.datatables.js b/formats/datatables/resources/ext.srf.formats.datatables.js index cce48b0d..2d98b70a 100644 --- a/formats/datatables/resources/ext.srf.formats.datatables.js +++ b/formats/datatables/resources/ext.srf.formats.datatables.js @@ -164,16 +164,17 @@ for (var i in data) { for (var ii in ret) { - if (data[i][ii] === "") { + var cellData = data[i][ii]; + if (!cellData) { continue; } dataLength[ii]++; var label; if (options.searchPanes.htmlLabels === false) { - div.innerHTML = data[i][ii]; + div.innerHTML = cellData.display; label = div.textContent || div.innerText || ""; } else { - label = data[i][ii]; + label = cellData.display; } // this will exclude images as well if @@ -182,15 +183,15 @@ continue; } - if (!(data[i][ii] in ret[ii])) { - ret[ii][data[i][ii]] = { + if (!(cellData.display in ret[ii])) { + ret[ii][cellData.display] = { label: label, - value: data[i][ii], + value: cellData.display, count: 0, }; } - ret[ii][data[i][ii]].count++; + ret[ii][cellData.display].count++; } } @@ -246,7 +247,7 @@ columnDefs[i].searchPanes.options.push({ label: searchPanesOptions[i][ii].label, value: function (rowData, rowIdx) { - return rowData[i] === searchPanesOptions[i][ii].value; + return rowData[i].display === searchPanesOptions[i][ii].value; }, }); } @@ -544,7 +545,7 @@ num: { null: null, }, - }, + } }; } else { options.dom = options.dom.replace("Q", ""); @@ -579,11 +580,9 @@ // @see https://datatables.net/reference/option/columns.type // value for all columns if (!options.columns.type) { - options.columns.type = - ( entityCollation === 'numeric' && property.typeid === '_wpg' ) - || [ '_num', '_tem', '_qty' ].indexOf(property.typeid) !== -1 - ? "any-number" - : null; + var isNumeric = ( entityCollation === 'numeric' && property.typeid === '_wpg' ) + || [ '_num', '_tem', '_qty' ].indexOf(property.typeid) !== -1; + options.columns.type = isNumeric ? 'num' : null; } columnDefs.push( @@ -597,9 +596,13 @@ className: "smwtype" + property.typeid, targets: [index], - // @FIXME https://datatables.net/reference/option/columns.searchBuilderType - // implement in the proper way - searchBuilderType: "string", + // https://datatables.net/reference/option/columns.render + render: { + _: 'display', + display: 'display', + filter: 'filter', + sort: 'order' + }, }, options.columns, data.printoutsParametersOptions[index] From 19ee98f2d7525bddcc249698c8da4f716652203b Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Fri, 22 Nov 2024 21:40:30 -0500 Subject: [PATCH 2/5] Drop any-number from DataTables We don't need it anymore because values are assigned a sorting key --- Resources.php | 3 +- formats/datatables/Api.php | 2 +- .../datatables/jquery.dataTables.extras.js | 38 ------------------- .../ext.srf.formats.datatables.test.js | 2 +- 4 files changed, 3 insertions(+), 42 deletions(-) delete mode 100644 resources/jquery/datatables/jquery.dataTables.extras.js diff --git a/Resources.php b/Resources.php index 1d6a917d..21fbb5e6 100644 --- a/Resources.php +++ b/Resources.php @@ -1008,8 +1008,7 @@ 'resources/jquery/datatables/object_hash.js', 'resources/jquery/datatables/jquery.mark.min.js', 'resources/jquery/datatables/datatables.mark.min.js', - 'resources/jquery/datatables/datatables.min.js', - 'resources/jquery/datatables/jquery.dataTables.extras.js', + 'resources/jquery/datatables/datatables.min.js' ], 'styles' => [ 'resources/jquery/datatables/datatables.mark.min.css', diff --git a/formats/datatables/Api.php b/formats/datatables/Api.php index 2ed3c1b0..6976625b 100644 --- a/formats/datatables/Api.php +++ b/formats/datatables/Api.php @@ -111,7 +111,7 @@ public function execute() { if ( $hasMainlabel && trim( $parameters['mainlabel'] ) === '-' ) { continue; } - // match something like |?=abc |+ datatables-columns.type=any-number |+template=mytemplate + // match something like |?=abc |+ datatables-columns.type=number |+template=mytemplate } // create printrequest from request mode, label, property name, output format, parameters diff --git a/resources/jquery/datatables/jquery.dataTables.extras.js b/resources/jquery/datatables/jquery.dataTables.extras.js deleted file mode 100644 index 8ad14dd9..00000000 --- a/resources/jquery/datatables/jquery.dataTables.extras.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * SRF DataTables JavaScript Printer using the SMWAPI - * - * @see http://datatables.net/ - * - * @licence GPL-2.0-or-later - * @author thomas-topway-it for KM-A - * @credits mwjames (ext.smw.tableprinter.js) - */ - -(function ($) { - - // @see https://datatables.net/plug-ins/sorting/any-number - var _anyNumberSort = function (a, b, high) { - var tmpA = document.createElement("DIV"); - tmpA.innerHTML = a; - a = tmpA.textContent || tmpA.innerText || ""; - - var tmpB = document.createElement("DIV"); - tmpB.innerHTML = b; - b = tmpB.textContent || tmpB.innerText || ""; - - return a.localeCompare(b, undefined, { - numeric: true, - sensitivity: "base", - }); - }; - - $.extend($.fn.dataTableExt.oSort, { - "any-number-asc": function (a, b) { - return _anyNumberSort(a, b, Number.POSITIVE_INFINITY); - }, - "any-number-desc": function (a, b) { - return _anyNumberSort(a, b, Number.NEGATIVE_INFINITY) * -1; - }, - }); -})(jQuery); - diff --git a/tests/qunit/formats/ext.srf.formats.datatables.test.js b/tests/qunit/formats/ext.srf.formats.datatables.test.js index ed611210..e96d2c42 100644 --- a/tests/qunit/formats/ext.srf.formats.datatables.test.js +++ b/tests/qunit/formats/ext.srf.formats.datatables.test.js @@ -13,7 +13,7 @@ QUnit.module( 'ext.srf.formats.datatables', QUnit.newMwEnvironment() ); var pass = 'Passes because '; - var context = $( '
', '#qunit-fixture' ), + var context = $( '
', '#qunit-fixture' ), container = context.find( '.datatables-container' ); /** From 5133a68bdb2db16bd396363b81e7489c36685b30 Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Fri, 22 Nov 2024 22:04:11 -0500 Subject: [PATCH 3/5] Remove datatables-columns.type as we do not need it anymore --- formats/datatables/Api.php | 2 +- formats/datatables/DataTables.php | 10 ---------- .../datatables/resources/ext.srf.formats.datatables.js | 10 +++------- tests/qunit/formats/ext.srf.formats.datatables.test.js | 2 +- 4 files changed, 5 insertions(+), 19 deletions(-) diff --git a/formats/datatables/Api.php b/formats/datatables/Api.php index 6976625b..d83cfb75 100644 --- a/formats/datatables/Api.php +++ b/formats/datatables/Api.php @@ -111,7 +111,7 @@ public function execute() { if ( $hasMainlabel && trim( $parameters['mainlabel'] ) === '-' ) { continue; } - // match something like |?=abc |+ datatables-columns.type=number |+template=mytemplate + // match something like |?=abc |+template=mytemplate } // create printrequest from request mode, label, property name, output format, parameters diff --git a/formats/datatables/DataTables.php b/formats/datatables/DataTables.php index fb64214f..c82daaad 100644 --- a/formats/datatables/DataTables.php +++ b/formats/datatables/DataTables.php @@ -267,16 +267,6 @@ public function getParamDefinitions( array $definitions ) { //////////////// datatables columns - // only the options whose value has a sense to - // use for all columns, otherwise use (for single printouts) - // |?printout name |+ datatables-columns.type = string - - $params['datatables-columns.type'] = [ - 'type' => 'string', - 'message' => 'srf-paramdesc-datatables-library-option', - 'default' => '', - ]; - $params['datatables-columns.width'] = [ 'type' => 'string', 'message' => 'srf-paramdesc-datatables-library-option', diff --git a/formats/datatables/resources/ext.srf.formats.datatables.js b/formats/datatables/resources/ext.srf.formats.datatables.js index 2d98b70a..211ccd33 100644 --- a/formats/datatables/resources/ext.srf.formats.datatables.js +++ b/formats/datatables/resources/ext.srf.formats.datatables.js @@ -577,13 +577,9 @@ var columnDefs = []; $.map(printrequests, function (property, index) { - // @see https://datatables.net/reference/option/columns.type - // value for all columns - if (!options.columns.type) { - var isNumeric = ( entityCollation === 'numeric' && property.typeid === '_wpg' ) - || [ '_num', '_tem', '_qty' ].indexOf(property.typeid) !== -1; - options.columns.type = isNumeric ? 'num' : null; - } + var isNumeric = ( entityCollation === 'numeric' && property.typeid === '_wpg' ) + || [ '_num', '_tem', '_qty' ].indexOf(property.typeid) !== -1; + options.columns.type = isNumeric ? 'num' : 'string'; columnDefs.push( $.extend( diff --git a/tests/qunit/formats/ext.srf.formats.datatables.test.js b/tests/qunit/formats/ext.srf.formats.datatables.test.js index e96d2c42..87d911d8 100644 --- a/tests/qunit/formats/ext.srf.formats.datatables.test.js +++ b/tests/qunit/formats/ext.srf.formats.datatables.test.js @@ -13,7 +13,7 @@ QUnit.module( 'ext.srf.formats.datatables', QUnit.newMwEnvironment() ); var pass = 'Passes because '; - var context = $( '
', '#qunit-fixture' ), + var context = $( '
', '#qunit-fixture' ), container = context.find( '.datatables-container' ); /** From 0981a2a5b73f0aa8463d1afe4dc342b4d2852a5f Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Fri, 22 Nov 2024 22:11:46 -0500 Subject: [PATCH 4/5] Use sort instead of order for key name --- formats/datatables/DataTables.php | 2 +- formats/datatables/resources/ext.srf.formats.datatables.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/formats/datatables/DataTables.php b/formats/datatables/DataTables.php index c82daaad..a0dd4b42 100644 --- a/formats/datatables/DataTables.php +++ b/formats/datatables/DataTables.php @@ -988,7 +988,7 @@ public function getCellContent( $label, $dataValues, $outputMode, $isSubject, $p return [ 'display' => $html, 'filter' => $sortKey, - 'order' => $sortKey + 'sort' => $sortKey ]; } diff --git a/formats/datatables/resources/ext.srf.formats.datatables.js b/formats/datatables/resources/ext.srf.formats.datatables.js index 211ccd33..344cf2fa 100644 --- a/formats/datatables/resources/ext.srf.formats.datatables.js +++ b/formats/datatables/resources/ext.srf.formats.datatables.js @@ -597,7 +597,7 @@ _: 'display', display: 'display', filter: 'filter', - sort: 'order' + sort: 'sort' }, }, options.columns, From 1d32cca46fdbef8e56eb2c565982d5c7d592722d Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Sun, 5 Jan 2025 20:25:54 -0500 Subject: [PATCH 5/5] Ensure that dataValues[0] exists in SortKey --- formats/datatables/DataTables.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/formats/datatables/DataTables.php b/formats/datatables/DataTables.php index a0dd4b42..1dccf064 100644 --- a/formats/datatables/DataTables.php +++ b/formats/datatables/DataTables.php @@ -983,7 +983,8 @@ public function getCellContent( $label, $dataValues, $outputMode, $isSubject, $p $html = implode( $this->params['sep'], $values ); } - $sortKey = $dataValues[0]->getDataItem()->getSortKey(); + // $dataValues could be empty + $sortKey = array_key_exists( 0, $dataValues ) ? $dataValues[0]->getDataItem()->getSortKey() : ''; return [ 'display' => $html,