[CLEANUP] FormEngine rendermode checkbox to bootstrap 27/35827/3
authorBenjamin Kott <benjamin.kott@outlook.com>
Tue, 6 Jan 2015 15:46:04 +0000 (16:46 +0100)
committerBenjamin Mack <benni@typo3.org>
Wed, 7 Jan 2015 16:34:23 +0000 (17:34 +0100)
- convert rendermode checkbox to bootstrap
- enhance visualisation of grouping
- make groups collapsable
- move reset all to group level
- move toggle all to group level
- make lists more accessible

Releases: master
Resolves: #64146
Change-Id: I78af271fe313f75490e4dfe05c6bc800ea986e8e
Reviewed-on: http://review.typo3.org/35827
Tested-by: Stefan Froemken <froemken@gmail.com>
Tested-by: Benjamin Mack <benni@typo3.org>
Reviewed-by: Felix Kopp <felix-source@phorax.com>
Tested-by: Felix Kopp <felix-source@phorax.com>
Reviewed-by: Benjamin Mack <benni@typo3.org>
typo3/sysext/backend/Classes/Form/Element/SelectElement.php
typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_element_label.less
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_element_panel.less
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_element_table.less
typo3/sysext/t3skin/Resources/Public/Css/visual/t3skin.css
typo3/sysext/tstemplate/Classes/Controller/TypoScriptTemplateObjectBrowserModuleFunctionController.php

index ee5e93c..8fdd660 100644 (file)
@@ -554,17 +554,17 @@ class SelectElement extends AbstractFormElement {
                }
                // Get values in an array (and make unique, which is fine because there can be no duplicates anyway):
                $itemArray = array_flip($this->formEngine->extractValuesOnlyFromValueLabelList($PA['itemFormElValue']));
-               $item = '';
-               $disabled = '';
+               $output = '';
+
+               // Disabled
+               $disabled = 0;
                if ($this->isRenderReadonly() || $config['readOnly']) {
-                       $disabled = ' disabled="disabled"';
+                       $disabled = 1;
                }
                // Traverse the Array of selector box items:
-               $tRows = array();
+               $groups = array();
+               $currentGroup = 0;
                $c = 0;
