[!!!][TASK] This is FormEngine 51/35951/35
authorBenjamin Kott <benjamin.kott@outlook.com>
Sat, 10 Jan 2015 23:31:58 +0000 (00:31 +0100)
committerWouter Wolters <typo3@wouterwolters.nl>
Mon, 2 Feb 2015 19:45:03 +0000 (20:45 +0100)
The patch brings responsive layout for FormEngine and its
elements. It fixes a couple of issues along the way,
escpecially DatePicker and palettes field are aligned in
a better way and wizard icons look much better.

Adjustments:
- Change datepicker to work directly on input without wrapper
- Change clearableJs to bootstrap
- Change dyntabs to bootstrap classes
- Change fixed-font to text-monospace
- Port CheckboxElement to boostrap
- Port GroupElement to bootstrap
- Port InputElement to bootstrap
- Port Irre/Inline to bootstrap
- Port Flexform to bootstrap
- Port Palettes to bootstrap
- Port RadioElements to bootstrap
- Port TextElement to bootstrap
- Port NoneElement to bootstrap

Removes:
- Unused change image javascript removed

Deprecations:
- cssClassTypeElementPrefix not used anymore
- maxTextareaWidth not used anymore
- paletteFieldTemplate not used anymore
- palFieldTemplateHeader not used anymore
- wizard config _PADDING
- wizard config _DISTANCE
- wrapOpenPalette not used anymore
- wrapPaletteField not used anymore
- formWidth not used anymore
- formWidthAsArray not used anymore
- addUserTemplateMarkers not used anymore

Releases: master
Resolves: #64762
Change-Id: I04ce24e63d2395fe25f7d5a314f5868882b2cd74
Reviewed-on: http://review.typo3.org/35951
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Tested-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Reviewed-by: Michael Oehlhof <typo3@oehlhof.de>
Tested-by: Michael Oehlhof <typo3@oehlhof.de>
Reviewed-by: Frederic Gaus <gaus@flagbit.de>
Tested-by: Frederic Gaus <gaus@flagbit.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
55 files changed:
typo3/contrib/jquery/jquery.clearable.js
typo3/sysext/backend/Classes/Controller/File/EditFileController.php
typo3/sysext/backend/Classes/Controller/PageLayoutController.php
typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
typo3/sysext/backend/Classes/Form/Element/CheckboxElement.php
typo3/sysext/backend/Classes/Form/Element/FlexElement.php
typo3/sysext/backend/Classes/Form/Element/GroupElement.php
typo3/sysext/backend/Classes/Form/Element/InlineElement.php
typo3/sysext/backend/Classes/Form/Element/InputElement.php
typo3/sysext/backend/Classes/Form/Element/RadioElement.php
typo3/sysext/backend/Classes/Form/Element/SelectElement.php
typo3/sysext/backend/Classes/Form/Element/SuggestElement.php
typo3/sysext/backend/Classes/Form/Element/TextElement.php
typo3/sysext/backend/Classes/Form/FormEngine.php
typo3/sysext/backend/Classes/Template/DocumentTemplate.php
typo3/sysext/backend/Resources/Private/Templates/FormEngine.html
typo3/sysext/backend/Resources/Public/JavaScript/DateTimePicker.js
typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js
typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js
typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.tbe_editor.js
typo3/sysext/backend/Resources/Public/JavaScript/tabmenu.js
typo3/sysext/belog/Resources/Private/Partials/Content/Filter.html
typo3/sysext/cms/flexform_media.xml
typo3/sysext/core/Classes/Database/QueryView.php
typo3/sysext/core/Configuration/TCA/be_groups.php
typo3/sysext/core/Configuration/TCA/be_users.php
typo3/sysext/core/Configuration/TCA/sys_file_reference.php
typo3/sysext/core/Configuration/TCA/sys_news.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-64762-FormEngineWizards.rst [new file with mode: 0644]
typo3/sysext/core/Documentation/Changelog/master/Deprecation-63850-FormEngine-insertDefStyle.rst
typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/Blog.php
typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/Post.php
typo3/sysext/frontend/Configuration/TCA/backend_layout.php
typo3/sysext/frontend/Configuration/TCA/sys_template.php
typo3/sysext/frontend/Configuration/TCA/tt_content.php
typo3/sysext/impexp/Tests/Functional/Fixtures/Extensions/impexp_group_files/Configuration/TCA/tx_impexpgroupfiles_item.php
typo3/sysext/openid/Configuration/TCA/Overrides/be_users.php
typo3/sysext/openid/Configuration/TCA/Overrides/fe_users.php
typo3/sysext/scheduler/Classes/Controller/SchedulerModuleController.php
typo3/sysext/setup/Classes/Controller/SetupModuleController.php
typo3/sysext/t3editor/Classes/FormWizard.php
typo3/sysext/t3editor/Classes/Hook/FileEditHook.php
typo3/sysext/t3editor/Classes/Hook/TypoScriptTemplateInfoHook.php
typo3/sysext/t3skin/Classes/Slot/IconStyleModifier.php
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_element_panel.less
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_element_tab.less
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_element_table.less
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_element_tceforms.less
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_main_form.less
typo3/sysext/t3skin/Resources/Private/Styles/TYPO3/_main_type.less
typo3/sysext/t3skin/Resources/Private/Styles/bootstrap/variables.less
typo3/sysext/t3skin/Resources/Public/Css/visual/t3skin.css
typo3/sysext/tstemplate/Classes/Controller/TypoScriptTemplateInformationModuleFunctionController.php
typo3/sysext/workspaces/Resources/Private/Layouts/Module.html
typo3/sysext/workspaces/Resources/Public/StyleSheet/module.css

