Index: t3lib/config_default.php =================================================================== --- t3lib/config_default.php (Revision 7539) +++ t3lib/config_default.php (Arbeitskopie) @@ -285,6 +285,7 @@ 'WorkspaceMenu::setWorkspace' => 'typo3/classes/class.workspaceselector.php:WorkspaceSelector->setWorkspace', 'ExtDirect::getAPI' => 't3lib/extjs/class.t3lib_extjs_extdirectapi.php:t3lib_extjs_ExtDirectApi->getAPI', 'ExtDirect::route' => 't3lib/extjs/class.t3lib_extjs_extdirectrouter.php:t3lib_extjs_ExtDirectRouter->route', + 'ExtJS_TabMenu::setExtTabMenuActiveTab' => 'typo3/template.php:template->setActiveTab', ), 'XCLASS' => array(), // See 'Inside TYPO3' document for more information. 'spriteIconRecordOverlayPriorities' => array('hidden', 'starttime', 'endtime', 'futureendtime', 'fe_group', 'protectedSection'), Index: t3lib/class.t3lib_tceforms.php =================================================================== --- t3lib/class.t3lib_tceforms.php (Revision 7539) +++ t3lib/class.t3lib_tceforms.php (Arbeitskopie) @@ -477,6 +477,7 @@ global $TCA, $TYPO3_CONF_VARS; $this->renderDepth=$depth; + $tabType = 'exttab'; // Init vars: $out_array = array(array()); @@ -530,10 +531,10 @@ $tabIdentStringMD5 = ''; if (strstr($itemList, '--div--') !== false && $this->enableTabMenu && $dividers2tabs) { $tabIdentString = 'TCEforms:'.$table.':'.$row['uid']; - $tabIdentStringMD5 = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId($tabIdentString); + $tabIdentStringMD5 = $GLOBALS['TBE_TEMPLATE']->getExtTabMenuId($tabIdentString); // Remember that were currently working on the general tab: if (isset($fields[0]) && strpos($fields[0], '--div--') !== 0) { - $this->pushToDynNestedStack('tab', $tabIdentStringMD5.'-1'); + $this->pushToDynNestedStack($tabType, $tabIdentStringMD5 . '-1'); } } @@ -581,9 +582,9 @@ // Remove last tab entry from the dynNestedStack: $out_sheet++; // Remove the previous sheet from stack (if any): - $this->popFromDynNestedStack('tab', $tabIdentStringMD5.'-'.($out_sheet)); + $this->popFromDynNestedStack($tabType, $tabIdentStringMD5 . '-' . $out_sheet); // Remember on which sheet we're currently working: - $this->pushToDynNestedStack('tab', $tabIdentStringMD5.'-'.($out_sheet+1)); + $this->pushToDynNestedStack($tabType, $tabIdentStringMD5 . '-' . ($out_sheet+1)); $out_array[$out_sheet] = array(); $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]); // Register newline for Tab @@ -593,7 +594,7 @@ $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]); // Only add the first tab to the dynNestedStack if there are more tabs: if ($tabIdentString && strpos($itemList, '--div--', strlen($fieldInfo))) { - $this->pushToDynNestedStack('tab', $tabIdentStringMD5.'-1'); + $this->pushToDynNestedStack($tabType, $tabIdentStringMD5 . '-1'); } } } elseif($theField=='--palette--') { @@ -669,7 +670,7 @@ if (count($parts) > 1) { // Unset the current level of tab menus: - $this->popFromDynNestedStack('tab', $tabIdentStringMD5.'-'.($out_sheet+1)); + $this->popFromDynNestedStack($tabType, $tabIdentStringMD5 . '-' . ($out_sheet+1)); $dividersToTabsBehaviour = (isset($TCA[$table]['ctrl']['dividers2tabs']) ? $TCA[$table]['ctrl']['dividers2tabs'] : 1); $output = $this->getDynTabMenu($parts, $tabIdentString, $dividersToTabsBehaviour); @@ -4323,7 +4324,7 @@ function getDynTabMenu($parts, $idString, $dividersToTabsBehaviour = 1) { if (is_object($GLOBALS['TBE_TEMPLATE'])) { $GLOBALS['TBE_TEMPLATE']->backPath = $this->backPath; - return $GLOBALS['TBE_TEMPLATE']->getDynTabMenu($parts, $idString, 0, false, 50, 1, false, 1, $dividersToTabsBehaviour); + return $GLOBALS['TBE_TEMPLATE']->getExtTabMenu($parts, $idString, 1, $dividersToTabsBehaviour); } else { $output = ''; foreach($parts as $singlePad) { @@ -5424,6 +5425,9 @@ '; } + $out .= 'Ext.onReady(function(){ + '; + // add JS required for inline fields if (count($this->inline->inlineData)) { $out .= ' @@ -5457,6 +5461,14 @@ $out .= ' TBE_EDITOR.loginRefreshed(); '; + + // Focus first element + $out .= ' + Ext.select(".typo3-TCEforms input:first").focus(); + '; + + $out .= ' + });'; // Regular direct output: if (!$update) { Index: typo3/jsfunc.tbe_editor.js =================================================================== --- typo3/jsfunc.tbe_editor.js (Revision 7539) +++ typo3/jsfunc.tbe_editor.js (Arbeitskopie) @@ -249,18 +249,27 @@ nestedLevelType = fieldLevels[i][0]; nestedLevelName = fieldLevels[i][1]; fieldLevelIdent = TBE_EDITOR.getNestedLevelIdent(fieldLevels[i]); + var backgroundImage = false; + // Construct the CSS id strings of the image/icon tags showing the notification: if (nestedLevelType == 'tab') { element = nestedLevelName+'-REQ'; } else if (nestedLevelType == 'inline') { element = nestedLevelName+'_req'; + } else if (nestedLevelType == 'exttab') { + element = 'ext-comp-1001__' + nestedLevelName + '-DIV'; + backgroundImage = true; } else { continue; } // Set the icons: if (resolved) { if (TBE_EDITOR.checkNested(fieldLevelIdent)) { - TBE_EDITOR.setImage(element, TBE_EDITOR.images.clear); + if (backgroundImage) { + TBE_EDITOR.unsetExtBackgroundImage(element); + } else { + TBE_EDITOR.unsetImage(element); + } } else { break; } @@ -268,7 +277,12 @@ if (TBE_EDITOR.nested.level && TBE_EDITOR.nested.level[fieldLevelIdent]) { TBE_EDITOR.nested.level[fieldLevelIdent].clean = false; } - TBE_EDITOR.setImage(element, TBE_EDITOR.images.req); + + if (backgroundImage) { + TBE_EDITOR.setExtBackgroundImage(element, TBE_EDITOR.images.req); + } else { + TBE_EDITOR.setImage(element, TBE_EDITOR.images.req); + } } } } @@ -480,6 +494,39 @@ } } }, + unsetImage: function(name) { + TBE_EDITOR.setImage(name, TBE_EDITOR.images.clear); + }, + setExtBackgroundImage: function(name,image) { + // Get Image Path + if (typeof image == 'object') { + var imagePath = image.src; + } else { + var imagePath = eval(image+'.src'); + } + + // Set the class in the top element + Ext.select('#'+name).addClass("x-tab-with-icon"); + + // set Background Image in the inner text + var outerBox = Ext.DomQuery.selectNode("#"+name+" .x-tab-strip-text"); + Ext.fly(outerBox).setStyle("background-image", "url("+imagePath+")"); + }, + unsetExtBackgroundImage: function(name) { + // get the image + var image = TBE_EDITOR.images.clear; + if (typeof image == 'object') { + var imagePath = image.src; + } else { + var imagePath = eval(image+'.src'); + } + + Ext.select('#'+name).removeClass("x-tab-with-icon"); + + // Set blank icon + var outerBox = Ext.DomQuery.selectNode("#"+name+" .x-tab-strip-text"); + Ext.fly(outerBox).setStyle("background-image", "url("+imagePath+")"); + }, submitForm: function() { if (TBE_EDITOR.doSaveFieldName) { document[TBE_EDITOR.formname][TBE_EDITOR.doSaveFieldName].value=1; Index: typo3/template.php =================================================================== --- typo3/template.php (Revision 7539) +++ typo3/template.php (Arbeitskopie) @@ -1772,7 +1772,144 @@ return ''; } + /** + * Creates a DYNAMIC tab-menu eith extJS TabPanel + * + * @param array Numeric array where each entry is an array in itself with associative keys: "label" contains the label for the TAB, "content" contains the HTML content that goes into the div-layer of the tabs content. "description" contains description text to be shown in the layer. "linkTitle" is short text for the title attribute of the tab-menu link (mouse-over text of tab). "stateIcon" indicates a standard status icon (see ->icon(), values: -1, 1, 2, 3). "icon" is an image tag placed before the text. + * @param string Identification string. This should be unique for every instance of a dynamic menu! + * @param integer Default tab to open (for toggle <=0). Value corresponds to integer-array index + 1 (index zero is "1", index "1" is 2 etc.). A value of zero (or something non-existing) will result in no default tab open. + * @param integer If set to '1' empty tabs will be remove, If set to '2' empty tabs will be disabled + * @return string rendered HTML + */ + function getExtTabMenu($menuItems, $identString, $defaultTabIndex = 1, $dividers2tabs = 2, $tabPanelConfig = array()) { + $tabId = $this->getExtTabMenuId($identString); + $content = '