-               $setAll = array();
-               $unSetAll = array();
-               $restoreCmd = array();
                $sOnChange = '';
                if (!$disabled) {
                        $sOnChange = implode('', $PA['fieldChangeFunc']);
@@ -576,32 +576,13 @@ class SelectElement extends AbstractFormElement {
                                        if (isset($p[2]) && $p[2] != 'empty-emtpy') {
                                                $selIcon = $this->formEngine->getIconHtml($p[2]);
                                        }
-                                       $tRows[] = '
-                                               <tr class="c-header">
-                                                       <td colspan="3">' . $selIcon . htmlspecialchars($p[0]) . '</td>
-                                               </tr>';
+                                       $currentGroup++;
+                                       $groups[$currentGroup]['header'] = array(
+                                               'icon' => $selIcon,
+                                               'title' => htmlspecialchars($p[0])
+                                       );
                                } else {
-                                       // Selected or not by default:
-                                       $sM = '';
-                                       if (isset($itemArray[$p[1]])) {
-                                               $sM = ' checked="checked"';
-                                               unset($itemArray[$p[1]]);
-                                       }
-                                       // Icon:
-                                       if (!empty($p[2])) {
-                                               $selIcon = $this->formEngine->getIconHtml($p[2]);
-                                       } else {
-                                               $selIcon = IconUtility::getSpriteIcon('empty-empty');
-                                       }
-                                       // Compile row:
-                                       $rowId = str_replace('.', '', uniqid('select_checkbox_row_', TRUE));
-                                       $onClickCell = $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked=!' . $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked;';
-                                       $onClick = 'this.attributes.getNamedItem("class").nodeValue = ' . $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked ? "c-selectedItem" : "c-unselectedItem";';
-                                       $setAll[] = $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked=1;';
-                                       $setAll[] = '$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');$(\'' . $rowId . '\').addClassName(\'c-selectedItem\');';
-                                       $unSetAll[] = $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked=0;';
-                                       $unSetAll[] = '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').addClassName(\'c-unselectedItem\');';
-                                       $restoreCmd[] = $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked=' . ($sM ? 1 : 0) . ';' . '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');' . '$(\'' . $rowId . '\').addClassName(\'c-' . ($sM ? '' : 'un') . 'selectedItem\');';
+
                                        // Check if some help text is available
                                        // Since TYPO3 4.5 help text is expected to be an associative array
                                        // with two key, "title" and "description"
@@ -619,64 +600,143 @@ class SelectElement extends AbstractFormElement {
                                                        $helpArray['description'] = $p[3];
                                                }
                                        }
-                                       $label = htmlspecialchars($p[0], ENT_COMPAT, 'UTF-8', FALSE);
                                        if ($hasHelp) {
                                                $help = BackendUtility::wrapInHelp('', '', '', $helpArray);
                                        }
-                                       $tRows[] = '
-                                               <tr id="' . $rowId . '" class="' . ($sM ? 'c-selectedItem' : 'c-unselectedItem')
-                                               . '" onclick="' . htmlspecialchars($onClick) . '" style="cursor: pointer;">
-                                                       <td class="c-checkbox"><input type="checkbox" class="' . $this->cssClassTypeElementPrefix . 'check"'
-                                               . ' name="' . htmlspecialchars(($PA['itemFormElName'] . '[' . $c . ']'))
-                                               . '" value="' . htmlspecialchars($p[1]) . '"' . $sM . ' onclick="' . htmlspecialchars($sOnChange)
-                                               . '"' . $PA['onFocus'] . ' /></td>
-                                                       <td class="c-labelCell" onclick="' . htmlspecialchars($onClickCell) . '">' . $selIcon . $label . '</td>
-                                                               <td class="c-descr" onclick="' . htmlspecialchars($onClickCell) . '">' . (empty($help) ? '' : $help) . '</td>
-                                               </tr>';
+
+                                       // Selected or not by default:
+                                       $checked = 0;
+                                       if (isset($itemArray[$p[1]])) {
+                                               $checked = 1;
+                                               unset($itemArray[$p[1]]);
+                                       }
+
+                                       // Build item array
+                                       $groups[$currentGroup]['items'][] = array(
+                                               'id' => str_replace('.', '', uniqid('select_checkbox_row_', TRUE)),
+                                               'name' => $PA['itemFormElName'] . '[' . $c . ']',
+                                               'value' => $p[1],
+                                               'checked' => $checked,
+                                               'disabled' => $disabled,
+                                               'class' => '',
+                                               'icon' => (!empty($p[2]) ? $this->formEngine->getIconHtml($p[2]) : IconUtility::getSpriteIcon('empty-empty')),
+                                               'title' => htmlspecialchars($p[0], ENT_COMPAT, 'UTF-8', FALSE),
+                                               'help' => $help
+                                       );
                                        $c++;
                                }
                        }
                }
                // Remaining values (invalid):
                if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
+                       $currentGroup++;
                        foreach ($itemArray as $theNoMatchValue => $temp) {
-                               // Compile <checkboxes> tag:
-                               array_unshift($tRows, '
-                                               <tr class="c-invalidItem">
-                                                       <td class="c-checkbox"><input type="checkbox" class="' . $this->cssClassTypeElementPrefix . 'check"'
-                                       . ' name="' . htmlspecialchars(($PA['itemFormElName'] . '[' . $c . ']'))
-                                       . '" value="' . htmlspecialchars($theNoMatchValue) . '" checked="checked" onclick="' . htmlspecialchars($sOnChange) . '"'
-                                       . $PA['onFocus'] . $disabled . ' /></td>
-                                                       <td class="c-labelCell">' . htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue), ENT_COMPAT, 'UTF-8', FALSE) . '</td><td>&nbsp;</td>
-                                               </tr>');
+                               // Build item array
+                               $groups[$currentGroup]['items'][] = array(
+                                       'id' => str_replace('.', '', uniqid('select_checkbox_row_', TRUE)),
+                                       'name' => $PA['itemFormElName'] . '[' . $c . ']',
+                                       'value' => $theNoMatchValue,
+                                       'checked' => 1,
+                                       'disabled' => $disabled,
+                                       'class' => 'danger',
+                                       'icon' => '',
+                                       'title' => htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue), ENT_COMPAT, 'UTF-8', FALSE),
+                                       'help' => ''
+                               );
                                $c++;
                        }
                }
                // Add an empty hidden field which will send a blank value if all items are unselected.
-               $item .= '<input type="hidden" class="select-checkbox" name="' . htmlspecialchars($PA['itemFormElName']) . '" value="" />';
-               // Remaining checkboxes will get their set-all link:
-               $tableHead = '';
-               if (count($setAll)) {
-                       $tableHead = '<thead>
-                                       <tr class="c-header-checkbox-controls t3-row-header">
-                                               <td class="c-checkbox">
-                                               <input type="checkbox" class="checkbox" onclick="if (checked) {' . htmlspecialchars(implode('', $setAll) . '} else {' . implode('', $unSetAll)) . '}">
-                                               </td>
-                                               <td colspan="2">
-                                               </td>
-                                       </tr></thead>';
-               }
-               // Implode rows in table:
-               $item .= '
-                       <table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-select-checkbox">' . $tableHead . '<tbody>' . implode('', $tRows) . '</tbody>
-                       </table>
-                       ';
-               // Add revert icon
-               if (!empty($restoreCmd)) {
-                       $item .= '<a href="#" onclick="' . implode('', $restoreCmd) . ' return false;' . '">'
-                               . IconUtility::getSpriteIcon('actions-edit-undo', array('title' => htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.revertSelection')))) . '</a>';
+               $output .= '<input type="hidden" class="select-checkbox" name="' . htmlspecialchars($PA['itemFormElName']) . '" value="" />';
+
+               // Building the checkboxes
+               foreach($groups as $groupKey => $group){
+                       $groupId = htmlspecialchars($PA['itemFormElID']) . '-group-' . $groupKey;
+                       $output .= '<div class="panel panel-default">';
+                       if(is_array($group['header'])){
+                               $output .= '
+                                       <div class="panel-heading">
+                                               <a data-toggle="collapse" href="#' . $groupId . '" aria-expanded="true" aria-controls="' . $groupId . '">
+                                                       ' . $group['header']['icon'] . '
+                                                       ' . $group['header']['title'] . '
+                                               </a>
+                                       </div>
+                                       ';
+                       }
+                       if(is_array($group['items']) && count($group['items']) >= 1){
+                               $tableRows = '';
+                               $checkGroup = array();
+                               $uncheckGroup = array();
+                               $resetGroup = array();
+
+                               // Render rows
+                               foreach($group['items'] as $item){
+                                       $tableRows .= '
+                                               <tr class="' . $item['class'] . '">
+                                                       <td class="col-checkbox">
+                                                               <input type="checkbox"
+                                                                       id="' . $item['id'] . '"
+                                                                       name="' . htmlspecialchars($item['name']) . '"
+                                                                       value="' . htmlspecialchars($item['value']) . '"
+                                                                       onclick="' . htmlspecialchars($sOnChange) . '"
+                                                                       ' . ($item['checked'] ? ' checked=checked' : '') . '
+                                                                       ' . ($item['disabled'] ? ' disabled=disabled' : '') . '
+                                                                       ' . $PA['onFocus'] . ' />
+                                                       </td>
+                                                       <td class="col-icon">
+                                                               <label class="label-block" for="' . $item['id'] . '">' . $item['icon'] . '</label>
+                                                       </td>
+                                                       <td class="col-title">
+                                                               <label class="label-block" for="' . $item['id'] . '">' . $item['title'] . '</label>
+                                                       </td>
+                                                       <td>' . $item['help'] . '</td>
+                                               </tr>
+                                               ';
+                                       $checkGroup[] = $this->formEngine->elName($item['name']) . '.checked=1;';
+                                       $uncheckGroup[] = $this->formEngine->elName($item['name']) . '.checked=0;';
+                                       $resetGroup[] = $this->formEngine->elName($item['name']) . '.checked='.$item['checked'] . ';';
+                               }
+
+                               // Build toggle group checkbox
+                               $toggleGroupCheckbox = '';
+                               if(count($resetGroup)){
+                                       $toggleGroupCheckbox = '
+                                               <input type="checkbox" class="checkbox" onclick="if (checked) {' . htmlspecialchars(implode('', $checkGroup) . '} else {' . implode('', $uncheckGroup)) . '}">
+                                               ';
+                               }
+
+                               // Build reset group button
+                               $resetGroupBtn = '';
+                               if(count($resetGroup)){
+                                       $resetGroupBtn = '
+                                               <a href="#" class="btn btn-default" onclick="' . implode('', $resetGroup) . ' return false;' . '">
+                                                       ' . IconUtility::getSpriteIcon('actions-edit-undo', array('title' => htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.revertSelection')))) . '
+                                                       ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.revertSelection') . '
+                                               </a>
+                                               ';
+                               }
+
+                               $output .= '
+                                       <div id="' . $groupId . '" class="panel-collapse collapse in" role="tabpanel">
+                                               <div class="table-fit">
+                                                       <table class="table table-transparent table-hover">
+                                                               <thead>
+                                                                       <tr>
+                                                                               <th class="col-checkbox">' . $toggleGroupCheckbox . '</th>
+                                                                               <th class="col-icon"></th>
+                                                                               <th class="text-right" colspan="2">' . $resetGroupBtn . '</th>
+                                                                       </tr>
+                                                               </thead>
+                                                               <tbody>' . $tableRows . '</tbody>
+                                                       </table>
+                                               </div>
+                                       </div>
+                                       ';
+                       }
+                       $output .= '</div>';
                }
