[FEATURE] Usability improvements by top searchbox in list module 97/30997/13
authorFrank Nägler <typo3@naegler.net>
Sat, 21 Jun 2014 13:10:41 +0000 (15:10 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Mon, 29 Sep 2014 12:10:03 +0000 (14:10 +0200)
For a better user experience in the list module, it makes sense to display
the search box at the top and not at the bottom of the page.
If a user works with a lot of records in the list module it is really
annoying to scroll down, the position in the top is more ergonomic.

With the new search icon in the doc header it is possible to toggle the
new search toolbar. if the user enter a search term and the results in
the list module are filtered, the search toolbar is visible by default.

This patch works also with the searchbox in the page module. The
searchbox in the ElementBrowser is always visible, but also now on top
above the table.

Resolves: #59763
Documentation: #59763
Related: #61777
Releases: master
Change-Id: I25e81b5f5b914cb75bf30de16fcc2da9edd7f6e6
Reviewed-on: http://review.typo3.org/30997
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Felix Kopp <felix-source@phorax.com>
Reviewed-by: Tymoteusz Motylewski <t.motylewski@gmail.com>
Tested-by: Tymoteusz Motylewski <t.motylewski@gmail.com>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/backend/Classes/Controller/PageLayoutController.php
typo3/sysext/backend/Resources/Private/Templates/db_layout.html
typo3/sysext/lang/locallang_core.xlf
typo3/sysext/recordlist/Classes/Browser/ElementBrowser.php
typo3/sysext/recordlist/Classes/RecordList.php
typo3/sysext/recordlist/Classes/RecordList/AbstractDatabaseRecordList.php
typo3/sysext/recordlist/Resources/Private/Templates/db_list.html
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/structure/_module_web_list.less
typo3/sysext/t3skin/Resources/Public/Css/visual/t3kin.css

index 09cc61c..8abcf05 100644 (file)
@@ -223,6 +223,11 @@ class PageLayoutController {
        public $activeColPosList;
 
        /**
+        * @var array markers array
+        */
+       protected $markers = array();
+
+       /**
         * Initializing the module
         *
         * @return void
@@ -254,6 +259,9 @@ class PageLayoutController {
                $this->current_sys_language = (int)$this->MOD_SETTINGS['language'];
                // CSH / Descriptions:
                $this->descrTable = '_MOD_' . $this->MCONF['name'];
+
+               $this->markers['SEARCHBOX'] = '';
+               $this->markers['BUTTONLIST_ADDITIONAL'] = '';
        }
 
        /**
@@ -568,14 +576,12 @@ class PageLayoutController {
                        }
                        // Setting up the buttons and markers for docheader
                        $docHeaderButtons = $this->getButtons($this->MOD_SETTINGS['function'] == 0 ? 'quickEdit' : '');
-                       $markers = array(
-                               'CSH' => $docHeaderButtons['csh'],
-                               'TOP_FUNCTION_MENU' => $this->topFuncMenu . $this->editSelect,
-                               'LANGSELECTOR' => $this->languageMenu,
-                               'CONTENT' => $body
-                       );
+                       $this->markers['CSH'] = $docHeaderButtons['csh'];
+                       $this->markers['TOP_FUNCTION_MENU'] = $this->topFuncMenu . $this->editSelect;
+                       $this->markers['LANGSELECTOR'] = $this->languageMenu;
+                       $this->markers['CONTENT'] = $body;
                        // Build the <body> for the module
-                       $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
+                       $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $this->markers);
                        // Renders the module page
                        $this->content = $this->doc->render($GLOBALS['LANG']->getLL('title'), $this->content);
                } else {
@@ -608,13 +614,11 @@ class PageLayoutController {
                                'history_record' => '',
                                'edit_language' => ''
                        );
-                       $markers = array(
-                               'CSH' => BackendUtility::cshItem($this->descrTable, '', $GLOBALS['BACK_PATH'], '', TRUE),
-                               'TOP_FUNCTION_MENU' => '',
-                               'LANGSELECTOR' => '',
-                               'CONTENT' => $body
-                       );
-                       $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
+                       $this->markers['CSH'] = BackendUtility::cshItem($this->descrTable, '', $GLOBALS['BACK_PATH'], '', TRUE);
+                       $this->markers['TOP_FUNCTION_MENU'] = '';
+                       $this->markers['LANGSELECTOR'] = '';
+                       $this->markers['CONTENT'] = $body;
+                       $this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $this->markers);
                        // Renders the module page
                        $this->content = $this->doc->render($GLOBALS['LANG']->getLL('title'), $this->content);
                }
@@ -1023,8 +1027,8 @@ class PageLayoutController {
                }
                // Making search form:
                if (!$this->modTSconfig['properties']['disableSearchBox'] && count($tableOutput)) {
-                       $sectionTitle = BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_searchbox', $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.search', TRUE));
-                       $content .= $this->doc->section($sectionTitle, $dblist->getSearchBox(0), FALSE, TRUE, FALSE, TRUE);
+                       $this->markers['BUTTONLIST_ADDITIONAL'] = '<a href="#" onclick="toggleSearchToolbox(); return false;" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.title.searchIcon', TRUE) . '">'.\TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('apps-toolbar-menu-search').'</a>';
+                       $this->markers['SEARCHBOX'] = $dblist->getSearchBox(0);
                }
                // Additional footer content
                $footerContentHook = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawFooterHook'];
index 2658425..347f5e9 100644 (file)
@@ -6,11 +6,20 @@
                        <div class="right">###PAGEPATH###</div>
                </div>
                <div class="typo3-docheader-buttons">
-                       <div class="left">###BUTTONLIST_LEFT###</div>
+                       <div class="left">###BUTTONLIST_LEFT### <div class="buttongroup">###BUTTONLIST_ADDITIONAL###</div></div>
                        <div class="right">###BUTTONLIST_RIGHT###</div>
                </div>
+               ###SEARCHBOX###
        </div>
-
+       <script>
+               function toggleSearchToolbox() {
+                       if (document.getElementById('db_list-searchbox-toolbar').style.display == 'none') {
+                               document.getElementById('db_list-searchbox-toolbar').style.display = 'block';
+                       } else {
+                               document.getElementById('db_list-searchbox-toolbar').style.display = 'none';
+                       }
+               }
+       </script>
        <div id="typo3-docbody">
                <div id="typo3-inner-docbody">
                        ###CONTENT###
index ce1c032..2376128 100644 (file)
@@ -61,7 +61,7 @@
                                <source>Collapse table</source>
                        </trans-unit>
                        <trans-unit id="labels.enterSearchString" xml:space="preserve">
-                               <source>Search String:</source>
+                               <source>Enter search term</source>
                        </trans-unit>
                        <trans-unit id="labels.enterSearchLevels" xml:space="preserve">
                                <source>This page|1 level down|2 levels down|3 levels down|4 levels down</source>
@@ -346,6 +346,30 @@ Do you want to continue WITHOUT saving?</source>
                        <trans-unit id="labels.noRecordFound" xml:space="preserve">
                                <source>No record found</source>
                        </trans-unit>
+                       <trans-unit id="labels.title.searchIcon" xml:space="preserve">
+                               <source>Toggle search toolbar</source>
+                       </trans-unit>
+                       <trans-unit id="labels.title.searchString" xml:space="preserve">
+                               <source>Search term</source>
+                       </trans-unit>
+                       <trans-unit id="labels.title.limit" xml:space="preserve">
+                               <source>Limit</source>
+                       </trans-unit>
+                       <trans-unit id="labels.title.search" xml:space="preserve">
+                               <source>Search</source>
+                       </trans-unit>
+                       <trans-unit id="labels.title.search_levels" xml:space="preserve">
+                               <source>Search levels</source>
+                       </trans-unit>
+                       <trans-unit id="labels.label.searchString" xml:space="preserve">
+                               <source>Search term</source>
+                       </trans-unit>
+                       <trans-unit id="labels.label.limit" xml:space="preserve">
+                               <source>Limit</source>
+                       </trans-unit>
+                       <trans-unit id="labels.label.search_levels" xml:space="preserve">
+                               <source>Search levels</source>
+                       </trans-unit>
                        <trans-unit id="alttext.suggestSearching" xml:space="preserve">
                                <source>Searching...</source>
                        </trans-unit>
index 275f0ab..a54cd27 100644 (file)
@@ -1778,13 +1778,15 @@ class ElementBrowser {
                );
                $dbList->setDispFields();
                $dbList->generateList();
+               $out .= $dbList->getSearchBox();
+               $out .= "<script>document.getElementById('db_list-searchbox-toolbar').style.display = 'block';document.getElementById('db_list-searchbox-toolbar').style.position = 'relative';</script>";
+
                //      Add the HTML for the record list to output variable:
                $out .= $dbList->HTMLcode;
                // Add support for fieldselectbox in singleTableMode
                if ($dbList->table) {
                        $out .= $dbList->fieldSelectBox($dbList->table);
                }
-               $out .= $dbList->getSearchBox();
 
                // Return accumulated content:
                return $out;
index 0ae7ce0..66eac9f 100644 (file)
@@ -444,11 +444,6 @@ class RecordList {
                if ($this->MOD_SETTINGS['clipBoard'] && $dblist->showClipboard && ($dblist->HTMLcode || $dblist->clipObj->hasElements())) {
                        $this->body .= '<div class="db_list-dashboard">' . $dblist->clipObj->printClipboard() . '</div>';
                }
-               // Search box:
-               if (!$this->modTSconfig['properties']['disableSearchBox'] && ($dblist->HTMLcode || $dblist->searchString !== '')) {
-                       $sectionTitle = BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_searchbox', $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.search', TRUE));
-                       $this->body .= '<div class="db_list-searchbox">' . $this->doc->section($sectionTitle, $dblist->getSearchBox(), FALSE, TRUE, FALSE, TRUE) . '</div>';
-               }
                // Additional footer content
                $footerContentHook = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['recordlist/mod1/index.php']['drawFooterHook'];
                if (is_array($footerContentHook)) {
@@ -462,8 +457,16 @@ class RecordList {
                $markers = array(
                        'CSH' => $docHeaderButtons['csh'],
                        'CONTENT' => $this->body,
-                       'EXTRACONTAINERCLASS' => $this->table ? 'singletable' : ''
+                       'EXTRACONTAINERCLASS' => $this->table ? 'singletable' : '',
+                       'BUTTONLIST_ADDITIONAL' => '',
+                       'SEARCHBOX' => '',
+                       'BUTTONLIST_ADDITIONAL' => ''
                );
+               // searchbox toolbar
+               if (!$this->modTSconfig['properties']['disableSearchBox'] && ($dblist->HTMLcode || !empty($dblist->searchString))) {
+                       $markers['SEARCHBOX'] = $dblist->getSearchBox();
+                       $markers['BUTTONLIST_ADDITIONAL'] = '<a href="#" onclick="toggleSearchToolbox(); return false;" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.title.searchIcon', TRUE) . '">'.\TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('apps-toolbar-menu-search').'</a>';
+               }
                // Build the <body> for the module
                $this->content = $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
                // Renders the module page
index 0f7de0c..43f8e89 100644 (file)
@@ -460,27 +460,19 @@ class AbstractDatabaseRecordList extends \TYPO3\CMS\Backend\RecordList\AbstractR
                foreach ($parts as $kv => $label) {
                        $opt[] = '<option value="' . $kv . '"' . ($kv == (int)$this->searchLevels ? ' selected="selected"' : '') . '>' . htmlspecialchars($label) . '</option>';
                }
-               $lMenu = '<select name="search_levels">' . implode('', $opt) . '</select>';
+               $lMenu = '<select name="search_levels" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.title.search_levels', TRUE) . '" id="search_levels">' . implode('', $opt) . '</select>';
                // Table with the search box:
-               $content = '<div class="db_list-searchbox-form">
+               $content = '<div class="db_list-searchbox-form db_list-searchbox-toolbar" id="db_list-searchbox-toolbar" style="display: ' . ($this->searchString == '' ? 'none' : 'block') . ';">
                        ' . $formElements[0] . '
-
-                               <!--
-                                       Search box:
-                               -->
-                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-dblist-search">
-                                       <tr>
-                                               <td><label for="search_field">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.enterSearchString', TRUE) . '</label></td>
-                                               <td><input type="search" name="search_field" id="search_field" value="' . htmlspecialchars($this->searchString) . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . ' /></td>
-                                               <td>' . $lMenu . '</td>
-                                               <td><input type="submit" name="search" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.search', TRUE) . '" /></td>
-                                       </tr>
-                                       <tr>
-                                               <td><label for="showLimit">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.showRecords', TRUE) . ':</label></td>
-                                               <td colspan="3"><input type="number" name="showLimit" id="showLimit" value="' . htmlspecialchars(($this->showLimit ? $this->showLimit : '')) . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(5) . ' /></td>
-                                       </tr>
-                               </table>
-                       ' . $formElements[1] . '</div>';
+                               <div id="typo3-dblist-search">
+                                       <label for="search_field">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.label.searchString', TRUE) . ': </label>
+                                       <input type="search" placeholder="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.enterSearchString', TRUE) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.title.searchString', TRUE) . '" name="search_field" id="search_field" value="' . htmlspecialchars($this->searchString) . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(15) . ' />
+                                       <label for="search_levels">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.label.search_levels', TRUE) . ': </label>
+                                       ' . $lMenu . '
+                                       <label for="showLimit">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.label.limit', TRUE) . ': </label>
+                                       <input type="number" placeholder="10" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.title.limit', TRUE) . '" name="showLimit" id="showLimit" value="' . htmlspecialchars(($this->showLimit ? $this->showLimit : '')) . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(5) . ' />
+                                       <input type="submit" name="search" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.search', TRUE) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.title.search', TRUE) . '" />
+                       ' . $formElements[1] . '</div></div>';
                return $content;
        }
 
index 2ade052..0122bb1 100644 (file)
@@ -6,11 +6,20 @@
                        <div class="right">###PAGEPATH###</div>
                </div>
                <div class="typo3-docheader-buttons">
-                       <div class="left">###BUTTONLIST_LEFT###</div>
+                       <div class="left">###BUTTONLIST_LEFT### <div class="buttongroup">###BUTTONLIST_ADDITIONAL###</div></div>
                        <div class="right">###BUTTONLIST_RIGHT###</div>
                </div>
+        ###SEARCHBOX###
        </div>
-
+    <script>
+        function toggleSearchToolbox() {
+           if (document.getElementById('db_list-searchbox-toolbar').style.display == 'none') {
+               document.getElementById('db_list-searchbox-toolbar').style.display = 'block';
+           } else {
+               document.getElementById('db_list-searchbox-toolbar').style.display = 'none';
+           }
+        }
+    </script>
        <div id="typo3-docbody">
                <div id="typo3-inner-docbody">
                        ###CONTENT###
index 26e45cb..0defc93 100644 (file)
@@ -202,4 +202,23 @@ div#typo3-dblist-pagination span.bar {
        height: 8px;
        padding: 4px 5px;
        width: 7px;
+}
+
+.db_list-searchbox-toolbar {
+    background: #dadada;
+    border-top: 1px solid #b3b3b3;
+    padding: 5px 5px 0 5px;
+    position: absolute;
+    z-index: 2000;
+    width: 100%;
+}
+
+#typo3-docheader .db_list-searchbox-toolbar input {
+    cursor: auto !important;
+    margin-right: 10px !important;
+}
+
+#typo3-docheader .db_list-searchbox-toolbar select {
+    vertical-align: text-bottom !important;
+    margin-right: 10px !important;
 }
\ No newline at end of file
index 168beb9..276c30a 100644 (file)
@@ -9906,6 +9906,22 @@ div#typo3-dblist-pagination span.bar {
   padding: 4px 5px;
   width: 7px;
 }
+.db_list-searchbox-toolbar {
+  background: #dadada;
+  border-top: 1px solid #b3b3b3;
+  padding: 5px 5px 0 5px;
+  position: absolute;
+  z-index: 2000;
+  width: 100%;
+}
+#typo3-docheader .db_list-searchbox-toolbar input {
+  cursor: auto !important;
+  margin-right: 10px !important;
+}
+#typo3-docheader .db_list-searchbox-toolbar select {
+  vertical-align: text-bottom !important;
+  margin-right: 10px !important;
+}
 /**
  * This file is part of the TYPO3 CMS project.
  *