index 6def681..69ba899 100644 (file)
                        if (!$input.data('clearable')) {
                                $input.data('clearable', 'loaded');
 
-                               var $inputFieldWithValue = $input;
-                               // the hidden field that holds the real data, used in FormEngine
-                               if ($input.next('input[type=hidden]').length) {
-                                       $inputFieldWithValue = $input.next('input[type=hidden]');
-                               }
-
                                // Wrap it with a div and add a span that is the trigger for
                                // clearing.
-                               $input.wrap('<div class="t3-clearable-wrapper"/>');
-                               $input.after('<span class="t3-icon t3-icon-actions t3-icon-actions-input t3-icon-input-clear t3-input-clearer"/>');
-                               $input.addClass('t3-clearable');
+                               $input.wrap('<div class="form-control-clearable" />');
+                               $input.after('<button class="close"><span class="fa fa-times" /></button>');
+                               $input.addClass('t3js-clearable');
 
-                               var $wrapper = $input.parent();
                                var $clearer = $input.next();
 
-                               // Add some data to the wrapper indicating if it is currently being
-                               // hovered or not.
-                               $input.data('isHovering', false);
-                               $wrapper.hover(function() {
-                                       $input.data('isHovering', true);
-                               }, function() {
-                                       $input.data('isHovering', false);
-                               });
-
                                // Register a listener the various events triggering the clearer to
                                // be shown or hidden.
                                var handler = function() {
-                                       var value = $inputFieldWithValue.val();
+                                       $element = $(this);
+                                       if ($element.next('input[type=hidden]').length) {
+                                               $element = $element.next('input[type=hidden]');
+                                       }
+                                       var value = $element.val();
                                        var hasEmptyValue = (value.length === 0);
-                                       if (value == "0" && $inputFieldWithValue.closest('.date').length) {
+                                       if (value === "0" && $element.closest('.t3js-datetimepicker').length) {
                                                hasEmptyValue = true;
                                        }
+
                                        // only show the clearing button if the value is set, or if the value is not "0" on a datetime field
-                                       if ($input.data('isHovering') && !hasEmptyValue) {
+                                       if (!hasEmptyValue) {
                                                $clearer.show();
                                        } else {
                                                $clearer.hide();
                                        }
                                };
-
-                               $wrapper.on('mouseover mouseout', handler);
-                               $input.on('keypress', handler);
-
+                               $input.on('keyup', handler);
+                               $input.on('mouseenter', handler);
+                               $input.on('change', handler);
+                               $input.on('initialize', handler);
 
                                // The actual clearing action. Focus the input element afterwards,
                                // the user probably wants to type into it after clearing.
-                               $clearer.click(function() {
-                                       $input.val('').change().focus();
-                                       handler();
+                               $clearer.click(function(e) {
+                                       e.preventDefault();
+                                       $input.val('').change();
+                                       if (!$input.hasClass("t3js-datetimepicker")) {
+                                               $input.focus();
+                                       }
+                                       $input.trigger('keyup');
 
                                        if ('function' === typeof(settings.onClear)) {
                                                settings.onClear.call($input.get());
                                        }
                                });
 
-                               // Initialize the clearer icon
-                               handler();
+                               $input.trigger('initialize');
                        }
                });
        };
index 81449aa..f4e372b 100644 (file)
@@ -160,7 +160,7 @@ class EditFileController {
                        // Edit textarea:
                        $code .= '
                                <div id="c-edit">
-                                       <textarea rows="30" name="file[editfile][0][data]" wrap="off"' . $this->doc->formWidth(48, TRUE, 'width:98%;height:80%') . ' class="fixed-font enable-tab">' . GeneralUtility::formatForTextarea($fileContent) . '</textarea>
+                                       <textarea rows="30" name="file[editfile][0][data]" wrap="off"' . $this->doc->formWidth(48, TRUE, 'width:98%;height:80%') . ' class="text-monospace enable-tab">' . GeneralUtility::formatForTextarea($fileContent) . '</textarea>
                                        <input type="hidden" name="file[editfile][0][target]" value="' . $this->fileObject->getUid() . '" />
                                        <input type="hidden" name="redirect" value="' . htmlspecialchars($hValue) . '" />
                                        ' . \TYPO3\CMS\Backend\Form\FormEngine::getHiddenTokenField('tceAction') . '
index 4687cfb..1e16993 100644 (file)
@@ -497,26 +497,26 @@ class PageLayoutController {
                                        if (DTM_array[idBase]) {
                                                for(cnt = 0; cnt < DTM_array[idBase].length ; cnt++) {
                                                        if (DTM_array[idBase][cnt] != idBase+"-"+index) {
-                                                               document.getElementById(DTM_array[idBase][cnt]+"-DIV").style.display = "none";
-                                                               document.getElementById(DTM_array[idBase][cnt]+"-MENU").attributes.getNamedItem("class").nodeValue = "tab";
+                                                               document.getElementById(DTM_array[idBase][cnt]+"-DIV").className = "tab-pane";
+                                                               document.getElementById(DTM_array[idBase][cnt]+"-MENU").attributes.getNamedItem("class").value = "tab";
                                                        }
                                                }
                                        }
 
                                                // Showing one:
                                        if (document.getElementById(idBase+"-"+index+"-DIV")) {
-                                               if (doToogle && document.getElementById(idBase+"-"+index+"-DIV").style.display == "block") {
-                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "none";
+                                               if (doToogle && document.getElementById(idBase+"-"+index+"-DIV").className === "tab-pane active") {
+                                                       document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane";
                                                        if(DTM_origClass=="") {
-                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tab";
+                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "tab";
                                                        } else {
                                                                DTM_origClass = "tab";
                                                        }
                                                        top.DTM_currentTabs[idBase] = -1;
                                                } else {
-                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "block";
+                                                       document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane active";
                                                        if(DTM_origClass=="") {
-                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "active";
+                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "active";
                                                        } else {
                                                                DTM_origClass = "active";
                                                        }
@@ -528,17 +528,17 @@ class PageLayoutController {
                                                // Showing one:
                                        if (document.getElementById(idBase+"-"+index+"-DIV")) {
                                                if (document.getElementById(idBase+"-"+index+"-DIV").style.display == "block") {
-                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "none";
+                                                       document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane";
                                                        if(isInit) {
-                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tab";
+                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "tab";
                                                        } else {
                                                                DTM_origClass = "tab";
                                                        }
                                                        top.DTM_currentTabs[idBase+"-"+index] = 0;
                                                } else {
-                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "block";
+                                                       document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane active";
                                                        if(isInit) {
-                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "active";
+                                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "active";
                                                        } else {
                                                                DTM_origClass = "active";
                                                        }
@@ -546,16 +546,6 @@ class PageLayoutController {
                                                }
                                        }
                                }
-
-                               function DTM_mouseOver(obj) {   //
-                                               DTM_origClass = obj.attributes.getNamedItem(\'class\').nodeValue;
-                                               obj.attributes.getNamedItem(\'class\').nodeValue += "_over";
-                               }
-
-                               function DTM_mouseOut(obj) {    //
-                                               obj.attributes.getNamedItem(\'class\').nodeValue = DTM_origClass;
-                                               DTM_origClass = "";
-                               }
                        ');
                        // Setting doc-header
                        $this->doc->form = '<form action="' . htmlspecialchars(
index ca5576b..6acb7b8 100644 (file)
@@ -26,11 +26,6 @@ use TYPO3\CMS\Lang\LanguageService;
 abstract class AbstractFormElement {
 
        /**
-        * @var string A CSS class name prefix for all element types, single elements add their type to this string
-        */
-       protected $cssClassTypeElementPrefix = 't3-formengine-field-';
-
-       /**
         * @var FormEngine
         */
        protected $formEngine;
index 63449eb..94f9ff2 100644 (file)
@@ -159,7 +159,6 @@ class CheckboxElement extends AbstractFormElement {
                                <label>
                                        <input type="checkbox"
                                                value="1"
-                                               class="' . $this->cssClassTypeElementPrefix . 'check"
                                                name="' . $checkboxName . '"
                                                ' . $checkboxParameters . '
                                                ' . $additionalInformation['onFocus'] . '
index 8892019..d8f44fb 100644 (file)
@@ -175,8 +175,7 @@ class FlexElement extends AbstractFormElement {
                                                        $this->formEngine->pushToDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1));
                                                }
                                                // Render flexform:
-                                               $tRows = $this->getSingleField_typeFlex_draw($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $table, $field, $row, $additionalInformation, '[data][' . $sheet . '][' . $lang . ']');
-                                               $sheetContent = '<div class="typo3-TCEforms-flexForm t3-form-flexform">' . $tRows . '</div>';
+                                               $sheetContent = $this->getSingleField_typeFlex_draw($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $table, $field, $row, $additionalInformation, '[data][' . $sheet . '][' . $lang . ']');
                                                // Pop the sheet level tab from DynNestedStack
                                                if (is_array($dataStructArray['sheets'])) {
                                                        $this->formEngine->popFromDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1));
@@ -534,12 +533,20 @@ class FlexElement extends AbstractFormElement {
                                                                // possible linebreaks in the label through xml: \n => <br/>, usage of nl2br()
                                                                // not possible, so it's done through str_replace
                                                                $processedTitle = str_replace('\\n', '<br />', $theTitle);
-                                                               $tRows[] = '<div class="t3-form-field-container t3-form-field-container-flex">'
-                                                                       . '<div class="t3-form-field-label t3-form-field-label-flex">' . $languageIcon
-                                                                       . BackendUtility::wrapInHelp($PA['_cshKey'], $key, $processedTitle) . '</div>
-                                                                       <div class="t3-form-field t3-form-field-flex">' . $theFormEl . $defInfo
-                                                                       . $this->renderVDEFDiff($editData[$key], $vDEFkey) . '</div>
-                                                               </div>';
+                                                               $tRows[] = '
+                                                                       <div class="form-section">
+                                                                               <div class="form-group t3js-formengine-palette-field">
+                                                                                       <label class="t3js-formengine-label">
+                                                                                               ' . $languageIcon . '
+                                                                                               ' . BackendUtility::wrapInHelp($PA['_cshKey'], $key, $processedTitle) . '
+                                                                                       </label>
+                                                                                       <div class="t3js-formengine-field-item">
+                                                                                               ' . $theFormEl . '
+                                                                                               ' . $defInfo . '
+                                                                                               ' . $this->renderVDEFDiff($editData[$key], $vDEFkey) . '
+                                                                                       </div>
+                                                                               </div>
+                                                                       </div>';
                                                        }
                                                }
                                                if (count($tRows)) {
index 1b71abf..2fac409 100644 (file)
@@ -38,30 +38,40 @@ class GroupElement extends AbstractFormElement {
         * @return string The HTML code for the TCEform field
         */
        public function render($table, $field, $row, &$additionalInformation) {
+
                $config = $additionalInformation['fieldConf']['config'];
                $show_thumbs = $config['show_thumbs'];
-               $size = isset($config['size']) ? (int)$config['size'] : 5;
+               $size = isset($config['size']) ? (int)$config['size'] : $this->formEngine->minimumInputWidth;
                $maxitems = MathUtility::forceIntegerInRange($config['maxitems'], 0);
                if (!$maxitems) {
                        $maxitems = 100000;
                }
                $minitems = MathUtility::forceIntegerInRange($config['minitems'], 0);
-               $allowed = trim($config['allowed']);
-               $disallowed = trim($config['disallowed']);
-               $item = '';
-               $disabled = '';
-               if ($this->isRenderReadonly() || $config['readOnly']) {
-                       $disabled = ' disabled="disabled"';
-               }
-               $item .= '<input type="hidden" name="' . $additionalInformation['itemFormElName'] . '_mul" value="' . ($config['multiple'] ? 1 : 0) . '"' . $disabled . ' />';
-               $this->formEngine->registerRequiredProperty('range', $additionalInformation['itemFormElName'], array($minitems, $maxitems, 'imgName' => $table . '_' . $row['uid'] . '_' . $field));
-               $info = '';
-               // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist.
-               $specConf = BackendUtility::getSpecConfParts($additionalInformation['extra'], $additionalInformation['fieldConf']['defaultExtras']);
+               $thumbnails = array();
+               $allowed = GeneralUtility::trimExplode(',', $config['allowed'], TRUE);
+               $disallowed = GeneralUtility::trimExplode(',', $config['disallowed'], TRUE);
+               $disabled = ($this->isRenderReadonly() || $config['readOnly']);
+               $info = array();
                $additionalInformation['itemFormElID_file'] = $additionalInformation['itemFormElID'] . '_files';
+
                // whether the list and delete controls should be disabled
                $noList = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'list');
                $noDelete = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'delete');
+
+               // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist.
+               $specConf = BackendUtility::getSpecConfParts($additionalInformation['extra'], $additionalInformation['fieldConf']['defaultExtras']);
+
+               // Register properties in requiredFields and requiredElements
+               $this->formEngine->registerRequiredProperty(
+                       'range',
+                       $additionalInformation['itemFormElName'],
+                       array(
+                               $minitems,
+                               $maxitems,
+                               'imgName' => $table . '_' . $row['uid'] . '_' . $field
+                       )
+               );
+
                // if maxitems==1 then automatically replace the current item (in list and file selector)
                if ($maxitems === 1) {
                        $this->formEngine->additionalJS_post[] = 'TBE_EDITOR.clearBeforeSettingFormValueFromBrowseWin[\'' . $additionalInformation['itemFormElName'] . '\'] = {
@@ -74,6 +84,9 @@ class GroupElement extends AbstractFormElement {
                        $additionalInformation['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = 'setFormValueManipulate(\'' . $additionalInformation['itemFormElName']
                                . '\', \'RemoveFirstIfFull\', \'' . $maxitems . '\'); ' . $additionalInformation['fieldChangeFunc']['TBE_EDITOR_fieldChanged'];
                }
+
+               $item = '<input type="hidden" name="' . $additionalInformation['itemFormElName'] . '_mul" value="' . ($config['multiple'] ? 1 : 0) . '"' . $disabled . ' />';
+
                // Acting according to either "file" or "db" type:
                switch ((string)$config['internal_type']) {
                        case 'file_reference':
@@ -81,24 +94,8 @@ class GroupElement extends AbstractFormElement {
                                // Fall through
                        case 'file':
                                // Creating string showing allowed types:
-                               $tempFT = GeneralUtility::trimExplode(',', $allowed, TRUE);
-                               if (!count($tempFT)) {
-                                       $info .= '*';
-                               }
-                               foreach ($tempFT as $ext) {
-                                       if ($ext) {
-                                               $info .= strtoupper($ext) . ' ';
-                                       }
-                               }
-                               // Creating string, showing disallowed types:
-                               $tempFT_dis = GeneralUtility::trimExplode(',', $disallowed, TRUE);
-                               if (count($tempFT_dis)) {
-                                       $info .= '<br />';
-                               }
-                               foreach ($tempFT_dis as $ext) {
-                                       if ($ext) {
-                                               $info .= '-' . strtoupper($ext) . ' ';
-                                       }
+                               if (!count($allowed)) {
+                                       $allowed = array('*');
                                }
                                // Making the array of file items:
                                $itemArray = GeneralUtility::trimExplode(',', $additionalInformation['itemFormElValue'], TRUE);
@@ -113,7 +110,6 @@ class GroupElement extends AbstractFormElement {
                                        $fileItem = $fileUid . '|' . $fileLabel;
                                }
                                // Showing thumbnails:
-                               $thumbsnail = '';
                                if ($show_thumbs) {
                                        $imgs = array();
                                        foreach ($itemArray as $imgRead) {
@@ -122,30 +118,39 @@ class GroupElement extends AbstractFormElement {
                                                // FAL icon production
                                                if (MathUtility::canBeInterpretedAsInteger($imgP[0])) {
                                                        $fileObject = $fileFactory->getFileObject($imgP[0]);
-
                                                        if ($fileObject->isMissing()) {
-                                                               $flashMessage = \TYPO3\CMS\Core\Resource\Utility\BackendUtility::getFlashMessageForMissingFile($fileObject);
-                                                               $imgs[] = $flashMessage->render();
+                                                               $thumbnails[] = array(
+                                                                       'message' => \TYPO3\CMS\Core\Resource\Utility\BackendUtility::getFlashMessageForMissingFile($fileObject)->render()
+                                                               );
                                                        } elseif (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileObject->getExtension())) {
-                                                               $imageUrl = $fileObject->process(ProcessedFile::CONTEXT_IMAGEPREVIEW, array())->getPublicUrl(TRUE);
-                                                               $imgTag = '<img src="' . $imageUrl . '" alt="' . htmlspecialchars($fileObject->getName()) . '" />';
-                                                               $imgs[] = '<span class="nobr">' . $imgTag . htmlspecialchars($fileObject->getName()) . '</span>';
+                                                               $thumbnails[] = array(
+                                                                       'name' => htmlspecialchars($fileObject->getName()),
+                                                                       'image' => $fileObject->process(ProcessedFile::CONTEXT_IMAGEPREVIEW, array())->getPublicUrl(TRUE)
+                                                               );
                                                        } else {
                                                                // Icon
-                                                               $imgTag = IconUtility::getSpriteIconForResource($fileObject, array('title' => $fileObject->getName()));
-                                                               $imgs[] = '<span class="nobr">' . $imgTag . htmlspecialchars($fileObject->getName()) . '</span>';
+                                                               $thumbnails[] = array(
+                                                                       'name' => htmlspecialchars($fileObject->getName()),
+                                                                       'image' => IconUtility::getSpriteIconForResource($fileObject, array('title' => $fileObject->getName()))
+                                                               );
                                                        }
                                                } else {
                                                        $rowCopy = array();
                                                        $rowCopy[$field] = $imgPath;
-                                                       $thumbnailCode = '';
                                                        try {
-                                                               $thumbnailCode = BackendUtility::thumbCode(
-                                                                       $rowCopy, $table, $field, $this->formEngine->backPath, 'thumbs.php',
-                                                                       $config['uploadfolder'], 0, ' align="middle"'
+                                                               $thumbnails[] = array(
+                                                                       'name' => $imgPath,
+                                                                       'image' => BackendUtility::thumbCode(
+                                                                               $rowCopy,
+                                                                               $table,
+                                                                               $field,
+                                                                               $this->formEngine->backPath,
+                                                                               'thumbs.php',
+                                                                               $config['uploadfolder'],
+                                                                               0,
+                                                                               ' align="middle"'
+                                                                       )
                                                                );
-                                                               $thumbnailCode = '<span class="nobr">' . $thumbnailCode . $imgPath . '</span>';
-
                                                        } catch (\Exception $exception) {
                                                                /** @var $flashMessage FlashMessage */
                                                                $message = $exception->getMessage();
@@ -157,33 +162,41 @@ class GroupElement extends AbstractFormElement {
                                                                $flashMessageService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class);
                                                                $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
                                                                $defaultFlashMessageQueue->enqueue($flashMessage);
-
                                                                $logMessage = $message . ' (' . $table . ':' . $row['uid'] . ')';
                                                                GeneralUtility::sysLog($logMessage, 'core', GeneralUtility::SYSLOG_SEVERITY_WARNING);
                                                        }
-
-                                                       $imgs[] = $thumbnailCode;
                                                }
                                        }
-                                       $thumbsnail = implode('<br />', $imgs);
                                }
                                // Creating the element:
                                $params = array(
                                        'size' => $size,
+                                       'allowed' => $allowed,
+                                       'disallowed' => $disallowed,
                                        'dontShowMoveIcons' => $maxitems <= 1,
                                        'autoSizeMax' => MathUtility::forceIntegerInRange($config['autoSizeMax'], 0),
                                        'maxitems' => $maxitems,
                                        'style' => isset($config['selectedListStyle'])
                                                ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"'
                                                : ' style="' . $this->formEngine->defaultMultipleSelectorStyle . '"',
-                                       'info' => $info,
-                                       'thumbnails' => $thumbsnail,
+                                       'thumbnails' => $thumbnails,
                                        'readOnly' => $disabled,
                                        'noBrowser' => $noList || isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'browser'),
                                        'noList' => $noList,
                                        'noDelete' => $noDelete
                                );
-                               $item .= $this->formEngine->dbFileIcons($additionalInformation['itemFormElName'], 'file', implode(',', $tempFT), $itemArray, '', $params, $additionalInformation['onFocus'], '', '', '', $config);
+                               $item .= $this->formEngine->dbFileIcons(
+                                       $additionalInformation['itemFormElName'],
+                                       'file',
+                                       implode(',', $allowed),
+                                       $itemArray,
+                                       '',
+                                       $params,
+                                       $additionalInformation['onFocus'],
+                                       '',
+                                       '',
+                                       '',
+                                       $config);
                                if (!$disabled && !(isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'upload'))) {
                                        // Adding the upload field:
                                        if ($this->formEngine->edit_docModuleUpload && $config['uploadfolder']) {
@@ -194,9 +207,13 @@ class GroupElement extends AbstractFormElement {
                                                        $multipleAttribute = ' multiple="multiple"';
                                                        $multipleFilenameSuffix = '[]';
                                                }
-                                               $item .= '<div id="' . $additionalInformation['itemFormElID_file'] . '"><input type="file"' . $multipleAttribute
-                                                       . ' name="' . $additionalInformation['itemFormElName_file'] . $multipleFilenameSuffix . '" size="35" onchange="'
-                                                       . implode('', $additionalInformation['fieldChangeFunc']) . '" /></div>';
+                                               $item .= '
+                                                       <div id="' . $additionalInformation['itemFormElID_file'] . '">
+                                                               <input type="file"' . $multipleAttribute . '
+                                                                       name="' . $additionalInformation['itemFormElName_file'] . $multipleFilenameSuffix . '"
+                                                                       size="35" onchange="' . implode('', $additionalInformation['fieldChangeFunc']) . '"
+                                                               />
+                                                       </div>';
                                        }
                                }
                                break;
@@ -213,34 +230,45 @@ class GroupElement extends AbstractFormElement {
                                        'style' => isset($config['selectedListStyle'])
                                                ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"'
                                                : ' style="' . $this->formEngine->defaultMultipleSelectorStyle . '"',
-                                       'info' => $info,
                                        'readOnly' => $disabled,
                                        'noBrowser' => $noList || isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'browser'),
                                        'noList' => $noList
                                );
-                               $item .= $this->formEngine->dbFileIcons($additionalInformation['itemFormElName'], 'folder', '', $itemArray, '', $params, $additionalInformation['onFocus']);
+                               $item .= $this->formEngine->dbFileIcons(
+                                       $additionalInformation['itemFormElName'],
+                                       'folder',
+                                       '',
+                                       $itemArray,
+                                       '',
+                                       $params,
+                                       $additionalInformation['onFocus']
+                               );
                                break;
                        case 'db':
                                // If the element is of the internal type "db":
                                // Creating string showing allowed types:
-                               $tempFT = GeneralUtility::trimExplode(',', $allowed, TRUE);
                                $onlySingleTableAllowed = FALSE;
                                $languageService = $this->getLanguageService();
-                               if (trim($tempFT[0]) === '*') {
-                                       $info .= '<span class="nobr">' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.allTables')) . '</span><br />';
-                               } elseif ($tempFT) {
-                                       $onlySingleTableAllowed = count($tempFT) == 1;
-                                       foreach ($tempFT as $theT) {
-                                               $aOnClick = 'setFormValueOpenBrowser(\'db\', \'' . ($additionalInformation['itemFormElName'] . '|||' . $theT) . '\'); return false;';
-                                               $info .= '<span class="nobr">
-                                                                       <a href="#" onclick="' . htmlspecialchars($aOnClick) . '">'
-                                                       . IconUtility::getSpriteIconForRecord($theT, array())
-                                                       . htmlspecialchars($languageService->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])) . '</a></span><br />';
+
+                               if ($allowed[0] === '*') {
+                                       $allowedTables = array(
+                                               'name' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.allTables'))
+                                       );
+                               } elseif ($allowed) {
+                                       $onlySingleTableAllowed = count($allowed) == 1;
+                                       $allowedTables = array();
+                                       foreach ($allowed as $allowedTable) {
+                                               $allowedTables[] = array(
+                                                       'name' => htmlspecialchars($languageService->sL($GLOBALS['TCA'][$allowedTable]['ctrl']['title'])),
+                                                       'icon' => IconUtility::getSpriteIconForRecord($allowedTable, array()),
+                                                       'onClick' => 'setFormValueOpenBrowser(\'db\', \'' . ($additionalInformation['itemFormElName'] . '|||' . $allowedTable) . '\'); return false;'
+                                               );
                                        }
                                }
                                $perms_clause = $this->getBackendUserAuthentication()->getPagePermsClause(1);
                                $itemArray = array();
                                $imgs = array();
+
                                // Thumbnails:
                                $temp_itemArray = GeneralUtility::trimExplode(',', $additionalInformation['itemFormElValue'], TRUE);
                                foreach ($temp_itemArray as $dbRead) {
@@ -253,17 +281,15 @@ class GroupElement extends AbstractFormElement {
                                        $itemArray[] = array('table' => $this_table, 'id' => $this_uid);
                                        if (!$disabled && $show_thumbs) {
                                                $rr = BackendUtility::getRecordWSOL($this_table, $this_uid);
-                                               $imgs[] = '<span class="nobr">' . $this->formEngine->getClickMenu(IconUtility::getSpriteIconForRecord($this_table, $rr, array(
-                                                               'style' => 'vertical-align:top',
-                                                               'title' => htmlspecialchars((BackendUtility::getRecordPath($rr['pid'], $perms_clause, 15) . ' [UID: ' . $rr['uid'] . ']'))
-                                                       )), $this_table, $this_uid) . '&nbsp;' . BackendUtility::getRecordTitle($this_table, $rr, TRUE)
-                                                       . ' <span class="typo3-dimmed"><em>[' . $rr['uid'] . ']</em></span>' . '</span>';
+                                               $thumbnails[] = array(
+                                                       'name' => BackendUtility::getRecordTitle($this_table, $rr, TRUE),
+                                                       'image' => IconUtility::getSpriteIconForRecord($this_table, $rr),
+                                                       'path' => BackendUtility::getRecordPath($rr['pid'], $perms_clause, 15),
+                                                       'uid' => $rr['uid'],
+                                                       'table' => $this_table
+                                               );
                                        }
                                }
-                               $thumbsnail = '';
-                               if (!$disabled && $show_thumbs) {
-                                       $thumbsnail = implode('<br />', $imgs);
-                               }
                                // Creating the element:
                                $params = array(
                                        'size' => $size,
@@ -274,18 +300,43 @@ class GroupElement extends AbstractFormElement {
                                                ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"'
                                                : ' style="' . $this->formEngine->defaultMultipleSelectorStyle . '"',
                                        'info' => $info,
-                                       'thumbnails' => $thumbsnail,
+                                       'allowedTables' => $allowedTables,
+                                       'thumbnails' => $thumbnails,
                                        'readOnly' => $disabled,
                                        'noBrowser' => $noList || isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'browser'),
                                        'noList' => $noList
                                );
-                               $item .= $this->formEngine->dbFileIcons($additionalInformation['itemFormElName'], 'db', implode(',', $tempFT), $itemArray, '', $params, $additionalInformation['onFocus'], $table, $field, $row['uid'], $config);
+                               $item .= $this->formEngine->dbFileIcons(
+                                       $additionalInformation['itemFormElName'],
+                                       'db',
+                                       implode(',', $allowed),
+                                       $itemArray,
+                                       '',
+                                       $params,
+                                       $additionalInformation['onFocus'],
+                                       $table,
+                                       $field,
+                                       $row['uid'],
+                                       $config
+                               );
                                break;
                }
                // Wizards:
                $altItem = '<input type="hidden" name="' . $additionalInformation['itemFormElName'] . '" value="' . htmlspecialchars($additionalInformation['itemFormElValue']) . '" />';
                if (!$disabled) {
-                       $item = $this->formEngine->renderWizards(array($item, $altItem), $config['wizards'], $table, $row, $field, $additionalInformation, $additionalInformation['itemFormElName'], $specConf);
+                       $item = $this->formEngine->renderWizards(
+                               array(
+                                       $item,
+                                       $altItem
+                               ),
+                               $config['wizards'],
+                               $table,
+                               $row,
+                               $field,
+                               $additionalInformation,
+                               $additionalInformation['itemFormElName'],
+                               $specConf
+                       );
                }
                return $item;
        }
index 4de48fe..2b6f01b 100644 (file)
@@ -308,17 +308,17 @@ class InlineElement {
                $levelLinks = $this->getLevelInteractionLink('newRecord', $nameObject . self::Structure_Separator . $foreign_table, $config);
 
                // Wrap all inline fields of a record with a <div> (like a container)
-               $item .= '<div id="' . $nameObject . '">';
+               $item .= '<div class="form-group" id="' . $nameObject . '">';
                // Define how to show the "Create new record" link - if there are more than maxitems, hide it
                if ($relatedRecords['count'] >= $maxitems || $uniqueMax > 0 && $relatedRecords['count'] >= $uniqueMax) {
                        $config['inline']['inlineNewButtonStyle'] = 'display: none;';
                }
                // Add the level links before all child records:
                if (in_array($config['appearance']['levelLinksPosition'], array('both', 'top'))) {
-                       $item .= $levelLinks . $localizationLinks;
+                       $item .= '<div class="form-group">' . $levelLinks . $localizationLinks . '</div>';
                }
                $title = $this->getLanguageService()->sL($PA['fieldConf']['label']);
-               $item .= '<div id="' . $nameObject . '_records" data-title="' . htmlspecialchars($title) . '">';
+               $item .= '<div class="panel-group panel-hover" data-title="' . htmlspecialchars($title) . '" id="' . $nameObject . '_records">';
                $relationList = array();
                if (count($relatedRecords['records'])) {
                        foreach ($relatedRecords['records'] as $rec) {
@@ -424,7 +424,6 @@ class InlineElement {
                                $combination = $this->renderCombinationTable($rec, $appendFormFieldNames, $config);
                                $overruleTypesArray = isset($config['foreign_types']) ? $config['foreign_types'] : array();
                                $fields = $this->renderMainFields($foreign_table, $rec, $overruleTypesArray);
-                               $fields = $this->wrapFormsSection($fields);
                                // Replace returnUrl in Wizard-Code, if this is an AJAX call
                                $ajaxArguments = GeneralUtility::_GP('ajax');
                                if (isset($ajaxArguments[2]) && trim($ajaxArguments[2]) != '') {
@@ -456,7 +455,7 @@ class InlineElement {
                        }
                        // If this record should be shown collapsed
                        if (!$isExpanded) {
-                               $class = 't3-form-field-container-inline-collapsed';
+                               $class = 'panel-collapsed';
                        }
                }
                if ($config['renderFieldsOnly']) {
@@ -469,13 +468,19 @@ class InlineElement {
                        if (isset($rec['hidden']) && (int)$rec['hidden']) {
                                $class .= ' t3-form-field-container-inline-hidden';
                        }
-                       $out = '<div class="t3-form-field-record-inline" id="' . $objectId . '_fields" data-expandSingle="' . ($config['appearance']['expandSingle'] ? 1 : 0) . '" data-returnURL="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '">' . $fields . $combination . '</div>';
-                       $header = IconUtility::getSpriteIcon('apps-irre-' . ($class != '' ? 'collapsed' : 'expanded'));
-                       $header .= $this->renderForeignRecordHeader($parentUid, $foreign_table, $rec, $config, $isVirtualRecord);
-                       $out = '<div class="t3-form-field-header-inline" id="' . $objectId . '_header">' . $header . '</div>' . $out;
-                       // Wrap the header, fields and combination part of a child record with a div container
-                       $class .= ' inlineDiv' . ($isNewRecord ? ' inlineIsNewRecord' : '');
-                       $out = '<div id="' . $objectId . '_div" class="t3-form-field-container-inline ' . trim($class) . '">' . $out . '</div>';
+                       $class .= ($isNewRecord ? ' inlineIsNewRecord' : '');
+                       $out = '
+                               <div class="panel panel-default panel-condensed ' . trim($class) . '" id="' . $objectId . '_div">
+                                       <div class="panel-heading" data-toggle="formengine-inline" id="' . $objectId . '_header">
+                                               <div class="form-irre-header">
+                                                       <div class="form-irre-header-cell form-irre-header-icon">
+                                                               <span class="caret"></span>
+                                                       </div>
+                                                       ' . $this->renderForeignRecordHeader($parentUid, $foreign_table, $rec, $config, $isVirtualRecord) . '
+                                               </div>
+                                       </div>
+                                       <div class="panel-collapse" id="' . $objectId . '_fields" data-expandSingle="' . ($config['appearance']['expandSingle'] ? 1 : 0) . '" data-returnURL="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '">' . $fields . $combination . '</div>
+                               </div>';
                }
                // Remove the current level also from the dynNestedStack of FormEngine:
                $this->fObj->popFromDynNestedStack();
@@ -609,27 +614,20 @@ class InlineElement {
                                        // Only use a thumbnail if the processing was successful.
                                        if (!$processedImage->usesOriginalFile()) {
                                                $imageUrl = $processedImage->getPublicUrl(TRUE);
-                                               $thumbnail = '<img class="t3-form-field-header-inline-thumbnail-image" src="' . $imageUrl . '" alt="' . htmlspecialchars($altText) . '" title="' . htmlspecialchars($altText) . '">';
+                                               $thumbnail = '<img src="' . $imageUrl . '" alt="' . htmlspecialchars($altText) . '" title="' . htmlspecialchars($altText) . '">';
                                        }
                                }
                        }
                }
 
                if (!empty($config['appearance']['headerThumbnail']['field']) && $thumbnail) {
-                       $headerClasses = ' t3-form-field-header-inline-has-thumbnail';
-                       $mediaContainer = '<div class="t3-form-field-header-inline-thumbnail" id="' . $objectId . '_thumbnailcontainer">' . $thumbnail . '</div>';
+                       $mediaContainer = '<div class="form-irre-header-cell form-irre-header-thumbnail" id="' . $objectId . '_thumbnailcontainer">' . $thumbnail . '</div>';
                } else {
-                       $headerClasses = ' t3-form-field-header-inline-has-icon';
-                       $mediaContainer = '<div class="t3-form-field-header-inline-icon" id="' . $objectId . '_iconcontainer">' . $iconImg . '</div>';
+                       $mediaContainer = '<div class="form-irre-header-cell form-irre-header-icon" id="' . $objectId . '_iconcontainer">' . $iconImg . '</div>';
                }
-
-               $header = '<div class="t3-form-field-header-inline-wrap' . $headerClasses . '">'
-                               . '<div class="t3-form-field-header-inline-ctrl">' . $ctrl . '</div>'
-                               . '<div class="t3-form-field-header-inline-body">'
-                               . $mediaContainer
-                               . '<div class="t3-form-field-header-inline-summary">' . $label . '</div>'
-                               . '</div>'
-                               . '</div>';
+               $header = $mediaContainer . '
+                               <div class="form-irre-header-cell form-irre-header-body">' . $label . '</div>
+                               <div class="form-irre-header-cell form-irre-header-control t3js-formengine-irre-control">' . $ctrl . '</div>';
 
                return $header;
        }
@@ -650,6 +648,7 @@ class InlineElement {
                $languageService = $this->getLanguageService();
                // Initialize:
                $cells = array();
+               $additionalCells = array();
                $isNewItem = substr($rec['uid'], 0, 3) == 'NEW';
                $isParentExisting = MathUtility::canBeInterpretedAsInteger($parentUid);
                $tcaTableCtrl = &$GLOBALS['TCA'][$foreign_table]['ctrl'];
@@ -673,8 +672,6 @@ class InlineElement {
                foreach ($this->hookObjects as $hookObj) {
                        $hookObj->renderForeignRecordHeaderControl_preProcess($parentUid, $foreign_table, $rec, $config, $isVirtualRecord, $enabledControls);
                }
-               // Icon to visualize that a required field is nested in this inline level:
-               $cells['required'] = '<img name="' . $nameObjectFtId . '_req" src="clear.gif" width="10" height="10" hspace="4" vspace="3" alt="" />';
                if (isset($rec['__create'])) {
                        $cells['localize.isLocalizable'] = IconUtility::getSpriteIcon('actions-edit-localize-status-low', array('title' => $languageService->sL('LLL:EXT:lang/locallang_misc.xlf:localize.isLocalizable', TRUE)));
                } elseif (isset($rec['__remove'])) {
@@ -689,7 +686,10 @@ class InlineElement {
                                $uid = $rec['uid'];
                                $table = $foreign_table;
                        }
-                       $cells['info'] = '<a href="#" onclick="' . htmlspecialchars(('top.launchView(\'' . $table . '\', \'' . $uid . '\'); return false;')) . '">' . IconUtility::getSpriteIcon('status-dialog-information', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:showInfo', TRUE))) . '</a>';
+                       $cells['info'] = '
+                               <a class="btn btn-default" href="#" onclick="' . htmlspecialchars(('top.launchView(\'' . $table . '\', \'' . $uid . '\'); return false;')) . '">
+                                       ' . IconUtility::getSpriteIcon('status-dialog-information', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:showInfo', TRUE))) . '
+                               </a>';
                }
                // If the table is NOT a read-only table, then show these links:
                if (!$tcaTableCtrl['readOnly'] && !$isVirtualRecord) {
@@ -697,25 +697,31 @@ class InlineElement {
                        if ($enabledControls['new'] && ($enableManualSorting || $tcaTableCtrl['useColumnsForDefaultValues'])) {
                                if (!$isPagesTable && $calcPerms & 16 || $isPagesTable && $calcPerms & 8) {
                                        $onClick = 'return inline.createNewRecord(\'' . $nameObjectFt . '\',\'' . $rec['uid'] . '\')';
-                                       $class = ' class="inlineNewButton ' . $this->inlineData['config'][$nameObject]['md5'] . '"';
                                        if ($config['inline']['inlineNewButtonStyle']) {
                                                $style = ' style="' . $config['inline']['inlineNewButtonStyle'] . '"';
                                        }
-                                       $cells['new'] = '<a href="#" onclick="' . htmlspecialchars($onClick) . '"' . $class . $style . '>' . IconUtility::getSpriteIcon(('actions-' . ($isPagesTable ? 'page' : 'document') . '-new'), array(
-                                               'title' => $languageService->sL(('LLL:EXT:lang/locallang_mod_web_list.xlf:new' . ($isPagesTable ? 'Page' : 'Record')), TRUE)
-                                       )) . '</a>';
+                                       $cells['new'] = '
+                                               <a class="btn btn-default inlineNewButton ' . $this->inlineData['config'][$nameObject]['md5'] . '" href="#" onclick="' . htmlspecialchars($onClick) . '"' . $class . $style . '>
+                                                       ' . IconUtility::getSpriteIcon(('actions-' . ($isPagesTable ? 'page' : 'document') . '-new'), array('title' => $languageService->sL(('LLL:EXT:lang/locallang_mod_web_list.xlf:new' . ($isPagesTable ? 'Page' : 'Record')), TRUE))) . '
+                                               </a>';
                                }
                        }
                        // "Up/Down" links
                        if ($enabledControls['sort'] && $permsEdit && $enableManualSorting) {
-                               $onClick = 'return inline.changeSorting(\'' . $nameObjectFtId . '\', \'1\')';
                                // Up
+                               $onClick = 'return inline.changeSorting(\'' . $nameObjectFtId . '\', \'1\')';
                                $style = $config['inline']['first'] == $rec['uid'] ? 'style="visibility: hidden;"' : '';
-                               $cells['sort.up'] = '<a href="#" onclick="' . htmlspecialchars($onClick) . '" class="sortingUp" ' . $style . '>' . IconUtility::getSpriteIcon('actions-move-up', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:moveUp', TRUE))) . '</a>';
-                               $onClick = 'return inline.changeSorting(\'' . $nameObjectFtId . '\', \'-1\')';
+                               $cells['sort.up'] = '
+                                       <a class="btn btn-default sortingUp" href="#" onclick="' . htmlspecialchars($onClick) . '" ' . $style . '>
+                                               ' . IconUtility::getSpriteIcon('actions-move-up', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:moveUp', TRUE))) . '
+                                       </a>';
                                // Down
+                               $onClick = 'return inline.changeSorting(\'' . $nameObjectFtId . '\', \'-1\')';
                                $style = $config['inline']['last'] == $rec['uid'] ? 'style="visibility: hidden;"' : '';
-                               $cells['sort.down'] = '<a href="#" onclick="' . htmlspecialchars($onClick) . '" class="sortingDown" ' . $style . '>' . IconUtility::getSpriteIcon('actions-move-down', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:moveDown', TRUE))) . '</a>';
+                               $cells['sort.down'] = '
+                                       <a class="btn btn-default sortingDown" href="#" onclick="' . htmlspecialchars($onClick) . '" ' . $style . '>
+                                               ' . IconUtility::getSpriteIcon('actions-move-down', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:moveDown', TRUE))) . '
+                                       </a>';
                        }
                        // "Edit" link:
                        if (($rec['table_local'] === 'sys_file') && !$isNewItem) {
@@ -730,15 +736,19 @@ class InlineElement {
                                                . 'top.content.list_frame.document.location' . '.pathname+top.content.list_frame.document.location' . '.search)+'
                                                . '\'&edit[sys_file_metadata][' . (int)$editUid . ']=edit\';}';
                                        $title = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:cm.editMetadata');
-                                       $cells['editmetadata'] = '<a href="#" class="btn" onclick="'
-                                               . htmlspecialchars($editOnClick) . '" title="' . htmlspecialchars($title) . '">'
-                                               . IconUtility::getSpriteIcon('actions-document-open') . '</a>';
+                                       $cells['editmetadata'] = '
+                                               <a class="btn btn-default" href="#" class="btn" onclick="' . htmlspecialchars($editOnClick) . '" title="' . htmlspecialchars($title) . '">
+                                                       ' . IconUtility::getSpriteIcon('actions-document-open') . '
+                                               </a>';
                                }
                        }
                        // "Delete" link:
                        if ($enabledControls['delete'] && ($isPagesTable && $localCalcPerms & 4 || !$isPagesTable && $calcPerms & 16)) {
                                $onClick = 'inline.deleteRecord(' . GeneralUtility::quoteJSvalue($nameObjectFtId) . ');';
-                               $cells['delete'] = '<a href="#" onclick="' . htmlspecialchars(('if (confirm(' . GeneralUtility::quoteJSvalue($languageService->getLL('deleteWarning')) . ')) {  ' . $onClick . ' } return false;')) . '">' . IconUtility::getSpriteIcon('actions-edit-delete', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:delete', TRUE))) . '</a>';
+                               $cells['delete'] = '
+                                       <a class="btn btn-default" href="#" onclick="' . htmlspecialchars(('if (confirm(' . GeneralUtility::quoteJSvalue($languageService->getLL('deleteWarning')) . ')) {      ' . $onClick . ' } return false;')) . '">
+                                               ' . IconUtility::getSpriteIcon('actions-edit-delete', array('title' => $languageService->sL('LLL:EXT:lang/locallang_mod_web_list.xlf:delete', TRUE))) . '
+                                       </a>';
                        }
 
                        // "Hide/Unhide" links:
@@ -746,36 +756,57 @@ class InlineElement {
                        if ($enabledControls['hide'] && $permsEdit && $hiddenField && $tcaTableCols[$hiddenField] && (!$tcaTableCols[$hiddenField]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $foreign_table . ':' . $hiddenField))) {
                                $onClick = 'return inline.enableDisableRecord(\'' . $nameObjectFtId . '\')';
                                if ($rec[$hiddenField]) {
-                                       $cells['hide.unhide'] = '<a href="#" class="hiddenHandle" onclick="' . htmlspecialchars($onClick) . '">' . IconUtility::getSpriteIcon('actions-edit-unhide', array(
-                                               'title' => $languageService->sL(('LLL:EXT:lang/locallang_mod_web_list.xlf:unHide' . ($isPagesTable ? 'Page' : '')), TRUE),
-                                               'id' => ($nameObjectFtId . '_disabled')
-                                       )) . '</a>';
+                                       $cells['hide.unhide'] = '
+                                               <a class="btn btn-default hiddenHandle" href="#" onclick="' . htmlspecialchars($onClick) . '">
+                                                       ' . IconUtility::getSpriteIcon('actions-edit-unhide', array('title' => $languageService->sL(('LLL:EXT:lang/locallang_mod_web_list.xlf:unHide' . ($isPagesTable ? 'Page' : '')), TRUE), 'id' => ($nameObjectFtId . '_disabled'))) . '
+                                               </a>';
                                } else {
-                                       $cells['hide.hide'] = '<a href="#" class="hiddenHandle" onclick="' . htmlspecialchars($onClick) . '">' . IconUtility::getSpriteIcon('actions-edit-hide', array(
-                                               'title' => $languageService->sL(('LLL:EXT:lang/locallang_mod_web_list.xlf:hide' . ($isPagesTable ? 'Page' : '')), TRUE),
-                                               'id' => ($nameObjectFtId . '_disabled')
-                                       )) . '</a>';
+                                       $cells['hide.hide'] = '
+                                               <a class="btn btn-default hiddenHandle" href="#" onclick="' . htmlspecialchars($onClick) . '">
+                                                       ' . IconUtility::getSpriteIcon('actions-edit-hide', array('title' => $languageService->sL(('LLL:EXT:lang/locallang_mod_web_list.xlf:hide' . ($isPagesTable ? 'Page' : '')), TRUE), 'id' => ($nameObjectFtId . '_disabled'))) . '
+                                               </a>';
                                }
                        }
                        // Drag&Drop Sorting: Sortable handler for script.aculo.us
                        if ($enabledControls['dragdrop'] && $permsEdit && $enableManualSorting && $config['appearance']['useSortable']) {
-                               $cells['dragdrop'] = IconUtility::getSpriteIcon('actions-move-move', array('data-id' => $rec['uid'], 'class' => 'sortableHandle', 'title' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move', TRUE)));
+                               $additionalCells['dragdrop'] = '
+                                       <span class="btn btn-default">
+                                               ' . IconUtility::getSpriteIcon('actions-move-move', array('data-id' => $rec['uid'], 'class' => 'sortableHandle', 'title' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move', TRUE))) . '
+                                       </span>';
                        }
                } elseif ($isVirtualRecord && $isParentExisting) {
                        if ($enabledControls['localize'] && isset($rec['__create'])) {
                                $onClick = 'inline.synchronizeLocalizeRecords(\'' . $nameObjectFt . '\', ' . $rec['uid'] . ');';
-                               $cells['localize'] = '<a href="#" onclick="' . htmlspecialchars($onClick) . '">' . IconUtility::getSpriteIcon('actions-document-localize', array('title' => $languageService->sL('LLL:EXT:lang/locallang_misc.xlf:localize', TRUE))) . '</a>';
+                               $cells['localize'] = '
+                                       <a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '">
+                                               ' . IconUtility::getSpriteIcon('actions-document-localize', array('title' => $languageService->sL('LLL:EXT:lang/locallang_misc.xlf:localize', TRUE))) . '
+                                       </a>';
                        }
                }
                // If the record is edit-locked by another user, we will show a little warning sign:
                if ($lockInfo = BackendUtility::isRecordLocked($foreign_table, $rec['uid'])) {
-                       $cells['locked'] = '<a href="#" onclick="alert(' . GeneralUtility::quoteJSvalue($lockInfo['msg']) . ');return false;">' . IconUtility::getSpriteIcon('status-warning-in-use', array('title' => $lockInfo['msg'])) . '</a>';
+                       $cells['locked'] = '
+                               <a class="btn btn-default" href="#" onclick="alert(' . GeneralUtility::quoteJSvalue($lockInfo['msg']) . ');return false;">
+                                       ' . IconUtility::getSpriteIcon('status-warning-in-use', array('title' => $lockInfo['msg'])) . '
+                               </a>';
                }
                // Hook: Post-processing of single controls for specific child records:
                foreach ($this->hookObjects as $hookObj) {
                        $hookObj->renderForeignRecordHeaderControl_postProcess($parentUid, $foreign_table, $rec, $config, $isVirtualRecord, $cells);
                }
-               return '<!-- CONTROL PANEL: ' . $foreign_table . ':' . $rec['uid'] . ' -->' . implode('', $cells);
+
+
+
+               $out = '
+                       <!-- CONTROL PANEL: ' . $foreign_table . ':' . $rec['uid'] . ' -->
+                       <img name="' . $nameObjectFtId . '_req" src="clear.gif" alt="" />';
+               if (!empty($cells)) {
+                       $out .= ' <div class="btn-group btn-group-sm" role="group">' . implode('', $cells) . '</div>';
+               }
+               if (!empty($additionalCells)) {
+                       $out .= ' <div class="btn-group btn-group-sm" role="group">' . implode('', $additionalCells) . '</div>';
+               }
+               return $out;
        }
 
        /**
@@ -805,7 +836,6 @@ class InlineElement {
                        $out = $flashMessage->render();
                        // Get the FormEngine interpretation of the TCA of the child table
                        $out .= $this->renderMainFields($comboConfig['foreign_table'], $comboRecord);
-                       $out = $this->wrapFormsSection($out, array(), array());
                        // If this is a new record, add a pid value to store this record and the pointer value for the intermediate table
                        if ($isNewRecord) {
                                $comboFormFieldName = $this->prependFormFieldNames . '[' . $comboConfig['foreign_table'] . '][' . $comboRecord['uid'] . '][pid]';
@@ -879,9 +909,8 @@ class InlineElement {
                        $size = $conf['autoSizeMax'] ? MathUtility::forceIntegerInRange(count($selItems) + 1, MathUtility::forceIntegerInRange($size, 1), $conf['autoSizeMax']) : $size;
                        $onChange = 'return inline.importNewRecord(\'' . $this->inlineNames['object'] . self::Structure_Separator . $conf['foreign_table'] . '\')';
                        $item = '
-                               <select id="' . $this->inlineNames['object'] . self::Structure_Separator . $conf['foreign_table'] . '_selector" class="t3-formengine-field-select"' . ($size ? ' size="' . $size . '"' : '') . ' onchange="' . htmlspecialchars($onChange) . '"' . $PA['onFocus'] . $selector_itemListStyle . ($conf['foreign_unique'] ? ' isunique="isunique"' : '') . '>
-                                       ' . implode('
-                                       ', $opt) . '
+                               <select id="' . $this->inlineNames['object'] . self::Structure_Separator . $conf['foreign_table'] . '_selector" class="form-control"' . ($size ? ' size="' . $size . '"' : '') . ' onchange="' . htmlspecialchars($onChange) . '"' . $PA['onFocus'] . $selector_itemListStyle . ($conf['foreign_unique'] ? ' isunique="isunique"' : '') . '>
+                                       ' . implode('', $opt) . '
                                </select>';
                        // Add a "Create new relation" link for adding new relations
                        // This is necessary, if the size of the selector is "1" or if
@@ -892,10 +921,15 @@ class InlineElement {
                        } else {
                                $createNewRelationText = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.createNewRelation', TRUE);
                        }
-                       $item .= ' <a href="#" class="btn btn-default" onclick="' . htmlspecialchars($onChange) . '" align="abstop">' . IconUtility::getSpriteIcon('actions-document-new', array('title' => $createNewRelationText)) . $createNewRelationText . '</a>';
+                       $item .= '
+                               <span class="input-group-btn">
+                                       <a href="#" class="btn btn-default" onclick="' . htmlspecialchars($onChange) . '">
+                                               ' . IconUtility::getSpriteIcon('actions-document-new', array('title' => $createNewRelationText)) . $createNewRelationText . '
+                                       </a>
+                               </span>';
                        // Wrap the selector and add a spacer to the bottom
                        $nameObject = $this->inlineNames['object'];
-                       $item = '<div class="t3-form-field-group ' . $this->inlineData['config'][$nameObject]['md5'] . '">' . $item . '</div>';
+                       $item = '<div class="input-group form-group ' . $this->inlineData['config'][$nameObject]['md5'] . '">' . $item . '</div>';
                }
                return $item;
        }
@@ -938,9 +972,11 @@ class InlineElement {
                $browserParams = '|||' . $allowed . '|' . $objectPrefix . '|inline.checkUniqueElement||inline.importElement';
                $onClick = 'setFormValueOpenBrowser(\'' . $mode . '\', \'' . $browserParams . '\'); return false;';
 
-               $item = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($onClick) . '">';
-               $item .= IconUtility::getSpriteIcon('actions-insert-record', array('title' => $createNewRelationText));
-               $item .= $createNewRelationText . '</a>';
+               $item = '
+                       <a href="#" class="btn btn-default" onclick="' . htmlspecialchars($onClick) . '">
+                               ' . IconUtility::getSpriteIcon('actions-insert-record', array('title' => $createNewRelationText)) . '
+                               ' . $createNewRelationText . '
+                       </a>';
 
                if ($showUpload && $this->fObj->edit_docModuleUpload) {
                        $folder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
@@ -965,8 +1001,17 @@ class InlineElement {
                        }
                }
 
+               $item = '<div class="form-control-wrap">' . $item . '</div>';
+               $allowedList = '';
+               $allowedArray = GeneralUtility::trimExplode(',', $allowed, TRUE);
                $allowedLabel = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.allowedFileExtensions', TRUE);
-               $item .= '<span class="btn-after">' . $allowedLabel . ' ' . $allowed . '</span>';
+               foreach ($allowedArray as $allowedItem) {
+                       $allowedList .= '<span class="label label-success">' . strtoupper($allowedItem) . '</span> ';
+               }
+               if (!empty($allowedList)) {
+                       $item .= '<div class="help-block">' . $allowedLabel . '<br>' . $allowedList . '</div>';
+               }
+               $item = '<div class="form-group">' . $item . '</div>';
                return $item;
        }
 
@@ -2223,8 +2268,10 @@ class InlineElement {
         * @param array $styleAttrs Attributes for the style argument in the table tag
         * @param array $tableAttrs Attributes for the table tag (like width, border, etc.)
         * @return string The wrapped HTML code
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8.
         */
        public function wrapFormsSection($section, $styleAttrs = array(), $tableAttrs = array()) {
+               GeneralUtility::logDeprecatedFunction();
                $style = '';
                $table = '';
                foreach ($styleAttrs as $key => $value) {
index 7de17d3..83528da 100644 (file)
@@ -34,14 +34,16 @@ class InputElement extends AbstractFormElement {
         * @return string The HTML code for the TCEform field
         */
        public function render($table, $field, $row, &$additionalInformation) {
+
                $isDateField = FALSE;
+
                $config = $additionalInformation['fieldConf']['config'];
                $specConf = BackendUtility::getSpecConfParts($additionalInformation['extra'], $additionalInformation['fieldConf']['defaultExtras']);
-               $size = MathUtility::forceIntegerInRange($config['size'] ? $config['size'] : 30, 5, $this->formEngine->maxInputWidth);
+               $size = MathUtility::forceIntegerInRange($config['size'] ?: $this->formEngine->defaultInputWidth, $this->formEngine->minimumInputWidth, $this->formEngine->maxInputWidth);
                $evalList = GeneralUtility::trimExplode(',', $config['eval'], TRUE);
-               $classAndStyleAttributes = $this->formEngine->formWidthAsArray($size);
-               $cssClasses = array($classAndStyleAttributes['class']);
-               $cssStyle = $classAndStyleAttributes['style'];
+               $classes = array();
+               $attributes = array();
+
                if (!isset($config['checkbox'])) {
                        $config['checkbox'] = '0';
                        $checkboxIsset = FALSE;
@@ -62,75 +64,58 @@ class InputElement extends AbstractFormElement {
                $dateFormats['datetime'] = $dateFormats['time'] . ' ' . $dateFormats['date'];
                $dateFormats['datetimesec'] = $dateFormats['timesec'] . ' ' . $dateFormats['date'];
 
+               // readonly
+               if ($this->isRenderReadonly() || $config['readOnly']) {
+                       $itemFormElValue = $additionalInformation['itemFormElValue'];
+                       if (in_array('date', $evalList)) {
+                               $config['format'] = 'date';
+                       } elseif (in_array('datetime', $evalList)) {
+                               $config['format'] = 'datetime';
+                       } elseif (in_array('time', $evalList)) {
+                               $config['format'] = 'time';
+                       }
+                       if (in_array('password', $evalList)) {
+                               $itemFormElValue = $itemFormElValue ? '*********' : '';
+                       }
+                       return $this->formEngine->getSingleField_typeNone_render($config, $itemFormElValue);
+               }
+
 
-               if (in_array('date', $evalList) || in_array('datetime', $evalList)) {
+               if (in_array('datetime', $evalList, TRUE)
+                       || in_array('date', $evalList)
+                       || in_array('time', $evalList)) {
+
+                       $classes[] = 't3js-datetimepicker';
+                       $isDateField = TRUE;
                        if (in_array('datetime', $evalList)) {
-                               $class = 'datetime';
+                               $attributes['data-date-type'] = 'datetime';
                                $dateFormat = $dateFormats['datetime'];
-                       } else {
-                               $class = 'date';
+                       } elseif (in_array('date', $evalList)) {
+                               $attributes['data-date-type'] = 'date';
                                $dateFormat = $dateFormats['date'];
+                       } else {
+                               $attributes['data-date-type'] = 'time';
+                               $dateFormat = $dateFormats['time'];
+                       }
+                       if ($additionalInformation['itemFormElValue'] > 0) {
+                               $additionalInformation['itemFormElValue'] += date('Z', $additionalInformation['itemFormElValue']);
                        }
-                       $dateRange = '';
-                       $lowerValue = NULL;
-                       $upperValue = NULL;
                        if (isset($config['range']['lower'])) {
-                               $lowerValue = (int)$config['range']['lower'];
-                               $dateRange .= ' lower-' . $lowerValue;
+                               $attributes['data-date-minDate'] = (int)$config['range']['lower'];
                        }
                        if (isset($config['range']['upper'])) {
-                               $upperValue = (int)$config['range']['upper'];
-                               $dateRange .= ' upper-' . $upperValue;
+                               $attributes['data-date-maxDate'] = (int)$config['range']['upper'];
                        }
-                       $inputId = uniqid('tceforms-' . $class . 'field-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-' . $class . 'field' . $dateRange;
-                       $isDateField = TRUE;
                } elseif (in_array('timesec', $evalList)) {
-                       $inputId = uniqid('tceforms-timesecfield-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-timesecfield';
-               } elseif (in_array('year', $evalList)) {
-                       $inputId = uniqid('tceforms-yearfield-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-yearfield';
-               } elseif (in_array('time', $evalList)) {
-                       $inputId = uniqid('tceforms-timefield-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-timefield';
-                       $isDateField = TRUE;
-                       $dateFormat = $dateFormats['time'];
-               } elseif (in_array('int', $evalList)) {
-                       $inputId = uniqid('tceforms-intfield-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-intfield';
-               } elseif (in_array('double2', $evalList)) {
-                       $inputId = uniqid('tceforms-double2field-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-double2field';
+                       $classes[] = 't3js-datetimepicker';
+                       $attributes['data-date-type'] = 'timesec';
                } else {
-                       $inputId = uniqid('tceforms-textfield-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield';
                        if ($checkboxIsset === FALSE) {
                                $config['checkbox'] = '';
                        }
                }
-               if (isset($config['wizards']['link'])) {
-                       $inputId = uniqid('tceforms-linkfield-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-linkfield';
-               } elseif (isset($config['wizards']['color'])) {
-                       $inputId = uniqid('tceforms-colorfield-', TRUE);
-                       $cssClasses[] = 'tceforms-textfield tceforms-colorfield';
-               }
-               $inputId = str_replace('.', '', $inputId);
-               if ($this->isRenderReadonly() || $config['readOnly']) {
-                       $itemFormElValue = $additionalInformation['itemFormElValue'];
-                       if (in_array('date', $evalList)) {
-                               $config['format'] = 'date';
-                       } elseif (in_array('datetime', $evalList)) {
-                               $config['format'] = 'datetime';
-                       } elseif (in_array('time', $evalList)) {
-                               $config['format'] = 'time';
-                       }
-                       if (in_array('password', $evalList)) {
-                               $itemFormElValue = $itemFormElValue ? '*********' : '';
-                       }
-                       return $this->formEngine->getSingleField_typeNone_render($config, $itemFormElValue);
-               }
+
+
                foreach ($evalList as $func) {
                        switch ($func) {
                                case 'required':
@@ -152,30 +137,44 @@ class InputElement extends AbstractFormElement {
                        }
                }
                $paramsList = '\'' . $additionalInformation['itemFormElName'] . '\',\'' . implode(',', $evalList) . '\',\'' . trim($config['is_in']) . '\',' . (isset($config['checkbox']) ? 1 : 0) . ',\'' . $config['checkbox'] . '\'';
+               $additionalInformation['fieldChangeFunc'] = array_merge(array('typo3form.fieldGet' => 'typo3form.fieldGet(' . $paramsList . ');'), $additionalInformation['fieldChangeFunc']);
 
+               // set classes
+               $classes[] = 'form-control';
+               $classes[] = 't3js-clearable';
+               $classes[] = 'hasDefaultValue';
 
-               $textFieldAttributes = array();
-               // additional data for the DatePicker
-               if ($isDateField) {
-                       // Add server timezone offset to UTC to our stored date
-                       if ($additionalInformation['itemFormElValue'] > 0) {
-                               $additionalInformation['itemFormElValue'] += date('Z', $additionalInformation['itemFormElValue']);
-                       }
-                       if ($lowerValue !== NULL) {
-                               $textFieldAttributes[] = 'data-date-minDate="' . strftime($dateFormat, $lowerValue) . '"';
-                       }
-                       if ($upperValue !== NULL) {
-                               $textFieldAttributes[] = 'data-date-maxDate="' . strftime($dateFormat, $upperValue) . '"';
-                       }
-                       $cssClasses[] = 'form-control';
+               // calculate attributes
+               $attributes['id'] = str_replace('.', '', uniqid('formengine-input-', TRUE));
+               $attributes['name'] = $additionalInformation['itemFormElName'] . '_hr';
+               $attributes['value'] = '';
+               $attributes['maxlength'] = $config['max'] ?: 256;
+               $attributes['onchange'] = htmlspecialchars(implode('', $additionalInformation['fieldChangeFunc']));
+
+               if (!empty($styles)) {
+                       $attributes['style'] = implode(' ', $styles);
+               }
+               if (!empty($classes)) {
+                       $attributes['class'] = implode(' ', $classes);
+               }
+               if (isset($config['max']) && (int)$config['max'] > 0) {
+                       $attributes['maxlength'] = (int)$config['max'];
+               }
+
+               // Build the attribute string
+               $attributeString = '';
+               foreach ($attributes as $attributeName => $attributeValue) {
+                       $attributeString .= ' '. $attributeName . '="' . $attributeValue . '"';
                }
-               $additionalInformation['fieldChangeFunc'] = array_merge(array('typo3form.fieldGet' => 'typo3form.fieldGet(' . $paramsList . ');'), $additionalInformation['fieldChangeFunc']);
 
-               $mLgd = $config['max'] ?: 256;
-               $iOnChange = implode('', $additionalInformation['fieldChangeFunc']);
-               $cssClasses[] = 'hasDefaultValue';
                // This is the EDITABLE form field.
-               $item = '<input type="text" ' . $this->formEngine->getPlaceholderAttribute($table, $field, $config, $row) . 'id="' . $inputId . '" ' . 'class="' . implode(' ', $cssClasses) . '" ' . 'name="' . $additionalInformation['itemFormElName'] . '_hr" ' . 'value=""' . 'style="' . $cssStyle . '" ' . 'maxlength="' . $mLgd . '" ' . 'onchange="' . htmlspecialchars($iOnChange) . '"' . $additionalInformation['onFocus'] . ' ' . implode(' ', $textFieldAttributes)  . ' />';
+               $item = '
+                       <input type="text"'
+                               . $attributeString
+                               . $this->formEngine->getPlaceholderAttribute($table, $field, $config, $row)
+                               . 'style="' . $cssStyle . '" '
+                               . $additionalInformation['onFocus'] . ' />';
+
                // This is the ACTUAL form field - values from the EDITABLE field must be transferred to this field which is the one that is written to the database.
                $item .= '<input type="hidden" name="' . $additionalInformation['itemFormElName'] . '" value="' . htmlspecialchars($additionalInformation['itemFormElValue']) . '" />';
 
@@ -194,17 +193,36 @@ TBE_EDITOR.customEvalFunctions[\'' . $evalData . '\'] = function(value) {
 
                // add HTML wrapper
                if ($isDateField) {
-                       $fieldAppendix = '<span class="input-group-addon datepickerbutton">' . IconUtility::getSpriteIcon('actions-edit-pick-date', array('style' => 'cursor:pointer;')) . '</span>';
-                       $item = '<span class="t3-tceforms-input-wrapper-datetime date t3js-datetimepicker input-group">' . $item . $fieldAppendix . '</span>';
-               } else {
-                       $item = '<span class="t3-tceforms-input-wrapper">' . $item . '</span>';
+                       $item = '
+                               <div class="input-group">
+                                       ' . $item . '
+                                       <span class="input-group-btn">
+                                               <label class="btn btn-default" for="' . $attributes['id'] . '">
+                                                       ' . IconUtility::getSpriteIcon('actions-edit-pick-date') . '
+                                               </label>
+                                       </span>
+                               </div>';
                }
 
                // Creating an alternative item without the JavaScript handlers.
-               $altItem = '<input type="hidden" name="' . $additionalInformation['itemFormElName'] . '_hr" value="" />';
-               $altItem .= '<input type="hidden" name="' . $additionalInformation['itemFormElName'] . '" value="' . htmlspecialchars($additionalInformation['itemFormElValue']) . '" />';
+               $altItem = '
+                       <input type="hidden" name="' . $additionalInformation['itemFormElName'] . '_hr" value="" />
+                       <input type="hidden" name="' . $additionalInformation['itemFormElName'] . '" value="' . htmlspecialchars($additionalInformation['itemFormElValue']) . '" />';
+
                // Wrap a wizard around the item?
-               $item = $this->formEngine->renderWizards(array($item, $altItem), $config['wizards'], $table, $row, $field, $additionalInformation, $additionalInformation['itemFormElName'] . '_hr', $specConf);
+               $item = $this->formEngine->renderWizards(
+                       array($item, $altItem),
+                       $config['wizards'],
+                       $table,
+                       $row,
+                       $field,
+                       $additionalInformation,
+                       $additionalInformation['itemFormElName'] . '_hr', $specConf
+               );
+
+               // Add a wrapper to remain maximum width
+               $width = (int)$this->formEngine->formMaxWidth($size);
+               $item = '<div class="form-control-wrap"' . ($width ? ' style="max-width: ' . $width . 'px"' : '') . '>' . $item . '</div>';
                return $item;
        }
 
index 61ab33d..f351973 100644 (file)
@@ -65,7 +65,6 @@ class RadioElement extends AbstractFormElement {
                                . '<label for="' . $radioId . '">'
                                . '<input '
                                . 'type="radio" '
-                               . 'class="' . $this->cssClassTypeElementPrefix . 'radio" '
                                . 'name="' . htmlspecialchars($additionalInformation['itemFormElName']) . '" '
                                . 'id="' . $radioId . '" '
                                . 'value="' . htmlspecialchars($selectedItem[1]) . '" '
index 6a52738..705354e 100644 (file)
@@ -216,7 +216,7 @@ class SelectElement extends AbstractFormElement {
                        $itemsToSelect = '
                                <select data-relatedfieldname="' . htmlspecialchars($PA['itemFormElName']) . '" data-exclusivevalues="'
                                . htmlspecialchars($config['exclusiveKeys']) . '" id="' . $multiSelectId . '" name="' . $PA['itemFormElName'] . '_sel" '
-                               . ' class="' . $this->cssClassTypeElementPrefix . 'select tceforms-multiselect tceforms-itemstoselect t3-form-select-itemstoselect" '
+                               . ' class="form-control t3js-formengine-select-itemstoselect" '
                                . ($size ? ' size="' . $size . '"' : '') . ' onchange="' . htmlspecialchars($sOnChange) . '"'
                                . $PA['onFocus'] . $selector_itemListStyle . '>
                                        ' . implode('
@@ -225,7 +225,13 @@ class SelectElement extends AbstractFormElement {
 
                        // enable filter functionality via a text field
                        if ($config['enableMultiSelectFilterTextfield']) {
-                               $filterTextfield = '<span class="input-group"><span class="input-group-addon"><span class="fa fa-filter"></span></span><input class="t3-form-multiselect-filter-textfield form-control" value="" /></span>';
+                               $filterTextfield = '
+                                       <span class="input-group input-group-sm">
+                                               <span class="input-group-addon">
+                                                       <span class="fa fa-filter"></span>
+                                               </span>
+                                               <input class="t3js-formengine-multiselect-filter-textfield form-control" value="" />
+                                       </span>';
                        }
 
                        // enable filter functionality via a select
@@ -237,16 +243,19 @@ class SelectElement extends AbstractFormElement {
                                        $filterDropDownOptions[] = '<option value="' . htmlspecialchars($languageService->sL($optionElement[0])) . '">'
                                                . htmlspecialchars($optionValue) . '</option>';
                                }
-                               $filterSelectbox = '<select class="t3-form-multiselect-filter-dropdown form-control">
+                               $filterSelectbox = '<select class="form-control input-sm t3js-formengine-multiselect-filter-dropdown">
                                                ' . implode('
                                                ', $filterDropDownOptions) . '
                                        </select>';
                        }
                }
 
-               $selectBoxFilterContents = trim($filterSelectbox . $filterTextfield);
-               if (!empty($selectBoxFilterContents)) {
-                       $selectBoxFilterContents = '<div class="form-inline"><div class="t3-form-multiselect-filter-container form-group-sm pull-right">' . $selectBoxFilterContents . '</div></div>';
+               if (!empty(trim($filterSelectbox)) && !empty(trim($filterTextfield))) {
+                       $filterSelectbox = '<div class="form-multigroup-item form-multigroup-element">' . $filterSelectbox . '</div>';
+                       $filterTextfield = '<div class="form-multigroup-item form-multigroup-element">' . $filterTextfield . '</div>';
+                       $selectBoxFilterContents = '<div class="t3js-formengine-multiselect-filter-container form-multigroup-wrap">' . $filterSelectbox . $filterTextfield . '</div>';
+               } else {
+                       $selectBoxFilterContents = trim($filterSelectbox . ' ' . $filterTextfield);
                }
 
                // Pass to "dbFileIcons" function:
@@ -260,11 +269,12 @@ class SelectElement extends AbstractFormElement {
                        'maxitems' => $maxitems,
                        'info' => '',
                        'headers' => array(
-                               'selector' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.selected') . ':<br />',
-                               'items' => '<div class="pull-left">' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.items') . ':</div>' . $selectBoxFilterContents
+                               'selector' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.selected'),
+                               'items' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.items'),
+                               'selectorbox' => $selectBoxFilterContents,
                        ),
                        'noBrowser' => 1,
-                       'thumbnails' => $itemsToSelect,
+                       'rightbox' => $itemsToSelect,
                        'readOnly' => $disabled
                );
                $item .= $this->formEngine->dbFileIcons($PA['itemFormElName'], '', '', $itemArray, '', $params, $PA['onFocus']);
@@ -360,12 +370,13 @@ class SelectElement extends AbstractFormElement {
         * @param array $row See getSingleField_typeSelect()
         * @param array $PA See getSingleField_typeSelect()
         * @param array $config (Redundant) content of $PA['fieldConf']['config'] (for convenience)
-        * @param array $selItems Items available for selection
-        * @param string $nMV_label Label for no-matching-value
+        * @param array $selectItems Items available for selection
+        * @param string $noMatchingLabel Label for no-matching-value
         * @return string The HTML code for the item
         * @see getSingleField_typeSelect()
         */
-       public function getSingleField_typeSelect_single($table, $field, $row, &$PA, $config, $selItems, $nMV_label) {
+       public function getSingleField_typeSelect_single($table, $field, $row, &$PA, $config, $selectItems, $noMatchingLabel) {
+
                // check against inline uniqueness
                $inlineParent = $this->formEngine->inline->getStructureLevel(-1);
                $uniqueIds = NULL;
@@ -385,20 +396,21 @@ class SelectElement extends AbstractFormElement {
                                $uniqueIds[] = $inlineParent['uid'];
                        }
                }
+
                // Initialization:
-               $c = 0;
-               $sI = 0;
+               $selectId = str_replace('.', '', uniqid('tceforms-select-', TRUE));
+               $selectedIndex = 0;
+               $selectedIcon = '';
                $noMatchingValue = 1;
-               $opt = array();
-               $selicons = array();
                $onlySelectedIconShown = 0;
                $size = (int)$config['size'];
+
                // Style set on <select/>
-               $selectedStyle = '';
-               $item = '';
-               $disabled = '';
+               $out = '';
+               $options = '';
+               $disabled = FALSE;
                if ($this->isRenderReadonly() || $config['readOnly']) {
-                       $disabled = ' disabled="disabled"';
+                       $disabled = TRUE;
                        $onlySelectedIconShown = 1;
                }
                // Register as required if minitems is greater than zero
@@ -417,121 +429,145 @@ class SelectElement extends AbstractFormElement {
                } else {
                        $suppressIcons = 0;
                }
-               // Traverse the Array of selector box items:
-               $optGroupStart = array();
-               $optGroupOpen = FALSE;
-               $classesForSelectTag = array();
-               foreach ($selItems as $p) {
-                       $sM = (string)$PA['itemFormElValue'] === (string)$p[1] ? ' selected="selected"' : '';
-                       if ($sM) {
-                               $sI = $c;
-                               $noMatchingValue = 0;
-                       }
-                       // Getting style attribute value (for icons):
-                       $styleAttrValue = '';
-                       if ($config['iconsInOptionTags']) {
-                               $styleAttrValue = $this->formEngine->optionTagStyle($p[2]);
-                               if ($sM) {
-                                       list($selectIconFile, $selectIconInfo) = $this->formEngine->getIcon($p[2]);
-                                       if (!empty($selectIconInfo)) {
-                                               $selectedStyle = ' style="background-image:url(' . $selectIconFile . ');"';
-                                               $classesForSelectTag[] = 'typo3-TCEforms-select-selectedItemWithBackgroundImage';
-                                       }
+
+               // Prepare groups
+               $selectItemCounter = 0;
+               $selectItemGroupCount = 0;
+               $selectItemGroups = array();
+               $selectIcons = array();
+               foreach ($selectItems as $item) {
+                       if ($item[1] === '--div--') {
+                               // IS OPTGROUP
+                               if ($selectItemCounter !== 0) {
+                                       $selectItemGroupCount++;
                                }
-                       }
-                       // Compiling the <option> tag:
-                       if (!($p[1] != $PA['itemFormElValue'] && is_array($uniqueIds) && in_array($p[1], $uniqueIds))) {
-                               if ($p[1] === '--div--') {
-                                       $optGroupStart[0] = $p[0];
+                               $selectItemGroups[$selectItemGroupCount]['header'] = array(
+                                       'title' => $item[0],
+                                       'icon' => (!empty($item[2]) ? $this->formEngine->getIconHtml($item[2]) : '')
+                               );
+                       } else {
+                               // IS ITEM
+                               $title = htmlspecialchars($item['0'], ENT_COMPAT, 'UTF-8', FALSE);
+                               $value = htmlspecialchars($item[1]);
+                               $icon = (!empty($item[2]) ? $this->formEngine->getIconHtml($item[2], $title, $title) : '');
+                               $selected = ((string)$PA['itemFormElValue'] === (string)$item[1] ? 1 : 0);
+                               if ($selected) {
+                                       $selectedIndex = $selectItemCounter;
+                                       $selectedValue = $item[1];
+                                       $selectedIcon = $icon;
+                                       $noMatchingValue = 0;
+                               }
+                               $selectItemGroups[$selectItemGroupCount]['items'][] = array(
+                                       'title' => $title,
+                                       'value' => $value,
+                                       'icon' => $icon,
+                                       'selected' => $selected,
+                                       'index' => $selectItemCounter
+                               );
+                               // ICON
+                               if ($icon && !$suppressIcons && (!$onlySelectedIconShown || $selected)) {
+                                       $onClick = $this->formEngine->elName($PA['itemFormElName']) . '.selectedIndex=' . $selectItemCounter . ';';
                                        if ($config['iconsInOptionTags']) {
-                                               $optGroupStart[1] = $this->formEngine->optgroupTagStyle($p[2]);
-                                       } else {
-                                               $optGroupStart[1] = $styleAttrValue;
+                                               $onClick .= 'document.getElementById(\'' . $selectId . '_icon\').innerHTML = '
+                                                       . $this->formEngine->elName($PA['itemFormElName'])
+                                                       . '.options[' . $selectItemCounter . '].getAttribute(\'data-icon\'); ';
                                        }
-                               } else {
-                                       if (count($optGroupStart)) {
-                                               // Closing last optgroup before next one starts
-                                               if ($optGroupOpen) {
-                                                       $opt[] = '</optgroup>' . LF;
-                                               }
-                                               $opt[] = '<optgroup label="' . htmlspecialchars($optGroupStart[0], ENT_COMPAT, 'UTF-8', FALSE)
-                                                       . '"' . ($optGroupStart[1] ? ' style="' . htmlspecialchars($optGroupStart[1]) . '"' : '')
-                                                       . ' class="c-divider">' . LF;
-                                               $optGroupOpen = TRUE;
-                                               $c--;
-                                               $optGroupStart = array();
-                                       }
-                                       $opt[] = '<option value="' . htmlspecialchars($p[1]) . '"' . $sM
-                                               . ($styleAttrValue ? ' style="' . htmlspecialchars($styleAttrValue) . '"' : '') . '>'
-                                               . htmlspecialchars($p[0], ENT_COMPAT, 'UTF-8', FALSE) . '</option>' . LF;
+                                       $onClick .= implode('', $PA['fieldChangeFunc']);
+                                       $onClick .= 'this.blur();return false;';
+                                       $selectIcons[] = array(
+                                               'title' => $title,
+                                               'icon' => $icon,
+                                               'index' => $selectItemCounter,
+                                               'onClick' => $onClick
+                                       );
                                }
+                               $selectItemCounter++;
                        }
-                       // If there is an icon for the selector box (rendered in selicon-table below)...:
-                       // if there is an icon ($p[2]), icons should be shown, and, if only selected are visible, is it selected
-                       if ($p[2] && !$suppressIcons && (!$onlySelectedIconShown || $sM)) {
-                               list($selIconFile, $selIconInfo) = $this->formEngine->getIcon($p[2]);
-                               $iOnClick = $this->formEngine->elName($PA['itemFormElName']) . '.selectedIndex=' . $c . '; ' . $this->formEngine->elName($PA['itemFormElName']);
-                               $iOnClickOptions = $this->formEngine->elName($PA['itemFormElName']) . '.options[' . $c . ']';
-                               if (empty($selIconInfo)) {
-                                       $iOnClick .= '.className=' . $iOnClickOptions . '.className; ';
-                               } else {
-                                       $iOnClick .= '.style.backgroundImage=' . $iOnClickOptions . '.style.backgroundImage; ';
-                               }
-                               $iOnClick .= implode('', $PA['fieldChangeFunc']) . 'this.blur(); return false;';
-                               $selicons[] = array(
-                                       (!$onlySelectedIconShown ? '<a href="#" onclick="' . htmlspecialchars($iOnClick) . '">' : '')
-                                       . $this->formEngine->getIconHtml($p[2], htmlspecialchars($p[0]), htmlspecialchars($p[0]))
-                                       . (!$onlySelectedIconShown ? '</a>' : ''),
-                                       $c,
-                                       $sM
-                               );
-                       }
-                       $c++;
-               }
-               // Closing optgroup if open
-               if ($optGroupOpen) {
-                       $opt[] = '</optgroup>';
+
                }
+
                // No-matching-value:
                if ($PA['itemFormElValue'] && $noMatchingValue && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
-                       $nMV_label = @sprintf($nMV_label, $PA['itemFormElValue']);
-                       $opt[] = '<option value="' . htmlspecialchars($PA['itemFormElValue']) . '" selected="selected">' . htmlspecialchars($nMV_label) . '</option>';
+                       $noMatchingLabel = @sprintf($noMatchingLabel, $PA['itemFormElValue']);
+                       $options = '<option value="' . htmlspecialchars($PA['itemFormElValue']) . '" selected="selected">' . htmlspecialchars($noMatchingLabel) . '</option>';
+               } elseif (!$selectedIcon && $selectItemGroups[0]['items'][0]['icon']) {
+                       $selectedIcon = $selectItemGroups[0]['items'][0]['icon'];
+               }
+
+               // Process groups
+               foreach ($selectItemGroups as $selectItemGroup) {
+                       $optionGroup = is_array($selectItemGroup['header']);
+                       $options .= ($optionGroup ? '<optgroup label="' . htmlspecialchars($selectItemGroup['header']['title'], ENT_COMPAT, 'UTF-8', FALSE) . '">' : '');
+                       if (is_array($selectItemGroup['items'])) {
+                               foreach ($selectItemGroup['items'] as $item) {
+                                       $options .= '<option value="' . htmlspecialchars($item['value']) . '" data-icon="' .
+                                               htmlspecialchars($item['icon']) . '"'
+                                               . ($item['selected'] ? ' selected="selected"' : '') . '>' . $item['title'] . '</option>';
+                               }
+                       }
+                       $options .= ($optionGroup ? '</optgroup>' : '');
                }
+
                // Create item form fields:
-               $sOnChange = 'if (this.options[this.selectedIndex].value==\'--div--\') {this.selectedIndex=' . $sI . ';} ' . implode('', $PA['fieldChangeFunc']);
-               if (!$disabled) {
-                       // MUST be inserted before the selector - else is the value of the hiddenfield here mysteriously submitted...
-                       $item .= '<input type="hidden" name="' . $PA['itemFormElName'] . '_selIconVal" value="' . htmlspecialchars($sI) . '" />';
-               }
+               $sOnChange = 'if (this.options[this.selectedIndex].value==\'--div--\') {this.selectedIndex=' . $selectedIndex . ';} ';
                if ($config['iconsInOptionTags']) {
-                       $classesForSelectTag[] = 'icon-select';
+                       $sOnChange .= 'document.getElementById(\'' . $selectId . '_icon\').innerHTML = this.options[this.selectedIndex].getAttribute(\'data-icon\'); ';
                }
-               $item .= '<select' . $selectedStyle . ' id="' . str_replace('.', '', uniqid('tceforms-select-', TRUE)) . '" name="' . $PA['itemFormElName'] . '" class="' . $this->cssClassTypeElementPrefix . 'select ' . implode(' ', $classesForSelectTag) . '"' . ($size ? ' size="' . $size . '"' : '') . ' onchange="' . htmlspecialchars($sOnChange) . '"' . $PA['onFocus'] . $disabled . '>';
-               $item .= implode('', $opt);
-               $item .= '</select>';
+               $sOnChange .= implode('', $PA['fieldChangeFunc']);
+
+               // Add icons in option tags
+               $prepend = '';
+               $append = '';
+               if ($config['iconsInOptionTags']) {
+                       $prepend = '<div class="input-group"><div id="' . $selectId . '_icon" class="input-group-addon input-group-icon t3js-formengine-select-prepend">' . $selectedIcon . '</div>';
+                       $append = '</div>';
+               }
+
+               // Build the element
+               $out .= '
+                       <div class="form-control-wrap">
+                               ' . $prepend . '
+                               <select'
+                                       . ' id="' . $selectId . '"'
+                                       . ' name="' . $PA['itemFormElName'] . '"'
+                                       . ' class="form-control form-control-adapt"'
+                                       . ($size ? ' size="' . $size . '"' : '')
+                                       . ' onchange="' . htmlspecialchars($sOnChange) . '"'
+                                       . $PA['onFocus']
+                                       . ($disabled ? ' disabled="disabled"' : '')
+                                       . '>
+                                       ' . $options . '
+                               </select>
+                               ' . (!$disabled ? '<input type="hidden" name="' . $PA['itemFormElName'] . '_selIconVal" value="' . $selectedValue . '" />' : '') . '
+                               ' . $append . '
+                       </div>';
+
                // Create icon table:
-               if (count($selicons) && !$config['noIconsBelowSelect']) {
-                       $item .= '<div class="typo3-TCEforms-selectIcons">';
-                       $selicon_cols = (int)$config['selicon_cols'];
-                       if (!$selicon_cols) {
-                               $selicon_cols = count($selicons);
+               if (count($selectIcons) && !$config['noIconsBelowSelect']) {
+                       $selectIconColumns = (int)$config['selicon_cols'];
+                       if (!$selectIconColumns) {
+                               $selectIconColumns = count($selectIcons);
                        }
-                       $sR = ceil(count($selicons) / $selicon_cols);
-                       $selicons = array_pad($selicons, $sR * $selicon_cols, '');
-                       for ($sa = 0; $sa < $sR; $sa++) {
-                               $item .= '<div>';
-                               for ($sb = 0; $sb < $selicon_cols; $sb++) {
-                                       $sk = $sa * $selicon_cols + $sb;
-                                       $imgN = 'selIcon_' . $table . '_' . $row['uid'] . '_' . $field . '_' . $selicons[$sk][1];
-                                       $imgS = $selicons[$sk][2] ? $this->formEngine->backPath . 'gfx/content_selected.gif' : 'clear.gif';
-                                       $item .= '<span><img name="' . htmlspecialchars($imgN) . '" src="' . htmlspecialchars($imgS) . '" width="7" height="10" alt="" /></span>';
-                                       $item .= '<span>' . $selicons[$sk][0] . '</span>';
+                       $selectIconColumns = ($selectIconColumns > 12 ? 12 : $selectIconColumns);
+                       $selectIconRows = ceil(count($selectIcons) / $selectIconColumns);
+                       $selectIcons = array_pad($selectIcons, $selectIconRows * $selectIconColumns, '');
+                       $out .= '<div class="table-fit table-fit-inline-block"><table class="table table-condensed table-white table-center"><tbody><tr>';
+                       for ($selectIconCount = 0; $selectIconCount < count($selectIcons); $selectIconCount++) {
+                               if ($selectIconCount % $selectIconColumns === 0 && $selectIconCount !== 0) {
+                                       $out .= '</tr><tr>';
+                               }
+                               $out .= '<td>';
+                               if (is_array($selectIcons[$selectIconCount])) {
+                                       $out .= (!$onlySelectedIconShown ? '<a href="#" title="' . $selectIcons[$selectIconCount]['title'] . '" onClick="' . htmlspecialchars($selectIcons[$selectIconCount]['onClick']) . '">' : '');
+                                       $out .= $selectIcons[$selectIconCount]['icon'];
+                                       $out .= (!$onlySelectedIconShown ? '</a>' : '');
                                }
-                               $item .= '</div>';
+                               $out . '</td>';
                        }
-                       $item .= '</div>';
+                       $out .= '</tr></tbody></table></div>';
                }
-               return $item;
+
+               return $out;
        }
 
        /**
@@ -778,7 +814,7 @@ class SelectElement extends AbstractFormElement {
                        // Non-selectable element:
                        $nonSel = '';
                        if ((string)$p[1] === '--div--') {
-                               $nonSel = ' onclick="this.selected=0;" class="c-divider"';
+                               $nonSel = ' onclick="this.selected=0;" class="formcontrol-select-divider"';
                        }
                        // Icon style for option tag:
                        $styleAttrValue = '';
@@ -810,7 +846,7 @@ class SelectElement extends AbstractFormElement {
                        ? MathUtility::forceIntegerInRange(count($selItems) + 1, MathUtility::forceIntegerInRange($size, 1), $config['autoSizeMax'])
                        : $size;
                $selectBox = '<select id="' . str_replace('.', '', uniqid($cssPrefix, TRUE)) . '" name="' . $PA['itemFormElName'] . '[]" '
-                       . 'class="' . $this->cssClassTypeElementPrefix . 'select ' . $cssPrefix . '"' . ($size ? ' size="' . $size . '" ' : '')
+                       . 'class="form-control ' . $cssPrefix . '"' . ($size ? ' size="' . $size . '" ' : '')
                        . ' multiple="multiple" onchange="' . htmlspecialchars($sOnChange) . '"' . $PA['onFocus']
                        . ' ' . $selector_itemListStyle . $disabled . '>
                                                ' . implode('
@@ -822,21 +858,23 @@ class SelectElement extends AbstractFormElement {
                }
                // Put it all into a table:
                $onClick = htmlspecialchars($this->formEngine->elName(($PA['itemFormElName'] . '[]')) . '.selectedIndex=-1;' . implode('', $restoreCmd) . ' return false;');
+               $width = $this->formEngine->formMaxWidth($this->formEngine->defaultInputWidth);
                $item .= '
-                       <table border="0" cellspacing="0" cellpadding="0" width="1" class="typo3-TCEforms-select-singlebox">
-                               <tr>
-                                       <td>
-                                       ' . $selectBox . '
-                                       <br/>
-                                       <em>' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.holdDownCTRL')) . '</em>
-                                       </td>
-                                       <td valign="top">
-                                               <a href="#" onclick="' . $onClick . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.revertSelection')) . '">'
-                       . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>
-                                       </td>
-                               </tr>
-                       </table>
-                               ';
+                       <div class="form-control-wrap" ' . ($width ? ' style="max-width: ' . $width . 'px"' : '') . '>
+                               <div class="form-wizards-wrap form-wizards-aside">
+                                       <div class="form-wizards-element">
+                                               ' . $selectBox . '
+                                       </div>
+                                       <div class="form-wizards-items">
+                                               <a href="#" class="btn btn-default" onclick="' . $onClick . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.revertSelection')) . '">'
+                                                       . IconUtility::getSpriteIcon('actions-edit-undo') . '</a>
+                                       </div>
+                               </div>
+                       </div>
+                       <p>
+                               <em>' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.holdDownCTRL')) . '</em>
+                       </p>
+                       ';
                return $item;
        }
 
index 1e0e570..13cca38 100644 (file)
@@ -76,11 +76,14 @@ class SuggestElement {
                }
                $selector = '
                <div class="' . $containerCssClass . '" id="' . $suggestId . '">
-                       <input type="search" id="' . $fieldname . 'Suggest" value="' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.findRecord') . '" class="' . $this->cssClass . '-search" />
-                       <div class="' . $this->cssClass . '-indicator" style="display: none;" id="' . $fieldname . 'SuggestIndicator">
-                               <img src="' . $GLOBALS['BACK_PATH'] . 'gfx/spinner.gif" alt="' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:alttext.suggestSearching') . '" />
+                       <div class="input-group">
+                               <span class="input-group-addon"><i class="fa fa-search"></i></span>
+                               <input type="search" id="' . $fieldname . 'Suggest" value="' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.findRecord') . '" class="form-control ' . $this->cssClass . '-search" />
+                               <div class="' . $this->cssClass . '-indicator" style="display: none;" id="' . $fieldname . 'SuggestIndicator">
+                                       <img src="' . $GLOBALS['BACK_PATH'] . 'gfx/spinner.gif" alt="' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:alttext.suggestSearching') . '" />
+                               </div>
+                               <div class="' . $this->cssClass . '-choices" style="display: none;" id="' . $fieldname . 'SuggestChoices"></div>
                        </div>
-                       <div class="' . $this->cssClass . '-choices" style="display: none;" id="' . $fieldname . 'SuggestChoices"></div>
 
                </div>';
                // Get minimumCharacters from TCA
index 5f930ee..778761c 100644 (file)
@@ -37,7 +37,7 @@ class TextElement extends AbstractFormElement {
                $config = $additionalInformation['fieldConf']['config'];
 
                // Setting columns number
-               $cols = MathUtility::forceIntegerInRange($config['cols'] ?: 30, 5, $this->formEngine->maxTextareaWidth);
+               $cols = MathUtility::forceIntegerInRange($config['cols'] ?: $this->formEngine->defaultInputWidth, $this->formEngine->minimumInputWidth, $this->formEngine->maxInputWidth);
 
                // Setting number of rows
                $rows = MathUtility::forceIntegerInRange($config['rows'] ?: 5, 1, 20);
@@ -45,7 +45,7 @@ class TextElement extends AbstractFormElement {
 
                $itemFormElementValueLength = strlen($additionalInformation['itemFormElValue']);
                if ($itemFormElementValueLength > $this->formEngine->charsPerRow * 2) {
-                       $cols = $this->formEngine->maxTextareaWidth;
+                       $cols = $this->formEngine->maxInputWidth;
                        $rows = MathUtility::forceIntegerInRange(
                                round($itemFormElementValueLength / $this->formEngine->charsPerRow),
                                count(explode(LF, $additionalInformation['itemFormElValue'])),
@@ -146,38 +146,7 @@ class TextElement extends AbstractFormElement {
                        if ($specialConfiguration['rte_only']) {
                                $item = '<p><em>' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.noRTEfound')) . '</em></p>';
                        } else {
-                               if ($specialConfiguration['nowrap']) {
-                                       $wrap = 'off';
-                               } else {
-                                       $wrap = $config['wrap'] ?: 'virtual';
-                               }
-                               $classes = array();
-                               if ($specialConfiguration['fixed-font']) {
-                                       $classes[] = 'fixed-font';
-                               }
-                               if ($specialConfiguration['enable-tab']) {
-                                       $classes[] = 'enable-tab';
-                               }
-                               $formWidthText = $this->formWidthText($cols, $wrap);
-                               // add the max-height from the users' preference to it
-                               $maximumHeight = (int)$this->getBackendUserAuthentication()->uc['resizeTextareas_MaxHeight'];
-                               if ($maximumHeight > 0) {
-                                       $formWidthText = str_replace('style="', 'style="max-height: ' . $maximumHeight . 'px; ', $formWidthText);
-                               }
-
-                               // Extract class attributes from $formWidthText (otherwise it would be added twice to the output)
-                               $res = array();
-                               if (preg_match('/ class="(.+?)"/', $formWidthText, $res)) {
-                                       $formWidthText = str_replace(' class="' . $res[1] . '"', '', $formWidthText);
-                                       $classes = array_merge($classes, explode(' ', $res[1]));
-                               }
-
-                               if (!empty($classes)) {
-                                       $class = ' class="tceforms-textarea t3js-formengine-textarea ' . implode(' ', $classes) . '"';
-                               } else {
-                                       $class = ' class="tceforms-textarea t3js-formengine-textarea"';
-                               }
-
+                               // validation
                                foreach ($evalList as $func) {
                                        if ($func === 'required') {
                                                $this->formEngine->registerRequiredProperty('field', $table . '_' . $row['uid'] . '_' . $field, $additionalInformation['itemFormElName']);
@@ -193,16 +162,56 @@ class TextElement extends AbstractFormElement {
                                                }
                                        }
                                }
-                               $textOnChange = implode('', $additionalInformation['fieldChangeFunc']);
-                               $additionalAttributes = '';
+
+                               // calculate classes
+                               $classes = array();
+                               //$classes[] = 'tceforms-textarea';
+                               $classes[] = 'form-control';
+                               $classes[] = 't3js-formengine-textarea';
+                               if ($specialConfiguration['fixed-font']) {
+                                       $classes[] = 'text-monospace';
+                               }
+                               if ($specialConfiguration['enable-tab']) {
+                                       $classes[] = 'enable-tab';
+                               }
+
+                               // calculate inline styles
+                               $styles = array();
+                               // add the max-height from the users' preference to it
+                               $maximumHeight = (int)$this->getBackendUserAuthentication()->uc['resizeTextareas_MaxHeight'];
+                               if ($maximumHeight > 0) {
+                                       $styles[] = 'max-height: ' . $maximumHeight . 'px';
+                               }
+
+                               // calculate attributes
+                               $attributes = array();
+                               $attributes['id'] = str_replace('.', '', uniqid('formengine-textarea-', TRUE));
+                               $attributes['name'] = $additionalInformation['itemFormElName'];
+                               if (!empty($styles)) {
+                                       $attributes['style'] = implode(' ', $styles);
+                               }
+                               if (!empty($classes)) {
+                                       $attributes['class'] = implode(' ', $classes);
+                               }
+                               $attributes['rows'] = $rows;
+                               $attributes['wrap'] = $specialConfiguration['nowrap'] ? 'off' : ($config['wrap'] ?: 'virtual');
+                               $attributes['onChange'] = htmlspecialchars(implode('', $additionalInformation['fieldChangeFunc']));
                                if (isset($config['max']) && (int)$config['max'] > 0) {
-                                       $additionalAttributes = ' maxlength="' . (int)$config['max'] . '"';
+                                       $attributes['maxlength'] = (int)$config['max'];
+                               }
+                               $attributeString = '';
+                               foreach ($attributes as $attributeName => $attributeValue) {
+                                       $attributeString .= ' '. $attributeName . '="' . $attributeValue . '"';
                                }
-                               $item .= '
-                                                       <textarea ' . 'id="' . str_replace('.', '', uniqid('tceforms-textarea-', TRUE)) . '" ' . 'name="' . $additionalInformation['itemFormElName']
-                                       . '"' . $formWidthText . $class . ' ' . 'rows="' . $rows . '" ' . 'wrap="' . $wrap . '" ' . 'onchange="'
-                                       . htmlspecialchars($textOnChange) . '"' . $this->formEngine->getPlaceholderAttribute($table, $field, $config, $row)
-                                       . $additionalInformation['onFocus'] . $additionalAttributes . '>' . GeneralUtility::formatForTextarea($additionalInformation['itemFormElValue']) . '</textarea>';
+
+                               // Build the textarea
+                               $item .= '<textarea'
+                                                       . $attributeString
+                                                       . $this->formEngine->getPlaceholderAttribute($table, $field, $config, $row)
+                                                       . $additionalInformation['onFocus']
+                                                       . '>' . GeneralUtility::formatForTextarea($additionalInformation['itemFormElValue']) . '</textarea>';
+
+                               // Wrap a wizard around the item?
                                $item = $this->formEngine->renderWizards(
                                        array($item, $altItem),
                                        $config['wizards'],
@@ -214,27 +223,12 @@ class TextElement extends AbstractFormElement {
                                        $specialConfiguration,
                                        $rteWouldHaveBeenLoaded
                                );
+
+                               $maximumWidth = (int)$this->formEngine->formMaxWidth($cols);
+                               $item = '<div class="form-control-wrap"' . ($maximumWidth ? ' style="max-width: ' . $maximumWidth . 'px"' : '') . '>' . $item . '</div>';
                        }
                }
                return $item;
        }
 
-       /**
-        * Returns parameters to set with for a textarea field
-        *
-        * @param int $size The abstract width (1-48)
-        * @param string $wrap Empty or "off" (text wrapping in the field or not)
-        * @return string The "cols" attribute string (or style from formWidth())
-        * @see formWidth()
-        */
-       protected function formWidthText($size = 48, $wrap = '') {
-               $wTags = $this->formEngine->formWidth($size, TRUE);
-               // Netscape 6+ seems to have this ODD problem where there WILL ALWAYS be wrapping
-               // with the cols-attribute set and NEVER without the col-attribute...
-               if (strtolower(trim($wrap)) != 'off' && $GLOBALS['CLIENT']['BROWSER'] == 'net' && $GLOBALS['CLIENT']['VERSION'] >= 5) {
-                       $wTags .= ' cols="' . $size . '"';
-               }
-               return $wTags;
-       }
-
 }
index 32d3202..8b4d14b 100644 (file)
@@ -41,11 +41,6 @@ use TYPO3\CMS\Lang\LanguageService;
 class FormEngine {
 
        /**
-        * @var string A CSS class name prefix for all element types, single elements add their type to this string
-        */
-       protected $cssClassTypeElementPrefix = 't3-formengine-field-';
-
-       /**
         * @var array
         */
        public $palFieldArr = array();
@@ -237,12 +232,12 @@ class FormEngine {
        protected $renderReadonly = FALSE;
 
        /**
-        * Form field width compensation: Factor of "size=12" to "style="width: 12*9.58px"
+        * Form field width compensation: Factor of "size=12" to "style="width: 12*12px"
         * for form field widths of style-aware browsers
         *
         * @var float
         */
-       public $form_rowsToStylewidth = 9.58;
+       public $form_rowsToStylewidth = 12;
 
        /**
         * Value that gets added for style="width: ...px" for textareas compared to input fields.
@@ -270,22 +265,40 @@ class FormEngine {
         * The maximum abstract value for textareas
         *
         * @var int
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
         */
        public $maxTextareaWidth = 48;
 
        /**
-        * The maximum abstract value for input fields
+        * The default abstract value for input and textarea elements
         *
         * @var int
+        * @internal
         */
-       public $maxInputWidth = 48;
+       public $defaultInputWidth = 30;
+
+       /**
+        * The minimum abstract value for input and textarea elements
+        *
+        * @var int
+        * @internal
+        */
+       public $minimumInputWidth = 10;
+
+       /**
+        * The maximum abstract value for input and textarea elements
+        *
+        * @var int
+        * @internal
+        */
+       public $maxInputWidth = 50;
 
        /**
         * Default style for the selector boxes used for multiple items in "select" and "group" types.
         *
         * @var string
         */
-       public $defaultMultipleSelectorStyle = 'width:310px;';
+       public $defaultMultipleSelectorStyle = '';
 
        // INTERNAL, static
        /**
@@ -967,10 +980,6 @@ class FormEngine {
                $parts = array();
                foreach ($out_array as $idx => $sheetContent) {
                        $content = implode('', $sheetContent);
-                       if ($content) {
-                               // Wrap content (row) with table-tag, otherwise tab/sheet will be disabled (see getdynTabMenu() )
-                               $content = '<table border="0" cellspacing="0" cellpadding="0" width="100%">' . $content . '</table>';
-                       }
                        $parts[$idx] = array(
                                'label' => $out_array_meta[$idx]['title'],
                                'content' => $content,
@@ -987,14 +996,9 @@ class FormEngine {
                }
                // Only one tab, so just implode and wrap the background image (= tab container) around:
                if ($out_sheet === 0) {
-                       $output = '<div class="typo3-dyntabmenu-divs">' . $output . '</div>';
+                       $output = '<div class="tab-content">' . $output . '</div>';
                }
-               $output = '
-                       <tr>
-                               <td colspan="2">
-                               ' . $output . '
-                               </td>
-                       </tr>';
+               $output = $output;
 
                return $output;
        }
@@ -1056,31 +1060,29 @@ class FormEngine {
                        foreach ($parts as $part) {
                                if ($part['NAME'] !== '--linebreak--') {
                                        $realFields++;
+                                       break;
                                }
                        }
                        if ($realFields > 0) {
-                               if ($header) {
-                                       $out .= $this->intoTemplate(array('HEADER' => htmlspecialchars($header)), $this->palFieldTemplateHeader);
-                               }
+
+                               $code = $this->printPalette($parts);
                                $collapsed = $this->isPalettesCollapsed($table, $palette);
-                               // Check if the palette is a hidden palette
                                $isHiddenPalette = !empty($GLOBALS['TCA'][$table]['palettes'][$palette]['isHiddenPalette']);
-                               $thePalIcon = '';
+
+
                                if ($collapsed && $collapsedHeader !== NULL && !$isHiddenPalette) {
-                                       list($thePalIcon, ) = $this->wrapOpenPalette(
-                                               IconUtility::getSpriteIcon(
-                                                       'actions-system-options-view',
-                                                       array('title' => htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.moreOptions')))
-                                               ),
-                                               $table,
-                                               $row,
-                                               $palette,
-                                               1
-                                       );
-                                       $thePalIcon = '<span style="margin-left: 20px;">' . $thePalIcon . $collapsedHeader . '</span>';
+                                       $code = $this->wrapCollapsiblePalette($code, 'FORMENGINE_' . $table . '_' . $palette . '_' . $row['uid'], $collapsed);
+                               } else {
+                                       $code = '<div class="row">' . $code . '</div>';
                                }
-                               $paletteHtml = $this->wrapPaletteField($this->printPalette($parts), $table, $row, $palette, $collapsed);
-                               $out .= $this->intoTemplate(array('PALETTE' => $thePalIcon . $paletteHtml), $this->palFieldTemplate);
+
+                               $out = '
+                                       <!-- getPaletteFields -->
+                                       <fieldset class="form-section">
+                                               ' . ($header ? '<h4 class="form-section-headline">' . htmlspecialchars($header) . '</h4>' : '') . '
+                                               ' . ($collapsedHeader ? '<h4 class="form-section-headline">' . htmlspecialchars($collapsedHeader) . '</h4>' : '') . '
+                                               ' . $code . '
+                                       </fieldset>';
                        }
                }
                return $out;
@@ -1183,24 +1185,6 @@ class FormEngine {
                                } else {
                                        $languageService = $this->getLanguageService();
                                        // Render as a normal field:
-                                       // If the field is NOT a palette field, then we might create an icon which links to a palette for the field, if one exists.
-                                       $palJSfunc = '';
-                                       $thePalIcon = '';
-                                       if (!$PA['palette']) {
-                                               $paletteFields = $this->loadPaletteElements($table, $row, $PA['pal']);
-                                               if ($PA['pal'] && $this->isPalettesCollapsed($table, $PA['pal']) && count($paletteFields)) {
-                                                       list($thePalIcon, $palJSfunc) = $this->wrapOpenPalette(
-                                                               IconUtility::getSpriteIcon(
-                                                                       'actions-system-options-view',
-                                                                       array('title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.moreOptions')))
-                                                               ),
-                                                               $table,
-                                                               $row,
-                                                               $PA['pal'],
-                                                               1
-                                                       );
-                                               }
-                                       }
                                        // onFocus attribute to add to the field:
                                        $PA['onFocus'] = $palJSfunc && !$this->getBackendUserAuthentication()->uc['dontShowPalettesOnFocusInAB'] ? ' onfocus="' . htmlspecialchars($palJSfunc) . '"' : '';
                                        $PA['label'] = $PA['altName'] ?: $PA['fieldConf']['label'];
@@ -1247,19 +1231,18 @@ class FormEngine {
                                                $this->additionalJS_post[] = 'typo3form.fieldTogglePlaceholder('
                                                        . GeneralUtility::quoteJSvalue($PA['itemFormElName']) . ', ' . ($checked ? 'false' : 'true') . ');';
 
-                                               $item = '<div class="t3-form-field-placeholder-override">'
-                                               . '<span class="t3-tceforms-placeholder-override-checkbox">' .
-                                                       '<input type="hidden" name="' . htmlspecialchars($PA['itemFormElNameActive']) . '" value="0" />' .
-                                                       '<input type="checkbox" name="' . htmlspecialchars($PA['itemFormElNameActive']) . '" value="1" id="tce-forms-textfield-use-override-' . $field . '-' . $row['uid'] . '" onchange="' . htmlspecialchars($onChange) . '"' . $checked . ' />' .
-                                                       '<label for="tce-forms-textfield-use-override-' . $field . '-' . $row['uid'] . '">' .
-                                                       sprintf($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.placeholder.override'),
-                                                       BackendUtility::getRecordTitlePrep($placeholder, 20)) . '</label>' .
-                                               '</span>'
-                                               . '<div class="t3-form-placeholder-placeholder">' . $this->getSingleField_typeNone_render(
-                                                       $PA['fieldConf']['config'], GeneralUtility::fixed_lgd_cs($placeholder, 30)
-                                               ) . '</div>'
-                                               . '<div class="t3-form-placeholder-formfield">' . $item . '</div>'
-                                               . '</div>';
+                                               $item = '
+                                                       <input type="hidden" name="' . htmlspecialchars($PA['itemFormElNameActive']) . '" value="0" />
+                                                       <div class="checkbox">
+                                                               <label>
+                                                                       <input type="checkbox" name="' . htmlspecialchars($PA['itemFormElNameActive']) . '" value="1" id="tce-forms-textfield-use-override-' . $field . '-' . $row['uid'] . '" onchange="' . htmlspecialchars($onChange) . '"' . $checked . ' />
+                                                                       ' . sprintf($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.placeholder.override'), BackendUtility::getRecordTitlePrep($placeholder, 20)) . '
+                                                               </label>
+                                                       </div>
+                                                       <div class="t3js-formengine-placeholder-placeholder">
+                                                               ' . $this->getSingleField_typeNone_render($PA['fieldConf']['config'], GeneralUtility::fixed_lgd_cs($placeholder, 30)) . '
+                                                       </div>
+                                                       <div class="t3js-formengine-placeholder-formfield">' . $item . '</div>';
                                        }
 
                                        // Wrap the label with help text
@@ -1278,22 +1261,23 @@ class FormEngine {
                                                        'ITEM_DISABLED' => ($this->isDisabledNullValueField($table, $field, $row, $PA) ? ' disabled' : ''),
                                                        'ITEM_NULLVALUE' => $this->renderNullValueWidget($table, $field, $row, $PA),
                                                );
-                                               $out = $this->addUserTemplateMarkers($out, $table, $field, $row, $PA);
                                        } else {
-                                               // String:
-                                               $out = array(
-                                                       'NAME' => $label,
-                                                       'ITEM' => $item,
-                                                       'TABLE' => $table,
-                                                       'ID' => $row['uid'],
-                                                       'PAL_LINK_ICON' => $thePalIcon,
-                                                       'FIELD' => $field,
-                                                       'ITEM_DISABLED' => ($this->isDisabledNullValueField($table, $field, $row, $PA) ? ' disabled' : ''),
-                                                       'ITEM_NULLVALUE' => $this->renderNullValueWidget($table, $field, $row, $PA),
-                                               );
-                                               $out = $this->addUserTemplateMarkers($out, $table, $field, $row, $PA);
-                                               // String:
-                                               $out = $this->intoTemplate($out);
+                                               $out = '
+                                                       <fieldset class="form-section">
+                                                               <!-- getSingleField -->
+                                                               <div class="form-group t3js-formengine-palette-field">
+                                                                       <label class="t3js-formengine-label">
+                                                                               ' . $label . '
+                                                                               <img name="req_' . $table . '_' . $row['uid'] . '_' . $field . '" src="clear.gif" class="t3js-formengine-field-required" alt="" />
+                                                                       </label>
+                                                                       <div class="t3js-formengine-field-item ' . ($this->isDisabledNullValueField($table, $field, $row, $PA) ? ' disabled' : '') . '">
+                                                                               <div class="t3-form-field-disable"></div>
+                                                                               ' . $this->renderNullValueWidget($table, $field, $row, $PA) . '
+                                                                               ' . $item . '
+                                                                       </div>
+                                                               </div>
+                                                       </fieldset>
+                                               ';
                                        }
                                }
                        } else {
@@ -1403,10 +1387,13 @@ class FormEngine {
                                'typo3form.fieldSetNull(\'' . $PA['itemFormElName'] . '\', !this.checked)'
                        );
 
-                       $widget = '<span class="t3-tceforms-widget-null-wrapper">' .
-                               '<input type="hidden" name="' . $PA['itemFormElNameActive'] . '" value="0" />' .
-                               '<input type="checkbox" name="' . $PA['itemFormElNameActive'] . '" value="1" onchange="' . $onChange . '"' . $checked . ' />' .
-                       '</span>';
+                       $widget = '
+                               <div class="checkbox">
+                                       <label>
+                                               <input type="hidden" name="' . $PA['itemFormElNameActive'] . '" value="0" />
+                                               <input type="checkbox" name="' . $PA['itemFormElNameActive'] . '" value="1" onchange="' . $onChange . '"' . $checked . ' /> &nbsp;
+                                       </label>
+                               </div>';
                }
 
                return $widget;
@@ -1563,20 +1550,25 @@ class FormEngine {
 
                $rows = (int)$config['rows'];
                // Render as textarea
-               if ($rows > 1) {
+               if ($rows > 1 || $config['type'] === 'text') {
                        if (!$config['pass_content']) {
                                $itemValue = nl2br($itemValue);
                        }
-                       $cols = round($config['cols'] * $this->form_largeComp);
-                       $width = ceil($cols * $this->form_rowsToStylewidth);
-                       $item = '<textarea class="form-control" style="width:' . $width . 'px;" cols="' . $cols . '" rows="' . $rows . '" disabled>' . $itemValue . '</textarea>';
+                       $cols = MathUtility::forceIntegerInRange($config['cols'] ?: $this->defaultInputWidth, 5, $this->maxInputWidth);
+                       $width = $this->formMaxWidth($cols);
+                       $item = '
+                               <div class="form-control-wrap"' . ($width ? ' style="max-width: ' . $width . 'px"' : '') . '>
+                                       <textarea class="form-control" rows="' . $rows . '" disabled>' . $itemValue . '</textarea>
+                               </div>';
                } else {
-                       $cols = $config['cols'] ?: ($config['size'] ?: $this->maxInputWidth);
-                       $cols = round($cols * $this->form_largeComp);
-                       $width = ceil($cols * $this->form_rowsToStylewidth);
+                       $cols = $config['cols'] ?: ($config['size'] ?: $this->defaultInputWidth);
+                       $size = MathUtility::forceIntegerInRange($cols ?: $this->defaultInputWidth, 5, $this->maxInputWidth);
+                       $width = $this->formMaxWidth($size);
                        $item = '
-                               <input class="form-control" value="'. $itemValue .'" style="width:' . $width . 'px;" type="text" disabled>'
-                               . '<span class="nobr">' . ((string)$itemValue !== '' ? $itemValue : '&nbsp;') . '</span>';
+                               <div class="form-control-wrap"' . ($width ? ' style="max-width: ' . $width . 'px"' : '') . '>
+                                       <input class="form-control" value="'. $itemValue .'" type="text" disabled>
+                               </div>
+                               ' . ((string)$itemValue !== '' ? '<p class="help-block">' . $itemValue . '</p>' : '');
                }
                return $item;
        }
@@ -2373,7 +2365,7 @@ class FormEngine {
                if (!$selector) {
                        $isMultiple = $params['maxitems'] != 1 && $params['size'] != 1;
                        $selector = '<select id="' . str_replace('.', '', uniqid('tceforms-multiselect-', TRUE)) . '" '
-                               . ($params['noList'] ? 'style="display: none"' : 'size="' . $sSize . '" class="' . $this->cssClassTypeElementPrefix . 'group tceforms-multiselect"')
+                               . ($params['noList'] ? 'style="display: none"' : 'size="' . $sSize . '" class="form-control tceforms-multiselect"')
                                . ($isMultiple ? ' multiple="multiple"' : '')
                                . ' name="' . $fName . '_list" ' . $onFocus . $params['style'] . $disabled . '>' . implode('', $opt)
                                . '</select>';
@@ -2407,35 +2399,47 @@ class FormEngine {
                                }
                                $aOnClick = 'setFormValueOpenBrowser(\'' . $elementBrowserType . '\',\''
                                        . ($fName . '|||' . $elementBrowserAllowed . '|' . $aOnClickInline) . '\'); return false;';
-                               $spriteIcon = IconUtility::getSpriteIcon('actions-insert-record', array(
-                                       'title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.browse_' . ($mode == 'db' ? 'db' : 'file')))
-                               ));
-                               $icons['R'][] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '" class="btn btn-default">' . $spriteIcon . '</a>';
+                               $icons['R'][] = '
+                                       <a href="#"
+                                               onclick="' . htmlspecialchars($aOnClick) . '"
+                                               class="btn btn-default"
+                                               title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.browse_' . ($mode == 'db' ? 'db' : 'file'))) . '">
+                                               ' . IconUtility::getSpriteIcon('actions-insert-record') . '
+                                       </a>';
                        }
                        if (!$params['dontShowMoveIcons']) {
                                if ($sSize >= 5) {
-                                       $icons['L'][] = IconUtility::getSpriteIcon('actions-move-to-top', array(
-                                               'data-fieldname' => $fName,
-                                               'class' => 't3-btn t3-btn-moveoption-top',
-                                               'title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_to_top'))
-                                       ));
+                                       $icons['L'][] = '
+                                               <a href="#"
+                                                       class="btn btn-default t3-btn-moveoption-top"
+                                                       data-fieldname="' . $fName . '"
+                                                       title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_to_top')) . '">
+                                                       ' . IconUtility::getSpriteIcon('actions-move-to-top') . '
+                                               </a>';
+
                                }
-                               $icons['L'][] = IconUtility::getSpriteIcon('actions-move-up', array(
-                                       'data-fieldname' => $fName,
-                                       'class' => 't3-btn t3-btn-moveoption-up',
-                                       'title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_up'))
-                               ));
-                               $icons['L'][] = IconUtility::getSpriteIcon('actions-move-down', array(
-                                       'data-fieldname' => $fName,
-                                       'class' => 't3-btn t3-btn-moveoption-down',
-                                       'title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_down'))
-                               ));
+                               $icons['L'][] = '
+                                       <a href="#"
+                                               class="btn btn-default t3-btn-moveoption-up"
+                                               data-fieldname="' . $fName . '"
+                                               title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_up')) . '">
+                                               ' . IconUtility::getSpriteIcon('actions-move-up') . '
+                                       </a>';
+                               $icons['L'][] = '
+                                       <a href="#"
+                                               class="btn btn-default t3-btn-moveoption-down"
+                                               data-fieldname="' . $fName . '"
+                                               title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_down')) . '">
+                                               ' . IconUtility::getSpriteIcon('actions-move-down') . '
+                                       </a>';
                                if ($sSize >= 5) {
-                                       $icons['L'][] = IconUtility::getSpriteIcon('actions-move-to-bottom', array(
-                                               'data-fieldname' => $fName,
-                                               'class' => 't3-btn t3-btn-moveoption-bottom',
-                                               'title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_to_bottom'))
-                                       ));
+                                       $icons['L'][] = '
+                                               <a href="#"
+                                                       class="btn btn-default t3-btn-moveoption-bottom"
+                                                       data-fieldname="' . $fName . '"
+                                                       title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.move_to_bottom')) . '">
+                                                       ' . IconUtility::getSpriteIcon('actions-move-to-bottom') . '
+                                               </a>';
                                }
                        }
                        $clipElements = $this->getClipboardElements($allowed, $mode);
@@ -2455,26 +2459,33 @@ class FormEngine {
                                                . rawurlencode(str_replace('%20', ' ', $elValue)) . '\'),' . $itemTitle . ',' . $itemTitle . ');';
                                }
                                $aOnClick .= 'return false;';
-                               $spriteIcon1 = IconUtility::getSpriteIcon('actions-document-paste-into', array(
-                                       'title' => htmlspecialchars(sprintf($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.clipInsert_' . ($mode == 'db' ? 'db' : 'file')), count($clipElements)))
-                               ));
-                               $icons['R'][] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $spriteIcon1 . '</a>';
+                               $icons['R'][] = '
+                                       <a href="#"
+                                               onclick="' . htmlspecialchars($aOnClick) . '"
+                                               title="' . htmlspecialchars(sprintf($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.clipInsert_' . ($mode == 'db' ? 'db' : 'file')), count($clipElements))) . '">
+                                               ' . IconUtility::getSpriteIcon('actions-document-paste-into') . '
+                                       </a>';
                        }
                }
                if (!$params['readOnly'] && !$params['noDelete']) {
-                       $icons['L'][] = IconUtility::getSpriteIcon('actions-selection-delete', array(
-                               'onclick' => $rOnClickInline,
-                               'data-fieldname' => $fName,
-                               'class' => 't3-btn t3-btn-removeoption',
-                               'title' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.remove_selected'))
+                       $icons['L'][] = '
+                               <a href="#"
+                                       class="btn btn-default t3-btn-removeoption"
+                                       onClick="' . $rOnClickInline . '"
+                                       data-fieldname="' . $fName . '"
+                                       title="' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.remove_selected')) . '">
+                                       ' . IconUtility::getSpriteIcon('actions-selection-delete') . '
+                               </a>';
 
-                       ));
                }
+
+
+               // Thumbnails
                $imagesOnly = FALSE;
-               if ($params['thumbnails'] && $params['info']) {
+               if ($params['thumbnails'] && $params['allowed']) {
                        // In case we have thumbnails, check if only images are allowed.
                        // In this case, render them below the field, instead of to the right
-                       $allowedExtensionList = GeneralUtility::trimExplode(' ', strtolower($params['info']), TRUE);
+                       $allowedExtensionList = $params['allowed'];
                        $imageExtensionList = GeneralUtility::trimExplode(',', strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']), TRUE);
                        $imagesOnly = TRUE;
                        foreach ($allowedExtensionList as $allowedExtension) {
@@ -2484,13 +2495,63 @@ class FormEngine {
                                }
                        }
                }
-               if ($imagesOnly) {
-                       $rightbox = '';
-                       $thumbnails = '<div class="imagethumbs">' . $params['thumbnails'] . '</div>';
-               } else {
-                       $rightbox = $params['thumbnails'];
-                       $thumbnails = '';
+               $thumbnails = '';
+               if (is_array($params['thumbnails']) && !empty($params['thumbnails'])) {
+                       if ($imagesOnly) {
+                               $thumbnails .= '<ul class="list-inline">';
+                               foreach ($params['thumbnails'] as $thumbnail) {
+                                       $thumbnails .= '<li><span class="thumbnail">' . $thumbnail['image'] . '</span></li>';
+                               }
+                               $thumbnails .= '</ul>';
+                       } else {
+                               $thumbnails .= '<div class="table-fit"><table class="table table-white"><tbody>';
+                               foreach ($params['thumbnails'] as $thumbnail) {
+                                       $thumbnails .= '
+                                               <tr>
+                                                       <td class="col-icon">
+                                                               ' . ($config['internal_type'] === 'db'
+                                                                       ? $this->getClickMenu($thumbnail['image'], $thumbnail['table'], $thumbnail['uid'])
+                                                                       : $thumbnail['image']) . '
+                                                       </td>
+                                                       <td class="col-title">
+                                                               ' . ($config['internal_type'] === 'db'
+                                                                       ? $this->getClickMenu($thumbnail['name'], $thumbnail['table'], $thumbnail['uid'])
+                                                                       : $thumbnail['name']) . '
+                                                               ' . ($config['internal_type'] === 'db' ? '' : ' <span class="text-muted">[' . $thumbnail['uid'] . ']</span>') . '
+                                                       </td>
+                                               </tr>
+                                               ';
+                               }
+                               $thumbnails .= '</tbody></table></div>';
+                       }
+               }
+
+               // Allowed Tables
+               $allowedTables = '';
+               if (is_array($params['allowedTables']) && !empty($params['allowedTables'])) {
+                       $allowedTables .= '<div class="help-block">';
+                       foreach ($params['allowedTables'] as $item) {
+                               $allowedTables .= '<a href="#" onClick="' . htmlspecialchars($item['onClick']) . '" class="btn btn-default">' . $item['icon'] . ' ' . $item['name'] . '</a> ';
+                       }
+                       $allowedTables .= '</div>';
+               }
+               // Allowed
+               $allowedList = '';
+               if (is_array($params['allowed']) && !empty($params['allowed'])) {
+                       foreach ($params['allowed'] as $item) {
+                               $allowedList .= '<span class="label label-success">' . strtoupper($item) . '</span> ';
+                       }
+               }
+               // Disallowed
+               $disallowedList = '';
+               if (is_array($params['disallowed']) && !empty($params['disallowed'])) {
+                       foreach ($params['disallowed'] as $item) {
+                               $disallowedList .= '<span class="label label-danger">' . strtoupper($item) . '</span> ';
+                       }
                }
+               // Rightbox
+               $rightbox = ($params['rightbox'] ?: '');
+
                // Hook: dbFileIcons_postProcess (requested by FAL-team for use with the "fal" extension)
                if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['dbFileIcons'])) {
                        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['dbFileIcons'] as $classRef) {
@@ -2511,25 +2572,36 @@ class FormEngine {
                                $hookObject->dbFileIcons_postProcess($params, $selector, $thumbnails, $icons, $rightbox, $fName, $uidList, $additionalParams, $this);
                        }
                }
-               $str = '<table border="0" cellpadding="0" cellspacing="0" width="1" class="t3-form-field-group-file">
-                       ' . ($params['headers'] ? '
-                               <tr>
-                                       <td>' . $params['headers']['selector'] . '</td>
-                                       <td></td>
-                                       <td></td>
-                                       <td>' . ($params['thumbnails'] ? $params['headers']['items'] : '') . '</td>
-                               </tr>' : '') . '
-                       <tr>
-                               <td>' . $selector . $thumbnails;
-               if (!$params['noList'] && $params['info'] !== '') {
-                       $str .= '<span class="filetypes">' . $params['info'] . '</span>';
-               }
-               $str .= '</td>
-                                       <td class="icons">' . implode('<br />', $icons['L']) . '</td>
-                                       <td class="icons">' . implode('<br />', $icons['R']) . '</td>
-                                       <td>' . $rightbox . '</td>
-                       </tr>
-               </table>';
+
+               // Output
+               $str = '
+                       ' . ($params['headers']['selector'] ? '<label>' . $params['headers']['selector'] . '</label>' : '') . '
+                       <div class="form-wizards-wrap form-wizards-aside">
+                               <div class="form-wizards-element">
+                                       ' . $selector . '
+                                       ' . (!$params['noList'] && !empty($allowedTables) ? $allowedTables : '') . '
+                                       ' . (!$params['noList'] && (!empty($allowedList) || !empty($disallowedList))
+                                               ? '<div class="help-block">' . $allowedList . $disallowedList . ' </div>'
+                                               : '') . '
+                               </div>
+                               ' . (!empty($icons['L']) ? '<div class="form-wizards-items"><div class="btn-group-vertical">' . implode('', $icons['L']) . '</div></div>' : '' ) . '
+                               ' . (!empty($icons['R']) ? '<div class="form-wizards-items"><div class="btn-group-vertical">' . implode('', $icons['R']) . '</div></div>' : '' ) . '
+                       </div>
+                       ';
+               if ($rightbox) {
+                       $str = '
+                               <div class="form-multigroup-wrap t3js-formengine-field-group">
+                                       <div class="form-multigroup-item form-multigroup-element">' . $str . '</div>
+                                       <div class="form-multigroup-item form-multigroup-element">
+                                               ' . ($params['headers']['items'] ? '<label>' . $params['headers']['items'] . '</label>' : '') . '
+                                               ' . ($params['headers']['selectorbox'] ? '<div class="form-multigroup-item-wizard">' . $params['headers']['selectorbox'] . '</div>' : '') . '
+                                               ' . $rightbox . '
+                                       </div>
+                               </div>
+                               ';
+               }
+               $str .= $thumbnails;
+
                // Creating the hidden field which contains the actual value as a comma list.
                $str .= '<input type="hidden" name="' . $fName . '" value="' . htmlspecialchars(implode(',', $uidList)) . '" />';
                return $str;
@@ -2620,7 +2692,10 @@ class FormEngine {
                // Init:
                $fieldChangeFunc = $PA['fieldChangeFunc'];
                $item = $itemKinds[0];
-               $outArr = array();
+               $outArr = array(
+                       'buttons' => '',
+                       'additional' => ''
+               );
                $colorBoxLinks = array();
                $fName = '[' . $table . '][' . $row['uid'] . '][' . $field . ']';
                $md5ID = 'ID' . GeneralUtility::shortmd5($itemName);
@@ -2700,7 +2775,7 @@ class FormEngine {
                                                                // If "script" type, create the links around the icon:
                                                                if ((string)$wConf['type'] === 'script') {
                                                                        $aUrl = $url . GeneralUtility::implodeArrayForUrl('', array('P' => $params));
-                                                                       $outArr[] = '<a href="' . htmlspecialchars($aUrl) . '" onclick="this.blur(); return !TBE_EDITOR.isFormChanged();">' . $icon . '</a>';
+                                                                       $outArr['buttons'][] = ' <a class="btn btn-default" href="' . htmlspecialchars($aUrl) . '" onclick="this.blur(); return !TBE_EDITOR.isFormChanged();">' . $icon . '</a>';
                                                                } else {
                                                                        // ... else types "popup", "colorbox" and "userFunc" will need additional parameters:
                                                                        $params['formName'] = $this->formName;
@@ -2725,9 +2800,9 @@ class FormEngine {
                                                                                                . ',\'popUp' . $md5ID . '\',\'' . $wConf['JSopenParams'] . '\');'
                                                                                                . 'vHWin.focus();return false;';
                                                                                        // Setting "colorBoxLinks" - user LATER to wrap around the color box as well:
-                                                                                       $colorBoxLinks = array('<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">', '</a>');
+                                                                                       $colorBoxLinks = array('<a class="btn btn-default" href="#" onclick="' . htmlspecialchars($aOnClick) . '">', '</a>');
                                                                                        if ((string)$wConf['type'] == 'popup') {
-                                                                                               $outArr[] = $colorBoxLinks[0] . $icon . $colorBoxLinks[1];
+                                                                                               $outArr['buttons'][] = $colorBoxLinks[0] . $icon . $colorBoxLinks[1];
                                                                                        }
                                                                                        break;
                                                                                case 'userFunc':
@@ -2737,9 +2812,12 @@ class FormEngine {
                                                                                        $params['iTitle'] = $iTitle;
                                                                                        $params['wConf'] = $wConf;
                                                                                        $params['row'] = $row;
-                                                                                       $outArr[] = GeneralUtility::callUserFunction($wConf['userFunc'], $params, $this);
+                                                                                       $outArr['additional'][] = GeneralUtility::callUserFunction($wConf['userFunc'], $params, $this);
                                                                                        break;
                                                                                case 'slider':
+                                                                                       // Prevent vertical alignment
+                                                                                       $verticalAlignmentIsPossible = FALSE;
+
                                                                                        // Reference set!
                                                                                        $params['item'] = &$item;
                                                                                        $params['icon'] = $icon;
@@ -2747,7 +2825,7 @@ class FormEngine {
                                                                                        $params['wConf'] = $wConf;
                                                                                        $params['row'] = $row;
                                                                                        $wizard = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Form\Element\ValueSlider::class);
-                                                                                       $outArr[] = call_user_func_array(array(&$wizard, 'renderWizard'), array(&$params, &$this));
+                                                                                       $outArr['additional'][] = call_user_func_array(array(&$wizard, 'renderWizard'), array(&$params, &$this));
                                                                                        break;
                                                                        }
                                                                }
@@ -2784,15 +2862,15 @@ class FormEngine {
                                                                $assignValue = $this->elName($itemName) . '.value=this.options[this.selectedIndex].value';
                                                        }
                                                        $sOnChange = $assignValue . ';this.blur();this.selectedIndex=0;' . implode('', $fieldChangeFunc);
-                                                       $outArr[] = '<select id="' . str_replace('.', '', uniqid('tceforms-select-', TRUE))
-                                                               . '" class="tceforms-select tceforms-wizardselect" name="_WIZARD' . $fName . '" onchange="'
+                                                       $outArr['additional'][] = '<select id="' . str_replace('.', '', uniqid('tceforms-select-', TRUE))
+                                                               . '" class="form-control tceforms-select tceforms-wizardselect" name="_WIZARD' . $fName . '" onchange="'
                                                                . htmlspecialchars($sOnChange) . '">' . implode('', $opt) . '</select>';
                                                        break;
                                                case 'suggest':
                                                        if (!empty($PA['fieldTSConfig']['suggest.']['default.']['hide'])) {
                                                                break;
                                                        }
-                                                       $outArr[] = $this->suggest->renderSuggestSelector($PA['itemFormElName'], $table, $field, $row, $PA);
+                                                       $outArr['additional'][] = $this->suggest->renderSuggestSelector($PA['itemFormElName'], $table, $field, $row, $PA);
                                                        break;
                                        }
                                        // Color wizard colorbox:
@@ -2806,7 +2884,7 @@ class FormEngine {
                                                        $color === '' ? 'gfx/colorpicker_empty.png' : 'gfx/colorpicker.png',
                                                        'width="' . $dX . '" height="' . $dY . '"' . BackendUtility::titleAltAttrib(trim($iTitle . ' ' . $PA['itemFormElValue'])) . ' border="0"'
                                                );
-                                               $outArr[] = '<table border="0" cellpadding="0" cellspacing="0" id="' . $md5ID . '"' . $color
+                                               $outArr['additional'][] = '<table border="0" cellpadding="0" cellspacing="0" id="' . $md5ID . '"' . $color
                                                        . ' style="' . htmlspecialchars($wConf['tableStyle']) . '">
                                                                        <tr>
                                                                                <td>' . $colorBoxLinks[0] . '<img ' . $skinImg . '>' . $colorBoxLinks[1] . '</td>
@@ -2816,34 +2894,39 @@ class FormEngine {
                                }
                        }
                        // For each rendered wizard, put them together around the item.
-                       if (count($outArr)) {
+                       if (count($outArr['buttons']) || count($outArr['additional'])) {
                                if ($wizConf['_HIDDENFIELD']) {
                                        $item = $itemKinds[1];
                                }
-                               $vAlign = $wizConf['_VALIGN'] ? ' style="vertical-align:' . $wizConf['_VALIGN'] . '"' : '';
-                               if (count($outArr) > 1 || $wizConf['_PADDING']) {
-                                       $dist = (int)$wizConf['_DISTANCE'];
-                                       if ($wizConf['_VERTICAL']) {
-                                               $dist = $dist ? '<tr><td><img src="clear.gif" width="1" height="' . $dist . '" alt="" /></td></tr>' : '';
-                                               $outStr = '<tr><td>' . implode(('</td></tr>' . $dist . '<tr><td>'), $outArr) . '</td></tr>';
-                                       } else {
-                                               $dist = $dist ? '<td><img src="clear.gif" height="1" width="' . $dist . '" alt="" /></td>' : '';
-                                               $outStr = '<tr><td' . $vAlign . '>' . implode(('</td>' . $dist . '<td' . $vAlign . '>'), $outArr) . '</td></tr>';
-                                       }
-                                       $outStr = '<table border="0" cellpadding="' . (int)$wizConf['_PADDING'] . '" cellspacing="' . (int)$wizConf['_PADDING'] . '">' . $outStr . '</table>';
-                               } else {
-                                       $outStr = implode('', $outArr);
+
+                               $outStr = '';
+                               if (!empty($outArr['buttons'])) {
+                                       $outStr .= '<div class="btn-group' . ($wizConf['_VERTICAL'] ? ' btn-group-vertical' : '') . '">' . implode('', $outArr['buttons']) . '</div>';
                                }
+                               if (!empty($outArr['additional'])) {
+                                       $outStr .= implode(' ', $outArr['additional']);
+                               }
+
+                               // Position
+                               $class = array();
                                if ($wizConf['_POSITION'] === 'left') {
-                                       $outStr = '<tr><td' . $vAlign . '>' . $outStr . '</td><td' . $vAlign . '>' . $item . '</td></tr>';
+                                       $class[] = 'form-wizards-aside';
+                                       $outStr = '<div class="form-wizards-items">' . $outStr . '</div><div class="form-wizards-element">' . $item . '</div>';
                                } elseif ($wizConf['_POSITION'] === 'top') {
-                                       $outStr = '<tr><td>' . $outStr . '</td></tr><tr><td>' . $item . '</td></tr>';
+                                       $class[] = 'form-wizards-top';
+                                       $outStr = '<div class="form-wizards-items">' . $outStr . '</div><div class="form-wizards-element">' . $item . '</div>';
                                } elseif ($wizConf['_POSITION'] === 'bottom') {
-                                       $outStr = '<tr><td>' . $item . '</td></tr><tr><td>' . $outStr . '</td></tr>';
+                                       $class[] = 'form-wizards-bottom';
+                                       $outStr = '<div class="form-wizards-element">' . $item . '</div><div class="form-wizards-items">' . $outStr . '</div>';
                                } else {
-                                       $outStr = '<tr><td' . $vAlign . '>' . $item . '</td><td' . $vAlign . '>' . $outStr . '</td></tr>';
+                                       $class[] = 'form-wizards-aside';
+                                       $outStr = '<div class="form-wizards-element">' . $item . '</div><div class="form-wizards-items">' . $outStr . '</div>';
                                }
-                               $item = '<table border="0" cellpadding="0" cellspacing="0">' . $outStr . '</table>';
+                               $item = '
+                                       <!-- renderWizards -->
+                                       <div class="form-wizards-wrap ' . (!empty($class) ? implode(' ', $class) : '' ) . '">
+                                               ' . $outStr . '
+                                       </div>';
                        }
                }
                return $item;
@@ -2980,6 +3063,32 @@ class FormEngine {
        }
 
        /**
+        * Add the id and the style property to the field palette
+        *
+        * @param string $code Palette Code
+        * @param string $id Collapsible ID
+        * @param string $collapsed Collapsed status
+        * @return bool Is collapsed
+        */
+       public function wrapCollapsiblePalette($code, $id, $collapsed) {
+               $display = $collapsed ? '' : ' in';
+               $id = str_replace('.', '', $id);
+               $out = '
+                       <!-- wrapCollapsiblePalette -->
+                       <p>
+                               <button class="btn btn-default" type="button" data-toggle="collapse" data-target="#' . $id . '" aria-expanded="false" aria-controls="' . $id . '">
+                                       ' . IconUtility::getSpriteIcon('actions-system-options-view') . '
+                                       ' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.moreOptions')) . '
+                               </button>
+                       </p>
+                       <div id="' . $id . '" class="form-section-collapse collapse' . $display . '">
+                               <div class="row">' . $code . '</div>
+                       </div>';
+               return $out;
+       }
+
+
+       /**
         * Wraps a string with a link to the palette.
         *
         * @param string $header The string to wrap in an A-tag
@@ -2988,8 +3097,10 @@ class FormEngine {
         * @param int $palette The record array
         * @param mixed $retFunc Not used
         * @return array
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
         */
        public function wrapOpenPalette($header, $table, $row, $palette, $retFunc) {
+               GeneralUtility::logDeprecatedFunction();
                $id = 'TCEFORMS_' . $table . '_' . $palette . '_' . $row['uid'];
                $res = '<a href="#" onclick="TBE_EDITOR.toggle_display_states(\'' . $id . '\',\'block\',\'none\'); return false;" >' . $header . '</a>';
                return array($res, '');
@@ -3004,8 +3115,10 @@ class FormEngine {
         * @param string $palette The record array
         * @param bool $collapsed TRUE if collapsed
         * @return bool Is collapsed
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
         */
        public function wrapPaletteField($code, $table, $row, $palette, $collapsed) {
+               GeneralUtility::logDeprecatedFunction();
                $display = $collapsed ? 'none' : 'block';
                $id = 'TCEFORMS_' . $table . '_' . $palette . '_' . $row['uid'];
                $code = '<div id="' . $id . '" style="display:' . $display . ';" >' . $code . '</div>';
@@ -3052,13 +3165,28 @@ class FormEngine {
        }
 
        /**
+        * Returns the max-width in pixels for a <input>/<textarea>-element
+        *
+        * @param int $size The abstract size value (1-48)
+        * @return int max-width in pixels
+        * @internal
+        */
+       public function formMaxWidth($size = 48) {
+               $size = round($size * $this->form_largeComp);
+               $width = ceil($size * $this->form_rowsToStylewidth);
+               return $width;
+       }
+
+       /**
         * Returns parameters to set the width for a <input>/<textarea>-element
         *
         * @param int $size The abstract size value (1-48)
         * @param bool $textarea If this is for a text area.
         * @return string Either a "style" attribute string or "cols"/"size" attribute string.
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
         */
        public function formWidth($size = 48, $textarea = FALSE) {
+               GeneralUtility::logDeprecatedFunction();
                $fieldWidthAndStyle = $this->formWidthAsArray($size, $textarea);
                // Setting width by style-attribute. 'cols' MUST be avoided with NN6+
                $widthAndStyleAttributes = ' style="' . htmlspecialchars($fieldWidthAndStyle['style']) . '"';
@@ -3074,18 +3202,12 @@ class FormEngine {
         * @param int $size The abstract size value (1-48)
         * @param bool $textarea If set, calculates sizes for a text area.
         * @return array An array containing style, class, and width attributes.
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
         */
        public function formWidthAsArray($size = 48, $textarea = FALSE) {
+               GeneralUtility::logDeprecatedFunction();
                $fieldWidthAndStyle = array('style' => '', 'class' => '', 'width' => '');
-               $size = round($size * $this->form_largeComp);
-
-               // Setting width by style-attribute. 'cols' MUST be avoided with NN6+
-               $widthInPixels = ceil($size * $this->form_rowsToStylewidth);
-
-               if ($textarea) {
-                       $widthInPixels += $this->form_additionalTextareaStyleWidth;
-               }
-
+               $widthInPixels = $this->formMaxWidth($size);
                $fieldWidthAndStyle['style'] = 'width: ' . $widthInPixels . 'px; ';
                $fieldWidthAndStyle['class'] = 'formfield-' . ($textarea ? 'text' : 'input');
                return $fieldWidthAndStyle;
@@ -3181,7 +3303,7 @@ class FormEngine {
                                ' . ($singlePad['description'] ? '<p class="c-descr">' . nl2br(htmlspecialchars($singlePad['description'])) . '</p>' : '') . '
                                ' . $singlePad['content'];
                        }
-                       return '<div class="typo3-dyntabmenu-divs">' . $output . '</div>';
+                       return '<div class="tab-content">' . $output . '</div>';
                }
        }
 
@@ -3642,8 +3764,10 @@ class FormEngine {
         * @param array $PA An array with additional configuration options.
         * @return array Marker array for template output
         * @see function intoTemplate()
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
         */
        public function addUserTemplateMarkers($marker, $table, $field, $row, &$PA) {
+               GeneralUtility::logDeprecatedFunction();
                return $marker;
        }
 
@@ -3826,50 +3950,96 @@ class FormEngine {
         * @return string HTML output
         */
        public function printPalette($palArr) {
-               $fieldAttributes = ' class="t3-form-palette-field"';
-               $labelAttributes = ' class="t3-form-palette-field-label t3-form-field-label"';
 
+               // GROUP FIELDS
+               $groupedFields = array();
                $row = 0;
-               $iRow = array();
-               $lastLineWasLinebreak = FALSE;
-               // Traverse palette fields and render them into containers:
-               foreach ($palArr as $content) {
-                       if ($content['NAME'] === '--linebreak--') {
+               $lastLineWasLinebreak = TRUE;
+               foreach ($palArr as $field){
+                       if ($field['NAME'] === '--linebreak--') {
                                if (!$lastLineWasLinebreak) {
                                        $row++;
+                                       $groupedFields[$row][] = $field;
+                                       $row++;
                                        $lastLineWasLinebreak = TRUE;
                                }
                        } else {
                                $lastLineWasLinebreak = FALSE;
+                               $groupedFields[$row][] = $field;
+                       }
+               }
 
-                               $paletteMarkers = array(
-                                       '###CONTENT_TABLE###' => $content['TABLE'],
-                                       '###CONTENT_ID###' => $content['ID'],
-                                       '###CONTENT_FIELD###' => $content['FIELD'],
-                                       '###CONTENT_NAME###' => $content['NAME'],
-                                       '###CONTENT_ITEM###' => $content['ITEM'],
-                                       '###CONTENT_ITEM_NULLVALUE###' => $content['ITEM_NULLVALUE'],
-                                       '###CONTENT_ITEM_DISABLED###' => $content['ITEM_DISABLED'],
-                                       '###ATTRIBUTES_LABEL###' => $labelAttributes,
-                                       '###ATTRIBUTES_FIELD###' => $fieldAttributes,
+               $out = '';
+               // PROCESS FIELDS
+               foreach ($groupedFields as $fields) {
+
+                       $numberOfItems = count($fields);
+                       $cols = $numberOfItems;
+                       $colWidth = (int)floor(12 / $cols);
+
+                       // COLS
+                       $colClass = "col-md-12";
+                       $colClear = array();
+                       if ($colWidth == 6) {
+                               $colClass = "col-sm-6";
+                               $colClear = array(
+                                       2 => 'visible-sm-block visible-md-block visible-lg-block',
+                               );
+                       } elseif ($colWidth === 4) {
+                               $colClass = "col-sm-4";
+                               $colClear = array(
+                                       3 => 'visible-sm-block visible-md-block visible-lg-block',
                                );
-                               $iRow[$row][] = HtmlParser::substituteMarkerArray(
-                                       $this->paletteFieldTemplate,
-                                       $paletteMarkers,
-                                       FALSE,
-                                       TRUE
+                       } elseif ($colWidth === 3) {
+                               $colClass = "col-sm-6 col-md-3";
+                               $colClear = array(
+                                       2 => 'visible-sm-block',
+                                       4 => 'visible-md-block visible-lg-block',
+                               );
+                       } elseif ($colWidth <= 2) {
+                               $colClass = "checkbox-column col-sm-6 col-md-3 col-lg-2";
+                               $colClear = array(
+                                       2 => 'visible-sm-block',
+                                       4 => 'visible-md-block',
+                                       6 => 'visible-lg-block'
                                );
                        }
-               }
-               // Final wrapping into the fieldset:
-               $out = '<fieldset class="t3-form-palette-fieldset">';
-               for ($i = 0; $i <= $row; $i++) {
-                       if (isset($iRow[$i])) {
-                               $out .= implode('', $iRow[$i]);
-                               $out .= $i < $row ? '<div class="clearfix"></div>' : '';
+
+                       // RENDER FIELDS
+                       for ($counter = 0; $counter < $numberOfItems; $counter++) {
+                               $content = $fields[$counter];
+                               if ($content['NAME'] === '--linebreak--') {
+                                       if ($counter + 1 !== $numberOfItems) {
+                                               $out .= '<div class="clearfix"></div>';
+                                       }
+                               } else {
+
+                                       // ITEM
+                                       $out .= '
+                                               <!-- printPalette -->
+                                               <div class="form-group t3js-formengine-palette-field ' . $colClass . '">
+                                                       <label class="t3js-formengine-label">
+                                                               ' . $content['NAME'] . '
+                                                               <img name="req_' . $content['TABLE'] . '_' . $content['ID'] . '_' . $content['FIELD'] . '" src="clear.gif" class="t3js-formengine-field-required" alt="" />
+                                                       </label>
+                                                       ' . $content['ITEM_NULLVALUE'] . '
+                                                       <div class="t3js-formengine-field-item ' . $content['ITEM_DISABLED'] . '">
+                                                               <div class="t3-form-field-disable"></div>
+                                                               ' . $content['ITEM'] . '
+                                                       </div>
+                                               </div>';
+
+                                       // BREAKPOINTS
+                                       if ($counter + 1 < $numberOfItems && !empty($colClear)) {
+                                               foreach ($colClear as $rowBreakAfter => $clearClass) {
+                                                       if (($counter + 1) % $rowBreakAfter === 0) {
+                                                               $out .= '<div class="clearfix '. $clearClass . '"></div>';
+                                                       }
+                                               }
+                                       }
+                               }
                        }
                }
-               $out .= '</fieldset>';
                return $out;
        }
 
index 809796e..b159030 100644 (file)
@@ -1643,7 +1643,7 @@ function jumpToUrl(URL) {
                                }
                                // Create DIV layer for content:
                                $divs[] = '
-                                               <div style="display: none;" id="' . $id . '-' . $index . '-DIV" class="c-tablayer">' . ($def['description'] ? '<p class="c-descr">' . nl2br(htmlspecialchars($def['description'])) . '</p>' : '') . $def['content'] . '</div>';
+                                               <div id="' . $id . '-' . $index . '-DIV" class="tab-pane">' . ($def['description'] ? '<p class="c-descr">' . nl2br(htmlspecialchars($def['description'])) . '</p>' : '') . $def['content'] . '</div>';
                                // Create initialization string:
                                $JSinit[] = '
                                                DTM_array["' . $id . '"][' . $c . '] = "' . $id . '-' . $index . '";
@@ -1669,12 +1669,12 @@ function jumpToUrl(URL) {
                                                ' . implode('', $options[$a]) . '
                                        </ul>';
                                        }
-                                       $content .= '<div class="typo3-dyntabmenu-tabs">' . $tabContent . '</div>';
+                                       $content .= $tabContent;
                                }
                                // Div layers are added:
                                $content .= '
                                <!-- Div layers for tab menu: -->
-                               <div class="typo3-dyntabmenu-divs' . ($foldout ? '-foldout' : '') . '">
+                               <div class="tab-content' . ($foldout ? ' tab-content-foldout' : '') . '">
                                ' . implode('', $divs) . '</div>';
                                // Java Script section added:
                                $content .= '
index 599bdc7..b73317c 100644 (file)
@@ -3,65 +3,6 @@
 
 <div class="typo3-TCEforms">
        |
-       <div class="typo3-TCEforms-recHeaderRow">###RECORD_ICON### <span class="typo3-TCEforms-recHeader">###TABLE_TITLE###</span> ###ID_NEW_INDICATOR###</div>
+       <div class="help-block text-right">###RECORD_ICON### <strong>###TABLE_TITLE###</strong> ###ID_NEW_INDICATOR###</div>
 </div>
 <!-- ###TOTALWRAP### end -->
-
-
-<!-- ###FIELDTEMPLATE### begin -->
-<tr>
-       <td colspan="2" class="formField-header t3-form-field-label">
-               <h4>###FIELD_NAME###</h4>
-       </td>
-</tr>
-<tr>
-       <td colspan="2" class="formField-field">
-               <span class="t3-form-field-container">
-                       <img name="req_###FIELD_TABLE###_###FIELD_ID###_###FIELD_FIELD###" src="clear.gif" class="t3-TCEforms-reqImg" alt="" />
-                       ###FIELD_ITEM_NULLVALUE###
-                       <div class="t3-form-field-item###FIELD_ITEM_DISABLED###">
-                               <div class="t3-form-field-disable"></div>
-                               ###FIELD_ITEM###
-                       </div>
-               </span>
-       </td>
-</tr>
-<tr>
-       <td colspan="2" class="formField-field">
-               ###FIELD_PAL_LINK_ICON###
-       </td>
-</tr>
-<!-- ###FIELDTEMPLATE### end -->
-
-
-<!-- ###PALETTEFIELDTEMPLATE### begin -->
-<span class="t3-form-palette-field-container">
-       <label###ATTRIBUTES_LABEL###>
-               ###CONTENT_NAME###
-       </label>
-       <span###ATTRIBUTES_FIELD###>
-               <img name="req_###CONTENT_TABLE###_###CONTENT_ID###_###CONTENT_FIELD###" src="clear.gif" class="t3-form-palette-icon-required" alt="" />
-               ###CONTENT_ITEM_NULLVALUE###
-               <div class="t3-form-field-item###CONTENT_ITEM_DISABLED###">
-                       <div class="t3-form-field-disable"></div>
-                       ###CONTENT_ITEM###
-               </div>
-       </span>
-</span>
-<!-- ###PALETTEFIELDTEMPLATE### end -->
-
-
-<!-- ###PALETTE_FIELDTEMPLATE### begin -->
-<tr>
-       <td colspan="2" nowrap="nowrap">###FIELD_PALETTE###</td>
-</tr>
-<!-- ###PALETTE_FIELDTEMPLATE### end -->
-
-
-<!-- ###PALETTE_FIELDTEMPLATE_HEADER### begin -->
-<tr>
-       <td colspan="2" nowrap="nowrap" class="palette-header">
-               <h3>###FIELD_HEADER###</h3>
-       </td>
-</tr>
-<!-- ###PALETTE_FIELDTEMPLATE_HEADER### end -->
index b686c97..4e3c9ad 100644 (file)
@@ -40,15 +40,9 @@ define('TYPO3/CMS/Backend/DateTimePicker', ['jquery'], function ($) {
 
                                // initialize the datepicker on each selected element
                                $dateTimeFields.each(function() {
-                                       var $container = $(this);
-                                       var $currentElement = $container.find('.form-control');
+                                       var $element = $(this);
                                        var format = DateTimePicker.options.format;
-                                       var isDateTimeField = $currentElement.hasClass('tceforms-datetimefield') || $currentElement.hasClass('datetime');
-                                       var isDateField = $currentElement.hasClass('tceforms-datefield') || $currentElement.hasClass('date');
-                                       var isTimeField = $currentElement.hasClass('tceforms-timefield') || $currentElement.hasClass('time');
-                                       var isTimeSecField = $currentElement.hasClass('tceforms-timesecfield');
-                                       var isYearField = $currentElement.hasClass('tceforms-timesecfield');
-
+                                       var type = $element.data('dateType');
                                        var options = {
                                                pick12HourFormat: false,
                                                pickDate: true,
@@ -63,44 +57,47 @@ define('TYPO3/CMS/Backend/DateTimePicker', ['jquery'], function ($) {
                                                }
                                        };
 
-                                       if (isDateTimeField) {
-                                               options.format = format[1];
-                                       }
-                                       if (isDateField) {
-                                               options.format = format[0];
-                                               options.pickTime = false;
-                                       }
-                                       if (isTimeSecField) {
-                                               options.format = 'hh:mm:ss';
-                                               options.pickDate = false;
-                                               options.useSeconds = true;
-                                       }
-                                       if (isTimeField) {
-                                               options.pickDate = false;
-                                               options.format = 'hh:mm';
-                                       }
-                                       if (isYearField) {
-                                               options.format = 'YYYY';
-                                               options.pickDate = true;
-                                               options.pickTime = false;
+                                       // set options based on type
+                                       switch (type) {
+                                               case 'datetime':
+                                                       options.format = format[1];
+                                                       break;
+                                               case 'date':
+                                                       options.format = format[0];
+                                                       options.pickTime = false;
+                                                       break;
+                                               case 'time':
+                                                       options.pickDate = false;
+                                                       options.format = 'hh:mm';
+                                                       break;
+                                               case 'timesec':
+                                                       options.format = 'hh:mm:ss';
+                                                       options.pickDate = false;
+                                                       options.useSeconds = true;
+                                                       break;
+                                               case 'year':
+                                                       options.format = 'YYYY';
+                                                       options.pickDate = true;
+                                                       options.pickTime = false;
+                                                       break;
                                        }
 
                                        // initialize the date time picker on this element
-                                       $container.datetimepicker(options);
+                                       $element.datetimepicker(options);
                                });
 
-                               $dateTimeFields.on('blur', '.form-control', function(event) {
-                                       var $target = $(event.target);
-                                       var $datePicker = $target.closest(DateTimePicker.options.fieldSelector);
-                                       var $hiddenField = $datePicker.find('input[type=hidden]');
-                                       var calculateTimeZoneOffset = $datePicker.data('date-offset');
+                               $dateTimeFields.on('blur', function(event) {
+
+                                       var $element = $(this);
+                                       var $hiddenField = $element.parent().find('input[type=hidden]');
+                                       var calculateTimeZoneOffset = $element.data('date-offset');
 
-                                       if ($target.val() == '') {
+                                       if ($element.val() === '') {
                                                $hiddenField.val('');
                                        } else {
-                                               var format = $datePicker.data('DateTimePicker').format;
-                                               var date = moment($target.val(), format);
-                                               if (typeof calculateTimeZoneOffset != 'undefined') {
+                                               var format = $element.data('DateTimePicker').format;
+                                               var date = moment($element.val(), format);
+                                               if (typeof calculateTimeZoneOffset !== 'undefined') {
                                                        var timeZoneOffset = parseInt(calculateTimeZoneOffset);
                                                } else {
                                                        var timeZoneOffset = date.zone() * 60;
@@ -110,22 +107,22 @@ define('TYPO3/CMS/Backend/DateTimePicker', ['jquery'], function ($) {
                                                        $hiddenField.val(date.unix() - timeZoneOffset);
                                                } else {
                                                        date = moment($hiddenField.val() + timeZoneOffset, 'X');
-                                                       $target.val(date.format(format));
+                                                       $element.val(date.format(format));
                                                }
                                        }
                                });
 
                                // on datepicker change, write the selected date with the timezone offset to the hidden field
                                $dateTimeFields.on('dp.change', function(event) {
+                                       var $element = $(this);
                                        var date = event.date;
-                                       var $datePicker = $(event.currentTarget);
-                                       var calculateTimeZoneOffset = $datePicker.data('date-offset');
-                                       if (typeof calculateTimeZoneOffset != 'undefined') {
+                                       var calculateTimeZoneOffset = $element.data('date-offset');
+                                       if (typeof calculateTimeZoneOffset !== 'undefined') {
                                                var timeZoneOffset = parseInt(calculateTimeZoneOffset);
                                        } else {
                                                var timeZoneOffset = date.zone() * 60;
                                        }
-                                       var $hiddenField = $datePicker.find('input[type=hidden]');
+                                       var $hiddenField = $element.parent().find('input[type=hidden]');
                                        $hiddenField.val(date.unix() - timeZoneOffset);
                                });
                        });
index 20c12b9..5471de0 100644 (file)
@@ -550,7 +550,7 @@ define('TYPO3/CMS/Backend/FormEngine', ['jquery'], function ($) {
                });
 
                // in multi-select environments with two (e.g. "Access"), on click the item from the right should go to the left
-               $(document).on('click', '.t3-form-select-itemstoselect', function(evt) {
+               $(document).on('click', '.t3js-formengine-select-itemstoselect', function(evt) {
                        var $el = $(this)
                                        ,fieldName = $el.data('relatedfieldname')
                                        ,exclusiveValues = $el.data('exclusivevalues');
@@ -571,11 +571,11 @@ define('TYPO3/CMS/Backend/FormEngine', ['jquery'], function ($) {
         */
        FormEngine.SelectBoxFilter = {
                options: {
-                       fieldContainerSelector: '.t3-form-field-group-file',
-                       filterContainerSelector: '.t3-form-multiselect-filter-container',
-                       filterTextFieldSelector: '.t3-form-multiselect-filter-textfield',
-                       filterSelectFieldSelector: '.t3-form-multiselect-filter-dropdown',
-                       itemsToSelectElementSelector: '.t3-form-select-itemstoselect'
+                       fieldContainerSelector: '.t3js-formengine-field-group',
+                       filterContainerSelector: '.t3js-formengine-multiselect-filter-container',
+                       filterTextFieldSelector: '.t3js-formengine-multiselect-filter-textfield',
+                       filterSelectFieldSelector: '.t3js-formengine-multiselect-filter-dropdown',
+                       itemsToSelectElementSelector: '.t3js-formengine-select-itemstoselect'
                }
        };
 
@@ -648,9 +648,9 @@ define('TYPO3/CMS/Backend/FormEngine', ['jquery'], function ($) {
         */
        FormEngine.reinitialize = function() {
                // apply "close" button to all input / datetime fields
-               if ($('.t3-tceforms-input-wrapper, .t3-tceforms-input-wrapper-datetime').length) {
+               if ($('.t3js-clearable').length) {
                        require(['jquery/jquery.clearable'], function() {
-                               $('.t3-tceforms-input-wrapper .formfield-input, .t3-tceforms-input-wrapper-datetime .formfield-input').clearable();
+                               $('.t3js-clearable').clearable();
                        });
                }
                // apply DatePicker to all date time fields
index 9de3fa4..78508db 100644 (file)
@@ -18,8 +18,8 @@
  */
 
 var inline = {
-       classVisible: 't3-form-field-container-inline-visible',
-       classCollapsed: 't3-form-field-container-inline-collapsed',
+       classVisible: 'panel-visible',
+       classCollapsed: 'panel-collapsed',
        structureSeparator: '-',
        flexFormSeparator: '---',
        flexFormSubstitute: ':',
@@ -46,7 +46,7 @@ var inline = {
        },
        toggleEvent: function (event) {
                var $triggerElement = TYPO3.jQuery(event.target);
-               if ($triggerElement.parents('.t3-form-field-header-inline-ctrl').length == 1) {
+               if ($triggerElement.parents('.t3js-formengine-irre-control').length == 1) {
                        return;
                }
 
@@ -694,7 +694,6 @@ var inline = {
                                return;
                        }
 
-                       $sortingContainer.addClass('t3-form-field-container-wrap');
                        $sortingContainer.sortable(
                                {
                                        containment: 'parent',
@@ -1332,6 +1331,6 @@ Object.extend(Array.prototype, {
 /*]]>*/
 (function ($) {
        $(function () {
-               $(document).delegate('div.t3-form-field-header-inline', 'click', inline.toggleEvent);
+               $(document).delegate('[data-toggle="formengine-inline"]', 'click', inline.toggleEvent);
        });
 })(TYPO3.jQuery);
index a7642fb..7f3bf39 100644 (file)
@@ -332,23 +332,12 @@ var TBE_EDITOR = {
 
                // modify the "field has changed" info by adding a class to the container element (based on palette or main field)
                var $formField = TYPO3.jQuery('[name="' + el + '"]');
-               var $label = $formField.closest('.t3-form-palette-field-container').find('.t3-form-field-label');
-               // no palette - find the header if it is a flexform
-               if ($label.length === 0) {
-                       $label = $formField.closest('.t3-form-field-container').children('.t3-form-field-label');
-               }
-               // no flex either, check for a "normal" field
-               if ($label.length === 0) {
-                       $label = $formField.closest('.formField-field').parent().prev().find('.t3-form-field-label');
-               }
-               $label.addClass('t3-form-field-state-changed');
+               var $paletteField = $formField.closest('.t3js-formengine-palette-field');
+               $paletteField.addClass('has-change');
 
-                       // Set change image
+               // Set hidden field to value
                if (document[TBE_EDITOR.formname][theField] && document[TBE_EDITOR.formname][theField].type=="select-one" && document[TBE_EDITOR.formname][theField+"_selIconVal"]) {
-                       var imgObjName = "selIcon_"+table+"_"+uid+"_"+field+"_";
-                       TBE_EDITOR.setImage(imgObjName+document[TBE_EDITOR.formname][theField+"_selIconVal"].value,TBE_EDITOR.images.clear);
-                       document[TBE_EDITOR.formname][theField+"_selIconVal"].value = document[TBE_EDITOR.formname][theField].selectedIndex;
-                       TBE_EDITOR.setImage(imgObjName+document[TBE_EDITOR.formname][theField+"_selIconVal"].value,TBE_EDITOR.images.sel);
+                       document[TBE_EDITOR.formname][theField+"_selIconVal"].value = document[TBE_EDITOR.formname][theField].value;
                }
 
                        // Set required flag:
@@ -579,7 +568,7 @@ var TBE_EDITOR_str_replace = TBE_EDITOR.str_replace;
 var typo3form = {
        fieldSetNull: function(fieldName, isNull) {
                if (document[TBE_EDITOR.formname][fieldName]) {
-                       var formFieldItemWrapper = Element.up(document[TBE_EDITOR.formname][fieldName], '.t3-form-field-item');
+                       var formFieldItemWrapper = Element.up(document[TBE_EDITOR.formname][fieldName], '.t3js-formengine-field-item');
 
                        if (isNull) {
                                formFieldItemWrapper.addClassName('disabled');
@@ -593,9 +582,9 @@ var typo3form = {
                        return;
                }
 
-               var formFieldItemWrapper = Element.up(document[TBE_EDITOR.formname][fieldName], '.t3-form-field-item');
-               var placeholder = formFieldItemWrapper.select('.t3-form-placeholder-placeholder')[0];
-               var formField = formFieldItemWrapper.select('.t3-form-placeholder-formfield')[0];
+               var formFieldItemWrapper = Element.up(document[TBE_EDITOR.formname][fieldName], '.t3js-formengine-field-item');
+               var placeholder = formFieldItemWrapper.select('.t3js-formengine-placeholder-placeholder')[0];
+               var formField = formFieldItemWrapper.select('.t3js-formengine-placeholder-formfield')[0];
                if (showPlaceholder) {
                        placeholder.show();
                        formField.hide();
index fbc179b..a104ad6 100644 (file)
@@ -27,10 +27,10 @@ function DTM_activate(idBase,index,doToogle) {
        if (DTM_array[idBase]) {
                for(var cnt = 0; cnt < DTM_array[idBase].length; cnt++) {
                        if (DTM_array[idBase][cnt] !== idBase + '-' + index) {
-                               document.getElementById(DTM_array[idBase][cnt]+'-DIV').style.display = 'none';
+                               document.getElementById(DTM_array[idBase][cnt]+'-DIV').className = "tab-pane";
                                // Only Overriding when Tab not disabled
-                               if (document.getElementById(DTM_array[idBase][cnt]+'-MENU').attributes.getNamedItem('class').nodeValue !== 'disabled') {
-                                       document.getElementById(DTM_array[idBase][cnt]+'-MENU').attributes.getNamedItem('class').nodeValue = 'tab';
+                               if (document.getElementById(DTM_array[idBase][cnt]+'-MENU').attributes.getNamedItem('class').value !== 'disabled') {
+                                       document.getElementById(DTM_array[idBase][cnt]+'-MENU').attributes.getNamedItem('class').value = 'tab';
                                }
                        }
                }
@@ -38,31 +38,31 @@ function DTM_activate(idBase,index,doToogle) {
 
                // Showing one:
        if (document.getElementById(idBase+'-'+index+'-DIV')) {
-               if (doToogle && document.getElementById(idBase+'-'+index+'-DIV').style.display === 'block') {
-                       document.getElementById(idBase+'-'+index+'-DIV').style.display = 'none';
-                       document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').nodeValue = 'tab';
+               if (doToogle && document.getElementById(idBase+'-'+index+'-DIV').className === 'tab-pane active') {
+                       document.getElementById(idBase+'-'+index+'-DIV').className = "tab-pane";
+                       document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').value = 'tab';
                        top.DTM_currentTabs[idBase] = -1;
                } else {
-                       document.getElementById(idBase+'-'+index+'-DIV').style.display = 'block';
-                       document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').nodeValue = 'active';
+                       document.getElementById(idBase+'-'+index+'-DIV').className = "tab-pane active";
+                       document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').value = 'active';
                        top.DTM_currentTabs[idBase] = index;
                }
        }
-       document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').nodeValue = 'active';
+       document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').value = 'active';
 }
 function DTM_toggle(idBase,index,isInit) {
                // Showing one:
        if (document.getElementById(idBase+'-'+index+'-DIV')) {
-               if (document.getElementById(idBase+'-'+index+'-DIV').style.display === 'block') {
-                       document.getElementById(idBase+'-'+index+'-DIV').style.display = 'none';
+               if (document.getElementById(idBase+'-'+index+'-DIV').className === 'tab-pane active') {
+                       document.getElementById(idBase+'-'+index+'-DIV').className = "tab-pane";
                        if (isInit) {
-                               document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').nodeValue = 'tab';
+                               document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').value = 'tab';
                        }
                        top.DTM_currentTabs[idBase+'-'+index] = 0;
                } else {
-                       document.getElementById(idBase+'-'+index+'-DIV').style.display = 'block';
+                       document.getElementById(idBase+'-'+index+'-DIV').className = "tab-pane active";
                        if (isInit) {
-                               document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').nodeValue = 'active';
+                               document.getElementById(idBase+'-'+index+'-MENU').attributes.getNamedItem('class').value = 'active';
                        }
                        top.DTM_currentTabs[idBase+'-'+index] = 1;
                }
index a3432a4..12a14a1 100644 (file)
                                <tr>
                                        <td colspan="8">
                                                <div class="form-group col-sm-5">
-                                                       <label for="manualDateStart"><f:translate key="LLL:EXT:lang/locallang_common.xlf:from" /></label>&nbsp;
-                                                       <div class="input-group date t3js-datetimepicker" data-date-offset="0" id="tceforms-datetimefield-manualDateStart-wrapper">
+                                                       <label for="manualDateStart"><f:translate key="LLL:EXT:lang/locallang_common.xlf:from" /></label>
+                                                       <div class="input-group">
                                                                <f:form.textfield
                                                                                name="manualDateStart"
                                                                                value="{f:if(condition: constraint.startTimestamp, then: \"{f:format.date(format:'{settings.timeFormat} {settings.dateFormat}', date: '@{constraint.startTimestamp}')}\")}"
                                                                                id="manualDateStart"
-                                                                               class="form-control datetime"
+                                                                               class="form-control t3js-datetimepicker t3js-clearable"
+                                                                               data="{date-type: 'datetime', date-offset: 0}"
                                                                                />
                                                                <f:form.hidden property="startTimestamp" value="{constraint.startTimestamp}" />
-                                                               <span class="input-group-addon datepickerbutton"><span class="fa fa-calendar"></span></span>
+                                                               <span class="input-group-btn">
+                                                                       <label class="btn btn-default" for="manualDateStart">
+                                                                               <span class="fa fa-calendar"></span>
+                                                                       </label>
+                                                               </span>
                                                        </div>
                                                </div>
                                                <div class="form-group col-sm-5">
-                                                       <label for="manualDateStop"><f:translate key="LLL:EXT:lang/locallang_common.xlf:to" /></label>&nbsp;
-                                                       <div class="input-group date t3js-datetimepicker" data-date-offset="0" id="tceforms-datetimefield-manualDateStop-wrapper">
+                                                       <label for="manualDateStop"><f:translate key="LLL:EXT:lang/locallang_common.xlf:to" /></label>
+                                                       <div class="input-group">
                                                                <f:form.textfield
                                                                                name="manualDateStop"
                                                                                value="{f:format.date(format:'{settings.timeFormat} {settings.dateFormat}', date: '@{constraint.endTimestamp}')}"
                                                                                id="manualDateStop"
-                                                                               class="form-control datetime"
+                                                                               class="form-control t3js-datetimepicker t3js-clearable"
+                                                                               data="{date-type: 'datetime', date-offset: 0}"
                                                                                />
                                                                <f:form.hidden property="endTimestamp" />
-                                                               <span class="input-group-addon datepickerbutton"><span class="fa fa-calendar"></span></span>
+                                                               <span class="input-group-btn">
+                                                                       <label class="btn btn-default" for="manualDateStop">
+                                                                               <span class="fa fa-calendar"></span>
+                                                                       </label>
+                                                               </span>
                                                        </div>
                                                </div>
                                                <div class="form-group col-sm-2">
index 3e87039..8c818f3 100644 (file)
                                                                <eval>trim,required</eval>
                                                                <default></default>
                                                                <wizards type="array">
-                                                                       <_PADDING>2</_PADDING>
                                                                        <link type="array">
                                                                                <type>popup</type>
                                                                                <title>LLL:EXT:cms/locallang_ttc.xml:media.browseUrlTitle</title>
                                                                                                <eval>trim,required</eval>
                                                                                                <default></default>
                                                                                                <wizards type="array">
-                                                                                                       <_PADDING>2</_PADDING>
                                                                                                        <link type="array">
                                                                                                                <type>popup</type>
                                                                                                                <title>LLL:EXT:cms/locallang_ttc.xml:media.browseUrlTitle</title>
                                                                <eval>trim</eval>
                                                                <default></default>
                                                                <wizards type="array">
-                                                                       <_PADDING>2</_PADDING>
                                                                        <link type="array">
                                                                                <type>popup</type>
                                                                                <title>LLL:EXT:cms/locallang_ttc.xml:media.browseUrlTitle</title>
                                                                                                <eval>trim,required</eval>
                                                                                                <default></default>
                                                                                                <wizards type="array">
-                                                                                                       <_PADDING>2</_PADDING>
                                                                                                        <link type="array">
                                                                                                                <type>popup</type>
                                                                                                                <title>LLL:EXT:cms/locallang_ttc.xml:media.browseUrlTitle</title>
                                                                <eval>trim</eval>
                                                                <default></default>
                                                                <wizards type="array">
-                                                                       <_PADDING>2</_PADDING>
                                                                        <link type="array">
                                                                                <type>popup</type>
                                                                                <title>LLL:EXT:cms/locallang_ttc.xml:media.browseUrlTitle</title>
                                                                                                <eval>trim,required</eval>
                                                                                                <default></default>
                                                                                                <wizards type="array">
-                                                                                                       <_PADDING>2</_PADDING>
                                                                                                        <link type="array">
                                                                                                                <type>popup</type>
                                                                                                                <title>LLL:EXT:cms/locallang_ttc.xml:media.browseUrlTitle</title>
                        </ROOT>
                </sAudio>
        </sheets>
-</T3DataStructure>
\ No newline at end of file
+</T3DataStructure>
index 1145e50..5d5cf36 100644 (file)
@@ -411,7 +411,7 @@ class QueryView {
                                        $rowArr[] = $this->csvValues($row, ',', '"', $GLOBALS['TCA'][$table], $table);
                                }
                                if (count($rowArr)) {
-                                       $out .= '<textarea name="whatever" rows="20" wrap="off"' . $GLOBALS['SOBE']->doc->formWidthText($this->formW, '', 'off') . ' class="fixed-font">' . GeneralUtility::formatForTextarea(implode(LF, $rowArr)) . '</textarea>';
+                                       $out .= '<textarea name="whatever" rows="20" wrap="off"' . $GLOBALS['SOBE']->doc->formWidthText($this->formW, '', 'off') . ' class="text-monospace">' . GeneralUtility::formatForTextarea(implode(LF, $rowArr)) . '</textarea>';
                                        if (!$this->noDownloadB) {
                                                $out .= '<br><input class="btn btn-default" type="submit" name="download_file" value="Click to download file" onClick="window.location.href=\'' . $this->downloadScript . '\';">';
                                        }
index 083091a..c2156a9 100644 (file)
@@ -62,7 +62,6 @@ return array(
                                'autoSizeMax' => 10,
                                'iconsInOptionTags' => 1,
                                'wizards' => array(
-                                       '_PADDING' => 1,
                                        '_VERTICAL' => 1,
                                        'edit' => array(
                                                'type' => 'popup',
index 077afd3..25650ea 100644 (file)
@@ -63,7 +63,6 @@ return array(
                                'maxitems' => '20',
                                'iconsInOptionTags' => 1,
                                'wizards' => array(
-                                       '_PADDING' => 1,
                                        '_VERTICAL' => 1,
                                        'edit' => array(
                                                'type' => 'popup',
@@ -141,7 +140,6 @@ return array(
                                'autoSizeMax' => 10,
                                'iconsInOptionTags' => 1,
                                'wizards' => array(
-                                       '_PADDING' => 1,
                                        '_VERTICAL' => 1,
                                        'edit' => array(
                                                'type' => 'popup',
index f23038b..269ea15 100644 (file)
@@ -173,7 +173,6 @@ return array(
                                'size' => '20',
                                'max' => 1024,
                                'wizards' => array(
-                                       '_PADDING' => 2,
                                        'link' => array(
                                                'type' => 'popup',
                                                'title' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.link',
index 659541e..b678279 100644 (file)
@@ -69,8 +69,6 @@ return array(
                                'cols' => '48',
                                'rows' => '5',
                                'wizards' => array(
-                                       '_PADDING' => 4,
-                                       '_VALIGN' => 'middle',
                                        'RTE' => array(
                                                'notNewRecords' => 1,
                                                'RTEonly' => 1,
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-64762-FormEngineWizards.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-64762-FormEngineWizards.rst
new file mode 100644 (file)
index 0000000..94f07b5
--- /dev/null
@@ -0,0 +1,30 @@
+========================================
+Deprecation: #64762 - FormEngine wizards
+========================================
+
+Description
+===========
+
+The following TCA wizards properties are removed:
+
+* _PADDING
+* _VALIGN
+* _DISTANCE
+
+
+Impact
+======
+
+Usage of the mentioned TCA properties has no effect anymore.
+
+
+Affected installations
+======================
+
+Installations with special TCA wizard position settings ignore those now.
+
+
+Migration
+=========
+
+Remove above properties.
\ No newline at end of file
index 75b8fdb..47da952 100644 (file)
@@ -21,4 +21,4 @@ Instances which use custom form elements, which make use of ``FormEngine::insert
 Migration
 =========
 
-All form fields should extend the ``AbstractFormElement`` class and make use of the new property ``AbstractFormElement::$cssClassTypeElementPrefix``
+The property is unused and can be removed.
index 8ffe51e..79f2ab2 100644 (file)
@@ -114,7 +114,6 @@ $TCA['tx_blogexample_domain_model_blog'] = array(
                                        array('--none--', 0),
                                        ),
                                'wizards' => Array(
-                                        '_PADDING' => 1,
                                         '_VERTICAL' => 1,
                                         'edit' => Array(
                                                 'type' => 'popup',
@@ -145,4 +144,4 @@ $TCA['tx_blogexample_domain_model_blog'] = array(
        'palettes' => array(
                '1' => array('showitem' => '')
        )
-);
\ No newline at end of file
+);
index a7df22a..281e855 100644 (file)
@@ -87,7 +87,6 @@ $TCA['tx_blogexample_domain_model_post'] = array(
                                'type' => 'select',
                                'foreign_table' => 'tx_blogexample_domain_model_person',
                                'wizards' => Array(
-                                        '_PADDING' => 1,
                                         '_VERTICAL' => 1,
                                         'edit' => Array(
                                                 'type' => 'popup',
index 75a9428..691cf39 100644 (file)
@@ -46,7 +46,6 @@ return array(
                                'rows' => '5',
                                'cols' => '25',
                                'wizards' => array(
-                                       '_PADDING' => 4,
                                        0 => array(
                                                'title' => 'LLL:EXT:cms/locallang_tca.xlf:backend_layout.wizard',
                                                'type' => 'popup',
diff --git