-               return $item;
+
+               return $output;
        }
 
        /**
index 476c45b..51e9b0c 100644 (file)
@@ -627,7 +627,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                        <!--
                                DB listing of elements: "' . htmlspecialchars($table) . '"
                        -->
-                               <div class="panel panel-default">
+                               <div class="panel panel-space panel-default">
                                        <div class="panel-heading">
                                        ' . $tableHeader . '
                                        </div>
index 4eb9427..64930e2 100644 (file)
@@ -8,4 +8,13 @@
 .label-obsolete:extend(.label-default){};
 .label-experimental:extend(.label-default){}
 .label-test:extend(.label-default){}
-.label-excludeFromUpdates:extend(.label-default){}
\ No newline at end of file
+.label-excludeFromUpdates:extend(.label-default){}
+
+.label-inline,
+.label-block {
+       margin: 0;
+       font-weight: normal;
+}
+.label-block {
+       display: block;
+}
\ No newline at end of file
index f3945ff..0e2b05e 100644 (file)
@@ -3,7 +3,6 @@
 //
 
 .panel {
-       margin: 3em 0;
        .panel-heading {
                font-weight: bold;
        }
@@ -13,3 +12,7 @@
                margin: 0;
        }
 }
+
+.panel-space {
+       margin: 3em 0;
+}
index c45ed9a..88daca8 100644 (file)
@@ -66,7 +66,7 @@ table {
                                vertical-align: middle;
                        }
                        > td {
-                               vertical-align: middle;
+                               vertical-align: middle!important; // @todo important needs to be removed as soon as .typo3-TCEforms .c-tablayer td is gone
                        }
                }
        }
@@ -164,14 +164,28 @@ table {
        }
 
        .col-icon {
+               text-align: center;
+
                .t3-icon {
                        margin: 0;
                }
-               text-align: center;
+
+               img {
+                       margin: 0;
+                       display: block;
+                       height: 16px;
+                       width: 16px;
+               }
+
+       }
+
+       .col-icon,
+       .col-checkbox {
+               padding-right: 0;
        }
 
        .col-title {
-               width: 95%;
+               width: 99%;
        }
 
        .col-control,
@@ -183,7 +197,13 @@ table {
        .col-border-left {
                border-left: 1px solid @table-border-color;
        }
+}
 
+//
+// Sets the background back to transparent
+//
+.table-transparent {
+       background-color: transparent;
 }
 
 //
index 5382124..d3e531d 100644 (file)
@@ -8433,7 +8433,7 @@ table {
 .table > thead > tr > td,
 .table > tbody > tr > td,
 .table > tfoot > tr > td {
-  vertical-align: middle;
+  vertical-align: middle!important;
 }
 .table > thead > tr {
   background-color: #ededed;
@@ -8818,8 +8818,18 @@ fieldset[disabled] .table .btn-checkbox-holder input[type=checkbox]:checked + .b
 .table .col-icon .t3-icon {
   margin: 0;
 }
+.table .col-icon img {
+  margin: 0;
+  display: block;
+  height: 16px;
+  width: 16px;
+}
+.table .col-icon,
+.table .col-checkbox {
+  padding-right: 0;
+}
 .table .col-title {
-  width: 95%;
+  width: 99%;
 }
 .table .col-control,
 .table .col-clipboard {
@@ -8829,6 +8839,9 @@ fieldset[disabled] .table .btn-checkbox-holder input[type=checkbox]:checked + .b
 .table .col-border-left {
   border-left: 1px solid #cccccc;
 }
+.table-transparent {
+  background-color: transparent;
+}
 .table-fit {
   width: 100%;
   margin-bottom: 1.5em;
@@ -8862,9 +8875,6 @@ fieldset[disabled] .table .btn-checkbox-holder input[type=checkbox]:checked + .b
 .table-fit > .table tr:last-child td {
   border-bottom: 0;
 }
-.panel {
-  margin: 3em 0;
-}
 .panel .panel-heading {
   font-weight: bold;
 }
@@ -8873,6 +8883,9 @@ fieldset[disabled] .table .btn-checkbox-holder input[type=checkbox]:checked + .b
   border: 0;
   margin: 0;
 }
+.panel-space {
+  margin: 3em 0;
+}
 .typo3-TCEforms .typo3-dyntabmenu-divs {
   border-top: 1px solid #cccccc;
 }
@@ -9834,6 +9847,14 @@ table#typo3-tree tr:hover {
 .pagination-block {
   display: block;
 }
+.label-inline,
+.label-block {
+  margin: 0;
+  font-weight: normal;
+}
+.label-block {
+  display: block;
+}
 @font-face {
   font-family: 'Share';
   src: url('../../Fonts/share-bold-webfont.eot');
index 13c2691..4f80d62 100644 (file)
@@ -446,7 +446,7 @@ class TypoScriptTemplateObjectBrowserModuleFunctionController extends AbstractFu
                        $label = $theKey ? $theKey : ($bType == 'setup' ? $lang->csConvObj->conv_case($lang->charSet, $lang->getLL('setupRoot'), 'toUpper') : $lang->csConvObj->conv_case($lang->charSet, $lang->getLL('constantRoot'), 'toUpper'));
                        $theOutput .= $this->pObj->doc->sectionEnd();
 
-                       $theOutput .= '<div class="panel panel-default">';
+                       $theOutput .= '<div class="panel panel-space panel-default">';
                        $theOutput .= '<div class="panel-heading">';
                        $theOutput .= '<strong>' . $label . ' ' . $remove . '</strong>';
                        $theOutput .= '</div>';