Commit 7c328484 authored by Andreas Fernandez's avatar Andreas Fernandez
Browse files

[BUGFIX] Migrate "Revert selection" of SelectCheckboxElement

With #87324 parts of the FormEngine have been split into smaller,
maintainable parts. However, `SelectCheckboxElement` brings it's own
"Revert selection" implementation that has nothing in common with the
"Reset selection" field control used for select boxes.

The code is now rewritten to handle the revert on its own. Additionally,
another inline `onclick` handler was removed.

Resolves: #88314
Related: #87324
Releases: master
Change-Id: Ifca1b67a960a8caab8145f2a7d5c8301918819fa
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60728

Tested-by: Frank Nägler's avatarFrank Naegler <frank.naegler@typo3.org>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Frank Nägler's avatarFrank Naegler <frank.naegler@typo3.org>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
parent cb1fbf04
......@@ -17,11 +17,13 @@ import FormEngine = require('TYPO3/CMS/Backend/FormEngine');
enum Identifier {
toggleAll = '.t3js-toggle-checkboxes',
singleItem = '.t3js-checkbox',
revertSelection = '.t3js-revert-selection',
}
class SelectCheckBoxElement {
private checkBoxId: string = '';
private $table: JQuery = null;
private checkedBoxes: JQuery = null;
/**
* Determines whether all available checkboxes are checked
......@@ -40,6 +42,7 @@ class SelectCheckBoxElement {
this.checkBoxId = checkBoxId;
$((): void => {
this.$table = $('#' + checkBoxId).closest('table');
this.checkedBoxes = this.$table.find(Identifier.singleItem + ':checked');
this.enableTriggerCheckBox();
this.registerEventHandler();
......@@ -50,7 +53,7 @@ class SelectCheckBoxElement {
* Registers the events for clicking the "Toggle all" and the single item checkboxes
*/
private registerEventHandler(): void {
$(this.$table).on('change', Identifier.toggleAll, (e: JQueryEventObject): void => {
this.$table.on('change', Identifier.toggleAll, (e: JQueryEventObject): void => {
const $me = $(e.currentTarget);
const $checkBoxes = this.$table.find(Identifier.singleItem);
const checkIt = !SelectCheckBoxElement.allCheckBoxesAreChecked($checkBoxes);
......@@ -59,13 +62,22 @@ class SelectCheckBoxElement {
$me.prop('checked', checkIt);
FormEngine.Validation.markFieldAsChanged($me);
}).on('change', Identifier.singleItem, (): void => {
const $checkBoxes = this.$table.find(Identifier.singleItem);
const checkIt = SelectCheckBoxElement.allCheckBoxesAreChecked($checkBoxes);
this.$table.find(Identifier.toggleAll).prop('checked', checkIt);
this.setToggleAllState();
}).on('click', Identifier.revertSelection, (): void => {
this.$table.find(Identifier.singleItem).each((_: number, checkbox: HTMLInputElement): void => {
checkbox.checked = this.checkedBoxes.index(checkbox) > -1;
});
this.setToggleAllState();
});
}
private setToggleAllState(): void {
const $checkBoxes = this.$table.find(Identifier.singleItem);
const checkIt = SelectCheckBoxElement.allCheckBoxesAreChecked($checkBoxes);
this.$table.find(Identifier.toggleAll).prop('checked', checkIt);
}
/**
* Enables the "Toggle all" checkbox on document load if all child checkboxes are checked
*/
......
......@@ -166,10 +166,11 @@ class SelectCheckBoxElement extends AbstractFormElement
// Building the checkboxes
foreach ($groups as $groupKey => $group) {
$groupId = htmlspecialchars($parameterArray['itemFormElID']) . '-group-' . $groupKey;
$html[] = '<div class="panel panel-default">';
$groupIdCollapsible = $groupId . '-collapse';
$html[] = '<div id="' . $groupId . '" class="panel panel-default">';
if (is_array($group['header'])) {
$html[] = '<div class="panel-heading">';
$html[] = '<a data-toggle="collapse" href="#' . $groupId . '" aria-expanded="false" aria-controls="' . $groupId . '">';
$html[] = '<a data-toggle="collapse" href="#' . $groupIdCollapsible . '" aria-expanded="false" aria-controls="' . $groupIdCollapsible . '">';
$html[] = $group['header']['icon'];
$html[] = htmlspecialchars($group['header']['title']);
$html[] = '</a>';
......@@ -177,7 +178,6 @@ class SelectCheckBoxElement extends AbstractFormElement
}
if (is_array($group['items']) && !empty($group['items'])) {
$tableRows = [];
$resetGroup = [];
// Render rows
foreach ($group['items'] as $item) {
......@@ -199,24 +199,22 @@ class SelectCheckBoxElement extends AbstractFormElement
$tableRows[] = '</td>';
$tableRows[] = '<td class="text-right">' . $item['help'] . '</td>';
$tableRows[] = '</tr>';
$resetGroup[] = 'document.editform[' . GeneralUtility::quoteJSvalue($item['name']) . '].checked=' . $item['checked'] . ';';
}
// Build reset group button
$resetGroupBtn = '';
if (!empty($resetGroup)) {
$resetGroup[] = 'TYPO3.FormEngine.updateCheckboxState(this);';
if (!empty($group['items'])) {
$title = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.revertSelection'));
$resetGroupBtn = '<a href="#" '
. 'class="btn btn-default btn-sm" '
. 'onclick="' . implode('', $resetGroup) . ' return false;" '
. 'title="' . $title . '">'
$resetGroupBtn = '<button type="button" '
. 'class="btn btn-default btn-sm t3js-revert-selection" '
. 'title="' . $title . '"'
. '>'
. $this->iconFactory->getIcon('actions-edit-undo', Icon::SIZE_SMALL)->render() . ' '
. $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.revertSelection') . '</a>';
. $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.revertSelection') . '</button>';
}
if (is_array($group['header'])) {
$html[] = '<div id="' . $groupId . '" class="panel-collapse collapse" role="tabpanel">';
$html[] = '<div id="' . $groupIdCollapsible . '" class="panel-collapse collapse" role="tabpanel">';
}
$checkboxId = uniqid($groupId);
$title = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleall'));
......
......@@ -10,4 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
define(["require","exports","jquery","TYPO3/CMS/Backend/FormEngine"],function(e,t,n,c){"use strict";var l,r;return(r=l||(l={})).toggleAll=".t3js-toggle-checkboxes",r.singleItem=".t3js-checkbox",function(){function e(e){var t=this;this.checkBoxId="",this.$table=null,this.checkBoxId=e,n(function(){t.$table=n("#"+e).closest("table"),t.enableTriggerCheckBox(),t.registerEventHandler()})}return e.allCheckBoxesAreChecked=function(e){return e.length===e.filter(":checked").length},e.prototype.registerEventHandler=function(){var t=this;n(this.$table).on("change",l.toggleAll,function(r){var i=n(r.currentTarget),o=t.$table.find(l.singleItem),h=!e.allCheckBoxesAreChecked(o);o.prop("checked",h),i.prop("checked",h),c.Validation.markFieldAsChanged(i)}).on("change",l.singleItem,function(){var n=t.$table.find(l.singleItem),c=e.allCheckBoxesAreChecked(n);t.$table.find(l.toggleAll).prop("checked",c)})},e.prototype.enableTriggerCheckBox=function(){var t=this.$table.find(l.singleItem),c=e.allCheckBoxesAreChecked(t);n("#"+this.checkBoxId).prop("checked",c)},e}()});
\ No newline at end of file
define(["require","exports","jquery","TYPO3/CMS/Backend/FormEngine"],function(e,t,n,c){"use strict";var l,i;return(i=l||(l={})).toggleAll=".t3js-toggle-checkboxes",i.singleItem=".t3js-checkbox",i.revertSelection=".t3js-revert-selection",function(){function e(e){var t=this;this.checkBoxId="",this.$table=null,this.checkedBoxes=null,this.checkBoxId=e,n(function(){t.$table=n("#"+e).closest("table"),t.checkedBoxes=t.$table.find(l.singleItem+":checked"),t.enableTriggerCheckBox(),t.registerEventHandler()})}return e.allCheckBoxesAreChecked=function(e){return e.length===e.filter(":checked").length},e.prototype.registerEventHandler=function(){var t=this;this.$table.on("change",l.toggleAll,function(i){var o=n(i.currentTarget),r=t.$table.find(l.singleItem),h=!e.allCheckBoxesAreChecked(r);r.prop("checked",h),o.prop("checked",h),c.Validation.markFieldAsChanged(o)}).on("change",l.singleItem,function(){t.setToggleAllState()}).on("click",l.revertSelection,function(){t.$table.find(l.singleItem).each(function(e,n){n.checked=t.checkedBoxes.index(n)>-1}),t.setToggleAllState()})},e.prototype.setToggleAllState=function(){var t=this.$table.find(l.singleItem),n=e.allCheckBoxesAreChecked(t);this.$table.find(l.toggleAll).prop("checked",n)},e.prototype.enableTriggerCheckBox=function(){var t=this.$table.find(l.singleItem),c=e.allCheckBoxesAreChecked(t);n("#"+this.checkBoxId).prop("checked",c)},e}()});
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment