Commit 6bd8291b authored by Benni Mack's avatar Benni Mack Committed by Christian Kuhn
Browse files

[FEATURE] Customize selectable columns in List module per table

In prior TYPO3 versions, it was possible to customize the list of fields
to be shown in the list view. This was only possible if the clipboard
was active OR the user was in "single table view", and displayed
in a box at the bottom of the module without any context.

The new field selector is now right at the top of the database table -
and per table - thus, always active and in context with the table.

Via UserTSconfig it is possible to explicitly disable the functionality
for users/groups for all tables or just a specific table.

Example: Disable it for all tables except for sys_category:

   mod.web_list.displayColumnSelector = 0
   mod.web_list.table.sys_category.displayColumnSelector = 1

Resolves: #94218
Releases: master
Change-Id: Ia6db3a18fea5d0cf96fa32611535048f6e5c6199
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69262

Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
parent c73e97fb
......@@ -90,7 +90,6 @@
@import "typo3/element_tree";
@import "typo3/element_uiblock";
@import "typo3/element_pagination";
@import "typo3/element_fieldselectbox";
@import "typo3/element_label";
@import "typo3/element_badges";
@import "typo3/element_buttons";
......
//
// Database Recordlist fieldSelectBox
//
.fieldSelectBox {
.table-scrollable {
overflow: auto;
max-height: 6 * (($line-height-base * $font-size-base) + 4px + (2 * $padding-base-horizontal) + 1px);
}
table {
.col-title {
padding: 0 $padding-base-vertical;
}
.label-block {
line-height: 32px;
height: 32px;
}
}
}
......@@ -2,7 +2,9 @@
// Web > List
//
div.recordlist {
.recordlist {
overflow: unset;
table tr {
td.deletePlaceholder {
text-decoration: line-through;
......@@ -12,6 +14,16 @@ div.recordlist {
.pagination {
display: inline-flex;
}
.field-selector-dropdown {
overflow-y: auto;
max-height: 6 * (($line-height-base * $font-size-base) + 4px + (2 * $padding-base-horizontal) + 1px);
}
.field-selector-header {
background-color: $dropdown-bg;
z-index: 2;
}
}
div.typo3-newRecordLink,
......
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import $ from 'jquery';
/**
* Module: TYPO3/CMS/Recordlist/FieldSelectBox
* Check-all / uncheck-all for the Database Recordlist fieldSelectBox
* @exports TYPO3/CMS/Recordlist/FieldSelectBox
*/
class FieldSelectBox {
constructor() {
$(() => {
$('.fieldSelectBox .checkAll').on('change', (event: JQueryEventObject): void => {
const checked = $(event.currentTarget).prop('checked');
const $checkboxes = $('.fieldSelectBox tbody').find(':checkbox');
$checkboxes.each((index: number, elem: Element): void => {
if (!$(elem).prop('disabled')) {
$(elem).prop('checked', checked);
}
});
});
});
}
}
export = new FieldSelectBox();
......@@ -65,6 +65,9 @@ class Recordlist {
Tooltip.initialize('.table-fit a[title]');
this.registerPaginationEvents();
});
DocumentService.ready().then((): void => {
this.registerColumnSelectorEvents();
});
new RegularEvent('typo3:datahandler:process', this.handleDataHandlerResult.bind(this)).bindTo(document);
}
......@@ -246,6 +249,24 @@ class Recordlist {
});
});
}
/**
* Show columns dropdown: If "Toggle all" is changed, then all other checkboxes are flipped
*/
private registerColumnSelectorEvents = (): void => {
// Fill out initially if the other checkboxes are set.
document.querySelectorAll('.recordlist-select-allcolumns').forEach((allFieldsCheckbox: HTMLInputElement) => {
allFieldsCheckbox.addEventListener('change', (e: InputEvent) => {
allFieldsCheckbox.closest('form').querySelectorAll('.recordlist-select-column').forEach((checkbox: HTMLInputElement) => {
if (!checkbox.disabled) {
checkbox.checked = !checkbox.checked;
}
});
});
});
}
}
export = new Recordlist();
.. include:: ../../Includes.txt
=============================================================
Feature: #94218 - Selectable columns per table in record list
=============================================================
See :issue:`94218`
Description
===========
The Record List (commonly known from the list module) previously allowed to
select specific columns for a table at the bottom of the module via the
so-called "field selector".
This approach had several drawbacks:
* UX-wise the selection was not directly visible for users, as the component was
separated at the module page at the bottom
* Only possible to select fields explicitly in the "single-table view"
Instead, this feature - the column selector - is now available at all times in
the title row of each table, regardless of the single-table-view, making it
much more appealing and prominent to use for editors.
This feature is active by default, and can be disabled via UserTSconfig per
table or completely for a specific user or usergroup.
Use cases / Examples via UserTSconfig:
.. code-block:: typoscript
# disable the column selector for tt_content
mod.web_list.table.tt_content.displayColumnSelector = 0
# disable the column selector completely
mod.web_list.displayColumnSelector = 0
# Disable the column selector everywhere except for a specific table
mod.web_list.displayColumnSelector = 0
mod.web_list.table.sys_category.displayColumnSelector = 1
Impact
======
The field selector at the bottom is not available anymore,
but has been replaced by a dropdown selector at the top of each table.
.. index:: Backend, TSConfig, ext:recordlist
......@@ -147,9 +147,7 @@ class TableListViewHelper extends AbstractBackendViewHelper
$storagePid = $frameworkConfiguration['persistence']['storagePid'];
}
$dblist->start($storagePid, $tableName, (int)GeneralUtility::_GP('pointer'), $filter, $levels, $recordsPerPage);
$dblist->allFields = true;
$dblist->dontShowClipControlPanels = true;
$dblist->displayFields = null;
$dblist->setFields = [$tableName => $fieldList];
$dblist->noControlPanels = !$enableControlPanels;
$dblist->sortField = $sortField;
......
......@@ -171,7 +171,6 @@ class DatabaseBrowser extends AbstractElementBrowser implements ElementBrowserIn
$dbList->noControlPanels = true;
$dbList->clickMenuEnabled = false;
$dbList->tableList = implode(',', $tablesArr);
$dbList->allFields = true;
// a string like "data[pages][79][storage_pid]"
[$fieldPointerString] = explode('|', $this->bparams);
......@@ -194,7 +193,7 @@ class DatabaseBrowser extends AbstractElementBrowser implements ElementBrowserIn
$searchLevels
);
$dbList->setDispFields();
$dbList->setDispFields($this->getRequest()->getParsedBody()['displayFields'] ?? null);
$tableList = $dbList->generateList();
$out .= $this->renderSearchBox($dbList, $searchWord, $searchLevels);
......@@ -202,12 +201,6 @@ class DatabaseBrowser extends AbstractElementBrowser implements ElementBrowserIn
// Add the HTML for the record list to output variable:
$out .= $tableList;
// Add support for fieldselectbox in singleTableMode
if ($dbList->table) {
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/FieldSelectBox');
$out .= $dbList->fieldSelectBox($dbList->table);
}
return $out;
}
......
......@@ -111,7 +111,6 @@ class RecordListController
{
$this->moduleTemplate = $this->moduleTemplateFactory->create($request);
$this->getLanguageService()->includeLLFile('EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf');
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/FieldSelectBox');
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/Recordlist');
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/ClearCache');
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/AjaxDataHandler');
......@@ -174,7 +173,6 @@ class RecordListController
$dblist->setModuleData($MOD_SETTINGS ?? []);
$dblist->calcPerms = $this->pagePermissions;
$dblist->returnUrl = $this->returnUrl;
$dblist->allFields = (bool)($MOD_SETTINGS['bigControlPanel'] ?? $table);
$dblist->showClipboard = true;
$dblist->disableSingleTableView = $this->modTSconfig['disableSingleTableView'] ?? false;
$dblist->listOnlyInSingleTableMode = $this->modTSconfig['listOnlyInSingleTableView'] ?? false;
......@@ -227,7 +225,7 @@ class RecordListController
}
// Initialize the listing object, dblist, for rendering the list:
$dblist->start($this->id, $table, $pointer, $search_field, $search_levels);
$dblist->setDispFields();
$dblist->setDispFields($request->getParsedBody()['displayFields'] ?? null);
// Render the list of tables:
$tableOutput = $dblist->generateList();
......@@ -329,10 +327,6 @@ class RecordListController
$body .= '<input type="hidden" name="cmd_table" /><input type="hidden" name="cmd" /></form>';
// If a listing was produced, create the page footer with search form etc:
if ($tableOutput) {
// Making field select box (when extended view for a single table is enabled):
if ($dblist->table) {
$body .= $dblist->fieldSelectBox($dblist->table);
}
// Adding checkbox options for extended listing and clipboard display:
$body .= '
......
......@@ -197,13 +197,6 @@ class DatabaseRecordList
*/
public $currentTable = [];
/**
* Indicates if all available fields for a user should be selected or not.
*
* @var bool
*/
public $allFields = false;
/**
* Decides the columns shown. Filled with values that refers to the keys of the data-array. $this->fieldArray[0] is the title column.
*
......@@ -218,13 +211,6 @@ class DatabaseRecordList
*/
public $hideTables = '';
/**
* Containing which fields to display in extended mode
*
* @var string[]|null
*/
public $displayFields;
/**
* Page select permissions
*
......@@ -430,9 +416,9 @@ class DatabaseRecordList
{
$titleCol = $GLOBALS['TCA'][$table]['ctrl']['label'] ?? '';
// Setting fields selected in fieldselectBox (saved in uc)
// Setting fields selected in columnSelectorBox (saved in uc)
$rowListArray = [];
if ($this->allFields && is_array($this->setFields[$table] ?? null)) {
if (is_array($this->setFields[$table] ?? null)) {
$rowListArray = $this->makeFieldList($table, false, true);
if ($includeMetaColumns) {
$rowListArray[] = '_PATH_';
......@@ -660,6 +646,8 @@ class DatabaseRecordList
. $icon
. '</button>';
}
// Show the select box
$tableHeader .= $this->columnSelector($table);
}
// Render table rows only if in multi table view or if in single table view
$rowOutput = '';
......@@ -1920,13 +1908,14 @@ class DatabaseRecordList
* Creates a checkbox list for selecting fields to display from a table:
*
* @param string $table Table name
* @return string HTML table with the selector check box (name: displayFields['.$table.'][])
* @return string HTML content with the selector check box (name: displayFields['.$table.'][])
*/
public function fieldSelectBox($table)
protected function columnSelector(string $table): string
{
// Table with the field selector
$lang = $this->getLanguageService();
// Load already selected fields, if any:
$setFields = (array)($this->setFields[$table]?? []);
$selectedFields = (array)($this->setFields[$table] ?? []);
// Request fields from table:
$fields = $this->makeFieldList($table, false, true);
// Add pseudo "control" fields
......@@ -1936,14 +1925,32 @@ class DatabaseRecordList
$checkboxes = [];
$checkAllChecked = true;
$tsConfig = BackendUtility::getPagesTSconfig($this->id);
$tsConfigOfTable = is_array($tsConfig['TCEFORM.'][$table . '.']) ? $tsConfig['TCEFORM.'][$table . '.'] : null;
$shouldRenderSelector = true;
// See if it is disabled in general
if (empty($tsConfig['mod.']['web_list.']['displayColumnSelector'] ?? true)) {
$shouldRenderSelector = false;
}
// Table override was explicitly set to false
if (isset($tsConfig['mod.']['web_list.']['table.'][$table . '.']['displayColumnSelector'])) {
if (empty($tsConfig['mod.']['web_list.']['table.'][$table . '.']['displayColumnSelector'])) {
$shouldRenderSelector = false;
} else {
$shouldRenderSelector = true;
}
}
if ($shouldRenderSelector === false) {
return '';
}
$tsConfigOfTable = is_array($tsConfig['TCEFORM.'][$table . '.'] ?? null) ? $tsConfig['TCEFORM.'][$table . '.'] : null;
foreach ($fields as $fieldName) {
// Hide field if hidden
if ($tsConfigOfTable && is_array($tsConfigOfTable[$fieldName . '.']) && isset($tsConfigOfTable[$fieldName . '.']['disabled']) && (int)$tsConfigOfTable[$fieldName . '.']['disabled'] === 1) {
if ($tsConfigOfTable && is_array($tsConfigOfTable[$fieldName . '.'] ?? null) && isset($tsConfigOfTable[$fieldName . '.']['disabled']) && (int)$tsConfigOfTable[$fieldName . '.']['disabled'] === 1) {
continue;
}
// Determine, if checkbox should be checked
if (($fieldName === $GLOBALS['TCA'][$table]['ctrl']['label'] ?? false) || in_array($fieldName, $setFields, true)) {
if (($fieldName === $GLOBALS['TCA'][$table]['ctrl']['label'] ?? false) || in_array($fieldName, $selectedFields, true)) {
$checked = true;
} else {
$checkAllChecked = false;
......@@ -1971,11 +1978,17 @@ class DatabaseRecordList
'fieldLabel' => $fieldLabel
];
}
// Table with the field selector
return $this->getFluidTemplateObject('FieldSelectBox.html')
// Sort disabled fields to top
usort($checkboxes, function ($a, $b) {
return $b['disabled'] - $a['disabled'];
});
return $this->getFluidTemplateObject('ColumnSelector.html')
->assignMultiple([
'formUrl' => $this->listURL(),
'table' => $table,
'tableIdentifier' => $this->showOnlyTranslatedRecords ? ($table . '_translated') : $table,
'allChecked' => $checkAllChecked,
'checkboxes' => $checkboxes
])
......@@ -2232,7 +2245,6 @@ class DatabaseRecordList
// Setting GPvars:
$this->sortField = GeneralUtility::_GP('sortField');
$this->sortRev = GeneralUtility::_GP('sortRev');
$this->displayFields = GeneralUtility::_GP('displayFields');
$this->duplicateField = GeneralUtility::_GP('duplicateField');
// If there is a current link to a record, set the current link uid and get the table name from the link handler configuration
......@@ -2335,17 +2347,17 @@ class DatabaseRecordList
* Setting the field names to display in extended list.
* Sets the internal variable $this->setFields
*/
public function setDispFields()
public function setDispFields($updatedFieldsToDisplay = null)
{
$backendUser = $this->getBackendUserAuthentication();
// Getting from session:
$dispFields = $backendUser->getModuleData('list/displayFields');
// If fields has been inputted, then set those as the value and push it to session variable:
if (is_array($this->displayFields)) {
reset($this->displayFields);
$tKey = key($this->displayFields);
$dispFields[$tKey] = $this->displayFields[$tKey];
$backendUser->pushModuleData('list/displayFields', $dispFields);
// If fields have been inputted, then set those as the value and push it to session variable:
if (is_array($updatedFieldsToDisplay) && $updatedFieldsToDisplay !== []) {
foreach ($updatedFieldsToDisplay as $table => $fields) {
$dispFields[$table] = $fields;
$backendUser->pushModuleData('list/displayFields', $dispFields);
}
}
// Setting result:
$this->setFields = $dispFields;
......
......@@ -3,6 +3,12 @@
<file source-language="en" datatype="plaintext" original="EXT:recordlist/Resources/Private/Language/locallang.xlf" date="2017-02-03T21:13:02Z" product-name="recordlist">
<header/>
<body>
<trans-unit id="showColumns" resname="showColumns">
<source>Show Columns</source>
</trans-unit>
<trans-unit id="updateColumnView" resname="updateColumnView">
<source>Update</source>
</trans-unit>
<trans-unit id="error.linkHandlerTitleMissing" resname="error.linkHandlerTitleMissing">
<source>[title missing]</source>
</trans-unit>
......
<div class="pull-right dropdown me-2 p-0">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" id="selectcolumns-{tableIdentifier}" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
<core:icon identifier="actions-options" size="small" />
<f:translate key="LLL:EXT:recordlist/Resources/Private/Language/locallang.xlf:showColumns" />
</button>
<div class="dropdown-menu dropdown-menu-end pt-0 field-selector-dropdown" aria-labelledby="selectcolumns-{tableIdentifier}">
<f:comment>
The below form and the anchor do only have effect outside of Recordlist (e.g. DatabaseBrowser) since
Recordlist already defines an outer form and nested forms are not supported.
</f:comment>
<form action="{formUrl}#t3-table-{tableIdentifier}" method="post" name="field-selector-form-{tableIdentifier}">
<div class="pt-2 pb-2 mb-2 row align-items-center border-bottom field-selector-header">
<div class="col">
<div class="form-check">
<input type="checkbox" class="form-check-input recordlist-select-allcolumns" id="select-allcolumns-{tableIdentifier}" {f:if(condition: allChecked, then: ' checked')} />
<label class="form-check-label" for="select-allcolumns-{tableIdentifier}">
<f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleall" />
</label>
</div>
</div>
<div class="col text-end">
<button type="submit" class="btn btn-primary">
<f:translate key="LLL:EXT:recordlist/Resources/Private/Language/locallang.xlf:updateColumnView" />
</button>
</div>
</div>
<f:for each="{checkboxes}" as="checkbox">
<div class="mb-2">
<div class="form-check">
<input
type="checkbox"
id="select-column-{tableIdentifier}-{checkbox.fieldName}"
name="displayFields[{table}][]"
class="form-check-input recordlist-select-column"
value="{checkbox.fieldName}"
{f:if(condition:'{checkbox.checked}', then:' checked')}
{f:if(condition:'{checkbox.disabled}', then: 'disabled')}
/>
<f:if condition="{checkbox.disabled}">
<input type="hidden" name="displayFields[{table}][]" value="{checkbox.fieldName}" />
</f:if>
<label class="form-check-label" for="select-column-{tableIdentifier}-{checkbox.fieldName}">
<f:if condition="{checkbox.fieldLabel}">
<span class="me-2"><f:translate key="{checkbox.fieldLabel}">{checkbox.fieldLabel}</f:translate></span>
</f:if>
<span class="text-muted text-monospace">[{checkbox.fieldName}]</span>
</label>
</div>
</div>
</f:for>
</form>
</div>
</div>
<div class="fieldSelectBox">
<form action="{formUrl}" method="post" name="fieldSelectBox">
<input type="hidden" name="displayFields[{table}][]" value="">
<div class="table-fit table-scrollable">
<table border="0" cellpadding="0" cellspacing="0" class="table table-transparent table-hover">
<thead>
<tr>
<th class="col-checkbox" colspan="2">
<div class="form-check">
<input type="checkbox" class="form-check-input checkAll" id="checkAll" {f:if(condition:'{allChecked}', then: ' checked="checked"')} />
<label class="form-check-label" for="checkAll">
<f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleall" />
</label>
</div>
</th>
</tr>
</thead>
<tbody>
<f:for each="{checkboxes}" as="checkbox">
<tr>
<td class="col-checkbox">
<input
type="checkbox"
id="check-{checkbox.fieldName}"
name="displayFields[{table}][]"
value="{checkbox.fieldName}"
{f:if(condition:'{checkbox.checked}', then:' checked')}
{f:if(condition:'{checkbox.disabled}', then: 'disabled')}
/>
</td>
<td class="col-title">
<label class="label-block" for="check-{checkbox.fieldName}">
<f:if condition="{checkbox.fieldLabel}">
<f:translate key="{checkbox.fieldLabel}">{checkbox.fieldLabel}</f:translate>
</f:if>
<span class="text-muted text-monospace">[{checkbox.fieldName}]</span>
</label>
</td>
</tr>
</f:for>
</tbody>
</table>
</div>
<input type="submit" name="search" class="btn btn-default" value="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.setFields')}" />
</form>
</div>
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};define(["require","exports","jquery"],(function(e,t,r){"use strict";r=__importDefault(r);return new class{constructor(){r.default(()=>{r.default(".fieldSelectBox .checkAll").on("change",e=>{const t=r.default(e.currentTarget).prop("checked");r.default(".fieldSelectBox tbody").find(":checkbox").each((e,c)=>{r.default(c).prop("disabled")||r.default(c).prop("checked",t)})})})}}}));
\ No newline at end of file
......@@ -10,4 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};define(["require","exports","jquery","TYPO3/CMS/Backend/Icons","TYPO3/CMS/Backend/Storage/Persistent","TYPO3/CMS/Core/Event/RegularEvent","TYPO3/CMS/Backend/Tooltip","TYPO3/CMS/Core/DocumentService"],(function(t,e,a,i,n,l,s,d){"use strict";a=__importDefault(a);return new class{constructor(){this.identifier={entity:".t3js-entity",toggle:".t3js-toggle-recordlist",localize:".t3js-action-localize",icons:{collapse:"actions-view-list-collapse",expand:"actions-view-list-expand",editMultiple:".t3js-record-edit-multiple"}},this.toggleClick=t=>{t.preventDefault();const e=a.default(t.currentTarget),l=e.data("table"),s=a.default(e.data("bs-target")),d="expanded"===s.data("state"),r=e.find(".collapseIcon"),o=d?this.identifier.icons.expand:this.identifier.icons.collapse;i.getIcon(o,i.sizes.small).done(t=>{r.html(t)});let c={};n.isset("moduleData.list")&&(c=n.get("moduleData.list"));const u={};u[l]=d?1:0,a.default.extend(c,u),n.set("moduleData.list",c).done(()=>{s.data("state",d?"collapsed":"expanded")})},this.onEditMultiple=t=>{let e,i,n,l,s;t.preventDefault(),e=a.default(t.currentTarget).closest("[data-table]"),0!==e.length&&(l=a.default(t.currentTarget).data("uri"),i=e.data("table"),n=e.find(this.identifier.entity+'[data-uid][data-table="'+i+'"]').map((t,e)=>a.default(e).data("uid")).toArray().join(","),s=l.match(/{[^}]+}/g),a.default.each(s,(t,e)=>{const s=e.substr(1,e.length-2).split(":");let d;switch(s.shift()){case"entityIdentifiers":d=n;break;case"T3_THIS_LOCATION":d=T3_THIS_LOCATION;break;default:return}a.default.each(s,(t,e)=>{"editList"===e&&(d=this.editList(i,d))}),l=l.replace(e,d)}),window.location.href=l)},this.disableButton=t=>{a.default(t.currentTarget).prop("disable",!0).addClass("disabled")},this.deleteRow=t=>{const e=a.default(`table[data-table="${t.table}"]`),i=e.find(`tr[data-uid="${t.uid}"]`),n=e.closest(".panel"),l=n.find(".panel-heading"),s=e.find(`[data-l10nparent="${t.uid}"]`),d=a.default().add(i).add(s);if(d.fadeTo("slow",.4,()=>{d.slideUp("slow",()=>{d.remove(),0===e.find("tbody tr").length&&n.slideUp("slow")})}),"0"===i.data("l10nparent")||""===i.data("l10nparent")){const t=Number(l.find(".t3js-table-total-items").html());l.find(".t3js-table-total-items").text(t-1)}"pages"===t.table&&top.document.dispatchEvent(new CustomEvent("typo3:pagetree:refresh"))},this.registerPaginationEvents=()=>{document.querySelectorAll(".t3js-recordlist-paging").forEach(t=>{t.addEventListener("keyup",e=>{e.preventDefault();let a=parseInt(t.value,10);a<parseInt(t.min,10)&&(a=parseInt(t.min,10)),a>parseInt(t.max,10)&&(a=parseInt(t.max,10)),"Enter"===e.key&&a!==parseInt(t.dataset.currentpage,10)&&(window.location.href=t.dataset.currenturl+a.toString())})})},a.default(document).on("click",this.identifier.toggle,this.toggleClick),a.default(document).on("click",this.identifier.icons.editMultiple,this.onEditMultiple),a.default(document).on("click",this.identifier.localize,this.disableButton),d.ready().then(()=>{s.initialize(".table-fit a[title]"),this.registerPaginationEvents()}),new l("typo3:datahandler:process",this.handleDataHandlerResult.bind(this)).bindTo(document)}editList(t,e){const a=[];let i=0,n=e.indexOf(",");for(;-1!==n;)this.getCheckboxState(t+"|"+e.substr(i,n-i))&&a.push(e.substr(i,n-i)),i=n+1,n=e.indexOf(",",i);return this.getCheckboxState(t+"|"+e.substr(i))&&a.push(e.substr(i)),a.length>0?a.join(","):e}handleDataHandlerResult(t){const e=t.detail.payload;e.hasErrors||"datahandler"!==e.component&&"delete"===e.action&&this.deleteRow(e)}getCheckboxState(t){const e="CBC["+t+"]";return document.querySelector('form[name="dblistForm"] [name="'+e+'"]').checked}}}));