Index: D:/workspace-typo3/typo3/typo3_src-svn/t3lib/class.t3lib_tceforms.php
===================================================================
--- D:/workspace-typo3/typo3/typo3_src-svn/t3lib/class.t3lib_tceforms.php	(revision 2547)
+++ D:/workspace-typo3/typo3/typo3_src-svn/t3lib/class.t3lib_tceforms.php	(working copy)
@@ -283,6 +283,9 @@
 	var $hiddenFieldListArr = array();			// This array of fields will be set as hidden-fields instead of rendered normally! For instance palette fields edited in the top frame are set as hidden fields since the main form has to submit the values. The top frame actually just sets the value in the main form!
 	var $requiredFields=array();				// Used to register input-field names, which are required. (Done during rendering of the fields). This information is then used later when the JavaScript is made.
 	var $requiredElements=array();				// Used to register the min and max number of elements for selectorboxes where that apply (in the "group" type for instance)
+	var $requiredNested=array();				// Used to determine where $requiredFields or $requiredElements are nested (in Tabs or IRRE)
+	var $requiredConditions = array();			// Used to register the condition for required-field
+	var $requiredTriggers = array();			// Used to register trigger-fields, which checks a required field on a change
 	var $renderDepth=0;							// Keeps track of the rendering depth of nested records.
 	var $savedSchemes=array();					// Color scheme buffer.
 	var $dynNestedStack = array();				// holds the path an element is nested in (e.g. required for RTEhtmlarea)
@@ -588,14 +591,14 @@
 				}
 			}
 		}
-
+		
 			// Hook: getMainFields_postProcess (requested by Thomas Hempel for use with the "dynaflex" extension)
 		foreach ($this->hookObjectsMainFields as $hookObj)	{
 			if (method_exists($hookObj,'getMainFields_postProcess'))	{
 				$hookObj->getMainFields_postProcess($table,$row,$this);
 			}
 		}
-
+		
 			// Wrapping a border around it all:
 		$this->wrapBorder($out_array[$out_sheet],$out_pointer);
 
@@ -944,6 +947,9 @@
 				$hookObj->getSingleField_postProcess($table, $field, $row, $out, $PA, $this);
 			}
 		}
+		if (!empty($out['ITEM'])) {
+			$this->registerPossibleTrigger($PA['itemFormElName']);
+		}
 			// Return value (string or array)
 		return $out;
 	}
@@ -1065,7 +1071,13 @@
 		}
 
 		if (in_array('required',$evalList))	{
-			$this->requiredFields[$table.'_'.$row['uid'].'_'.$field]=$PA['itemFormElName'];
+			$this->registerRequiredProperty('field', $table.'_'.$row['uid'].'_'.$field, $PA['itemFormElName']);
+			foreach ($evalList AS $evalListItem) {
+				if (strpos($evalListItem,'condition') !== false) {
+					$this->registerRequiredCondition($table,$row['uid'],$field,substr($evalListItem,9));
+					break;
+				}
+			}
 		}
 
 		$paramsList = "'".$PA['itemFormElName']."','".implode(',',$evalList)."','".trim($config['is_in'])."',".(isset($config['checkbox'])?1:0).",'".$config['checkbox']."'";
@@ -1799,7 +1811,7 @@
 		$minitems = t3lib_div::intInRange($config['minitems'],0);
 
 			// Register the required number of elements:
-		$this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
+		$this->registerRequiredProperty('range', $PA['itemFormElName'], array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field));
 
 			// Get "removeItems":
 		$removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
@@ -1903,7 +1915,7 @@
 		}
 
 		$item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'"'.$disabled.' />';
-		$this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
+		$this->registerRequiredProperty('range', $PA['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. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/.
@@ -4652,6 +4664,8 @@
 		$jsFile = array();
 		$elements = array();
 
+		$this->validateConditions();
+
 			// required:
 		foreach ($this->requiredFields as $itemImgName => $itemName) {
 			if (preg_match('/^(.+)\[((\w|\d|_)+)\]$/', $itemName, $match)) {
@@ -4659,6 +4673,9 @@
 				$field = $match[2];
 				$elements[$record][$field]['required'] = 1;
 				$elements[$record][$field]['requiredImg'] = $itemImgName;
+				if (isset($this->requiredConditions[$itemName])) {
+					$elements[$record][$field]['requiredCond'] = $this->requiredConditions[$itemName];
+				}
 			}
 		}
 			// range:
@@ -4670,6 +4687,16 @@
 				$elements[$record][$field]['rangeImg'] = $range['imgName'];
 			}
 		}
+			// trigger:
+		foreach ($this->requiredTriggers AS $itemName => $fields) {
+			if (count($fields) > 0) {
+				if (preg_match('/^(.+)\[((\w|\d|_)+)\]$/', $itemName, $match)) {
+					$record = $match[1];
+					$field = $match[2];
+					$elements[$record][$field]['trigger'] = $fields;
+				}
+			}
+		}
 
 		$this->TBE_EDITOR_fieldChanged_func='TBE_EDITOR.fieldChanged_fName(fName,formObj[fName+"_list"]);';
 
@@ -4721,6 +4748,12 @@
 			inline.addToDataArray('.$this->inline->getJSON($this->inline->inlineData).');
 			';
 		}
+			// Registered nested elements for tabs or inline levels:
+		if (count($this->requiredNested)) {
+			$out .= '
+			TBE_EDITOR.addNested('.$this->inline->getJSON($this->requiredNested).');
+			';
+		}
 			// elements which are required or have a range definition:
 		if (count($elements)) {
 			$out .= '
@@ -4728,7 +4761,7 @@
 			TBE_EDITOR.initRequired()
 			';
 		}
-			// $this->additionalJS_post:
+			// $this->additionalJS_submit:
 		if ($this->additionalJS_submit) {
 			$additionalJS_submit = implode('', $this->additionalJS_submit);
 			$additionalJS_submit = str_replace("\r", '', $additionalJS_submit);
@@ -5016,28 +5049,6 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 	/********************************************
 	 *
 	 * Various helper functions
@@ -5484,6 +5495,168 @@
 		}
 		return ($json ? $this->inline->getJSON($result) : $result);
 	}
+	
+	/**
+	 * Takes care of registering properties in requiredFields and requiredElements.
+	 * The current hierarchy of IRRE and/or Tabs is stored. Thus, it is possible to determine,
+	 * which required field/element was filled incorrectly and show it, even if the Tab or IRRE
+	 * level is hidden.
+	 *
+	 * @param	string		$type: Type of requirement ('field' or 'range')
+	 * @param	string		$name: The name of the form field
+	 * @param	mixed		$value: For type 'field' string, for type 'range' array
+	 * @return	void
+	 */
+	function registerRequiredProperty($type, $name, $value) {
+		if ($type == 'field' && is_string($value)) {
+			$this->requiredFields[$name] = $value;
+				// requiredFields have name/value swapped! For backward compatibility we keep this:
+			$itemName = $value;
+		} elseif ($type == 'range' && is_array($value)) {
+			$this->requiredElements[$name] = $value;
+			$itemName = $name;
+		}
+			// Set the situation of nesting for the current field:
+		$this->registerNestedElement($itemName);
+	}
+
+	/**
+	 * Set the current situation of nested tabs and inline levels for a given element.
+	 *
+	 * @param	string		$itemName: The element the nesting should be stored for
+	 * @param	boolean		$setLevel: Set the reverse level lookup - default: true
+	 * @return	void
+	 */
+	function registerNestedElement($itemName, $setLevel=true) {
+		$dynNestedStack = $this->getDynNestedStack();
+		if (count($dynNestedStack) && preg_match('/^(.+\])\[(\w+)\]$/', $itemName, $match)) {
+			array_shift($match);
+			$this->requiredNested[$itemName] = array(
+				'parts' => $match,
+				'level' => $dynNestedStack,
+			);
+		}
+	}
+
+	/**
+	 * Takes care of registering properties in requiredConditions.
+	 *
+	 * @param	string		$table: The name of the form field
+	 * @param	string		$uid: The name of the form field
+	 * @param	string		$field: The name of the form field
+	 * @param	string		$condition: Condition string
+	 * @return	void
+	 */
+	function registerRequiredCondition($table,$uid,$field, $condition) {
+		$name = $this->prependFormFieldNames.'['.$table.']['.$uid.']['.$field.']';
+		$this->requiredConditions[$name]['cond'] = $condition;
+		$this->requiredConditions[$name]['table'] = $table;
+		$this->requiredConditions[$name]['uid'] = $uid;
+		$this->requiredConditions[$name]['field'] = $field;
+	}
+	
+	/**
+	 * Takes care of registering properties in requiredConditions.
+	 *
+	 * @param	string		$name: The name of the form field
+	 * @return	void
+	 */
+	function registerPossibleTrigger($name) {
+		$this->requiredTriggers[$name] = array();
+	}
+	
+	/**
+	 * Validates requiredConditions.
+	 * Checking wether a field exists etc.
+	 *
+	 * @return	void
+	 */
+	function validateConditions() {
+		foreach ($this->requiredConditions AS $field => $condition) {
+			$this->validateCondition($condition['table'],$condition['uid'],$condition['field'],$condition['cond']);
+		}
+	}
+	
+	/**
+	 * Takes care of registering properties in requiredTriggers and requiredCondition.
+	 *
+	 * @param	string		$table: Tablename of the form field
+	 * @param	string		$uid: Uid of the form field
+	 * @param	string		$name: The name of the form field
+	 * @param	string		$condition: Condition string
+	 * @return	void
+	 */
+	function validateCondition($table,$uid,$field, $condition) {
+		
+		$i = 0;
+		$condParts = array();
+		//Getting all Trigger-Fields
+		$replace = "([a-z\_\-\!]+)";
+		while(preg_match($replace, $condition,$res)) {
+			$trigger = $res[0];
+			$condParts[$i]['part'] = $trigger;
+			$condParts[$i]['cond'] = false;
+			$trigger_value = 1;
+			if (substr($trigger,0,1) == '!') {
+				$trigger = substr($trigger,1);
+				$trigger_value = 0;
+			}
+			$trigger_name = $this->prependFormFieldNames.'['.$table.']['.$uid.']['.$trigger.']'; 
+			if (isset($this->requiredTriggers[$trigger_name])) {
+				$this->requiredTriggers[$trigger_name][] = $field;
+				$condParts[$i]['cond'] = array(
+											'type' => 'field',
+											'parameter' => array(
+													'name' => $trigger,
+													'value' => $trigger_value
+											)
+										);
+			}
+			
+			$condition = preg_replace($replace , "~$i~", $condition,1);
+			$i++;
+		}
+		// Getting Subpattern with ORs and ANDs
+		$replace = "|\[([0-9\~\&\|]+)\]|";
+		while(preg_match($replace, $condition,$res)) {
+			$res = str_replace('[','',str_replace(']','',$res[0]));
+			$condParts[$i]['part'] = $res; //check output
+			$ors = explode("|",$res);
+			$condParts[$i]['cond'] = array('type' => 'or', 'parameter' => array());
+			foreach ($ors AS $or) {
+				$ands = explode("&",$or);
+				$or = array('type' => 'and', 'parameter' => array());
+				foreach($ands AS $and) {
+					$and = $condParts[str_replace('~','',$and)]['cond'];
+					if ($and !== false) {
+						$or['parameter'][] = $and;
+					}
+				}
+				if (count($or['parameter']) == 1) {
+					$or = $or['parameter'][0];
+				}
+				if (count($or['parameter']) > 0) {
+					$condParts[$i]['cond']['parameter'][] = $or;
+				}
+			}
+			if (count($condParts[$i]['cond']['parameter']) == 1) {
+				$condParts[$i]['cond'] = $condParts[$i]['cond']['parameter'][0];
+			}
+			if (count($condParts[$i]['cond']['parameter']) == 0) {
+				$condParts[$i]['cond'] = false;
+			}
+			$condition = preg_replace($replace , "~$i~", $condition,1);
+			$i++;
+		}
+		$condition = $condParts[str_replace('~','',$condition)]['cond'];
+		if ($condition === false) {
+			$condition = array('type' => 'ignore');
+		}
+
+		$this->requiredConditions[$this->prependFormFieldNames.'['.$table.']['.$uid.']['.$field.']'] = $condition;
+	}
+	
+	
 }
 
 
Index: D:/workspace-typo3/typo3/typo3_src-svn/t3lib/jsfunc.inline.js
===================================================================
--- D:/workspace-typo3/typo3/typo3_src-svn/t3lib/jsfunc.inline.js	(revision 2547)
+++ D:/workspace-typo3/typo3/typo3_src-svn/t3lib/jsfunc.inline.js	(working copy)
@@ -535,6 +535,7 @@
 
 			// Remove from TBE_EDITOR (required fields, required range, etc.):
 		if (TBE_EDITOR && TBE_EDITOR.removeElement) {
+			var removeStack = [];
 			inlineRecords = document.getElementsByClassName('inlineRecord', objectId+'_div');
 				// Remove nested child records from TBE_EDITOR required/range checks:
 			for (i=inlineRecords.length-1; i>=0; i--) {
@@ -543,11 +544,12 @@
 					childObjectId = this.data.map[inlineRecords[i].name];
 					childTable = this.data.config[childObjectId].table;
 					for (j=records.length-1; j>=0; j--) {
-						TBE_EDITOR.removeElement(this.prependFormFieldNames+'['+childTable+']['+records[j]+']');
+						removeStack.push(this.prependFormFieldNames+'['+childTable+']['+records[j]+']');
 					}
 				}
 			}
-			TBE_EDITOR.removeElement(this.prependFormFieldNames+shortName);
+			removeStack.push(this.prependFormFieldNames+shortName);
+			TBE_EDITOR.removeElementArray(removeStack);
 		}
 
 		var recordCount = this.memorizeRemoveRecord(
Index: D:/workspace-typo3/typo3/typo3_src-svn/t3lib/class.t3lib_tceforms_inline.php
===================================================================
--- D:/workspace-typo3/typo3/typo3_src-svn/t3lib/class.t3lib_tceforms_inline.php	(revision 2547)
+++ D:/workspace-typo3/typo3/typo3_src-svn/t3lib/class.t3lib_tceforms_inline.php	(working copy)
@@ -448,7 +448,7 @@
 	 */
 	function renderForeignRecordHeaderControl($parentUid, $foreign_table, $rec, $config = array()) {
 			// Initialize:
-		$cells=array();
+		$cells = array();
 		$isNewItem = substr($rec['uid'], 0, 3) == 'NEW';
 
 		$tcaTableCtrl =& $GLOBALS['TCA'][$foreign_table]['ctrl'];
@@ -473,6 +473,9 @@
 			// This expresses the edit permissions for this particular element:
 		$permsEdit = ($isPagesTable && ($localCalcPerms&2)) || (!$isPagesTable && ($calcPerms&16));
 
+			// Icon to visualize that a required field is nested in this inline level:
+		$cells[] = '<img id="'.$nameObjectFtId.'_req" src="clear.gif" width="10" height="10" hspace="4" vspace="3" alt="" />';
+
 			// "Info": (All records)
 		if (!$isNewItem)
 			$cells[]='<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$foreign_table.'\', \''.$rec['uid'].'\'); return false;').'">'.
Index: D:/workspace-typo3/typo3/typo3_src-svn/typo3/jsfunc.tbe_editor.js
===================================================================
--- D:/workspace-typo3/typo3/typo3_src-svn/typo3/jsfunc.tbe_editor.js	(revision 2547)
+++ D:/workspace-typo3/typo3/typo3_src-svn/typo3/jsfunc.tbe_editor.js	(working copy)
@@ -44,14 +44,15 @@
 					'requiredImg':	''
 				}
 			}
-		
 		},
 	*/
-	
+
 	elements: {},
+	nested: {'field':{}, 'level':{}},
+	ignoreElements: [],
 	recentUpdatedElements: {},
 	actionChecks: { submit:	[] },
-	
+
 	formname: '',
 	formnameUENC: '',
 	loadTime: 0,
@@ -62,10 +63,10 @@
 	prependFormFieldNames: 'data',
 	prependFormFieldNamesUENC: 'data',
 	prependFormFieldNamesCnt: 0,
-	
+
 	isPalettedoc: null,
 	doSaveFieldName: 0,
-	
+
 	labels: {},
 	images: {
 		req: new Image(),
@@ -79,15 +80,63 @@
 		TBE_EDITOR.recentUpdatedElements = elements;
 		TBE_EDITOR.elements = $H(TBE_EDITOR.elements).merge(elements);
 	},
+	addNested: function(elements) {
+		var name, nested, levelMax, i, currentLevel, subLevel;
+		// Merge data structures:
+		if (elements) {
+			for (name in elements) {
+				nested = elements[name];
+				if (nested.level && nested.level.length) {
+						// If the first level is of type 'inline', it could be created by a AJAX request to IRRE.
+						// So, try to get the upper levels this dynamic level is nested in:
+					if (nested.level[0][0]=='inline') {
+						nested.level = inline.findContinuedNestedLevel(nested.level, nested.level[0][1]);
+					}
+					levelMax = nested.level.length-1;
+					for (i=0; i<=levelMax; i++) {
+						currentLevel = TBE_EDITOR.getNestedLevelIdent(nested.level[i]);
+						if (typeof TBE_EDITOR.nested.level[currentLevel] == 'undefined') {
+							TBE_EDITOR.nested.level[currentLevel] = { 'clean': true, 'item': {}, 'sub': {} };
+						}
+							// Add next sub level to the current level:
+						if (i<levelMax) {
+							subLevel = TBE_EDITOR.getNestedLevelIdent(nested.level[i+1]);
+							TBE_EDITOR.nested.level[currentLevel].sub[subLevel] = true;
+							// Add the current item to the last level in nesting:
+						} else {
+							TBE_EDITOR.nested.level[currentLevel].item[name] = nested.parts;
+						}
+					}
+				}
+			}
+				// Merge the nested fields:
+			TBE_EDITOR.nested.field = $H(TBE_EDITOR.nested.field).merge(elements);
+		}
+	},
 	removeElement: function(record) {
 		if (TBE_EDITOR.elements && TBE_EDITOR.elements[record]) {
+			// Inform envolved levels the this record is removed and the missing requirements are resolved:
+			$H(TBE_EDITOR.elements[record]).each(
+				function(pair) {
+					TBE_EDITOR.notifyNested(record+'['+pair.key+']', true);
+				}
+			);
 			delete(TBE_EDITOR.elements[record]);
 		}
 	},
+	removeElementArray: function(removeStack) {
+		if (removeStack && removeStack.length) {
+			TBE_EDITOR.ignoreElements = removeStack;
+			for (var i=removeStack.length; i>=0; i--) {
+				TBE_EDITOR.removeElement(removeStack[i]);
+			}
+			TBE_EDITOR.ignoreElements = [];
+		}
+	},
 	getElement: function(record, field, type) {
 		var result = null;
 		var element;
-		
+
 		if (TBE_EDITOR.elements && TBE_EDITOR.elements[record] && TBE_EDITOR.elements[record][field]) {
 			element = TBE_EDITOR.elements[record][field];
 			if (type) {
@@ -96,22 +145,28 @@
 				result = element;
 			}
 		}
-		
+
 		return result;
 	},
 	checkElements: function(type, recentUpdated, record, field) {
 		var result = 1;
 		var elementName, elementData, elementRecord, elementField;
-		var source = recentUpdated ? TBE_EDITOR.recentUpdatedElements : TBE_EDITOR.elements;
+		var source = (recentUpdated ? TBE_EDITOR.recentUpdatedElements : TBE_EDITOR.elements);
 
+		if (TBE_EDITOR.ignoreElements.length && TBE_EDITOR.ignoreElements.indexOf(record)!=-1) {
+			return result;
+		}
+
 		if (type) {
 			if (record && field) {
 				elementName = record+'['+field+']';
 				elementData = TBE_EDITOR.getElement(record, field, type);
 				if (elementData) {
-					if (!TBE_EDITOR.checkElementByType(type, elementName, elementData)) result = 0;
+					if (!TBE_EDITOR.checkElementByType(type, elementName, elementData, recentUpdated)) {
+						result = 0;
+					}
 				}
-				
+
 			} else {
 				var elementFieldList, elRecIndex, elRecCnt, elFldIndex, elFldCnt;
 				var elementRecordList = $H(source).keys();
@@ -123,23 +178,47 @@
 						elementData = TBE_EDITOR.getElement(elementRecord, elementField, type);
 						if (elementData) {
 							elementName = elementRecord+'['+elementField+']';
-							if (!TBE_EDITOR.checkElementByType(type, elementName, elementData)) result = 0;
+							if (!TBE_EDITOR.checkElementByType(type, elementName, elementData, recentUpdated)) {
+								result = 0;
+							}
 						}
 					}
 				}
 			}
 		}
-		
+
 		return result;
 	},
-	checkElementByType: function(type, elementName, elementData) {
+	checkElementByType: function(type, elementName, elementData, autoNotify) {
 		var result = 1;
-		
+
 		if (type) {
 			if (type == 'required') {
 				if (!document[TBE_EDITOR.formname][elementName].value) {
-					result = 0;
-					TBE_EDITOR.setImage('req_'+elementData.requiredImg, TBE_EDITOR.images.req);
+					if (!elementData.requiredCond) {
+						result = 0;
+						if (autoNotify) {
+							TBE_EDITOR.setImage('req_'+elementData.requiredImg, TBE_EDITOR.images.req);
+							TBE_EDITOR.notifyNested(elementName, false);
+						}
+					}else {
+						var idx = 2+TBE_EDITOR.prependFormFieldNamesCnt;
+						var table = TBE_EDITOR.split(elementName, "[", idx);
+						var uid = TBE_EDITOR.split(elementName, "[", idx+1);
+									
+						table = table.substr(0,table.length-1);
+						uid = uid.substr(0,uid.length-1);
+						
+						var theRecord = TBE_EDITOR.prependFormFieldNames+'['+table+']['+uid+']';
+						if (TBE_EDITOR.checkCondition(theRecord,elementData.requiredCond)) {
+							var test = 0
+							result = 0;
+							if (autoNotify) {
+								TBE_EDITOR.setImage('req_'+elementData.requiredImg, TBE_EDITOR.images.req);
+								TBE_EDITOR.notifyNested(elementName, false);
+							}
+						}
+					}
 				}
 			} else if (type == 'range' && elementData.range) {
 				var formObj = document[TBE_EDITOR.formname][elementName+'_list'];
@@ -152,17 +231,131 @@
 				}
 				if (!TBE_EDITOR.checkRange(formObj, elementData.range[0], elementData.range[1])) {
 					result = 0;
-					TBE_EDITOR.setImage('req_'+elementData.rangeImg, TBE_EDITOR.images.req);
+					if (autoNotify) {
+						TBE_EDITOR.setImage('req_'+elementData.rangeImg, TBE_EDITOR.images.req);
+						TBE_EDITOR.notifyNested(elementName, false);
+					}
 				}
 			}
 		}
-		
+
 		return result;
 	},
+	// Checks one ore more conditions
+	checkCondition: function(theRecord,condition) {
+		var type = condition['type'];
+		var parameter = condition['parameter'];
+
+			// Checking a single Field
+		if (type == 'field') {
+			var elementNameCond = theRecord+'['+parameter['name']+']';
+			if (parameter['value'] == 1 || parameter['value'] == 0) {
+				if ((parameter['value'] && document[TBE_EDITOR.formname][elementNameCond].value) || (!parameter['value'] && !document[TBE_EDITOR.formname][elementNameCond].value)) {
+					return 1;
+				}
+			}else {
+				if (parameter['value'] == document[TBE_EDITOR.formname][elementNameCond].value) {
+					return 1;
+				}
+			}
+			// Checking a and-Array
+		}else if (type == 'and') {
+			for (var i = 0; i < parameter.size(); i++) {
+				if (!TBE_EDITOR.checkCondition(theRecord,parameter[i])) {
+					return 0;
+				}
+			}
+			return 1;
+			// Checking a or-Array
+		}else if (type == 'or') {
+			for (var i = 0; i < parameter.size(); i++) {
+				if (TBE_EDITOR.checkCondition(theRecord,parameter[i])) {
+					return 1;
+				}
+			}
+		}
+		return 0;
+	},
+	// Notify tabs and inline levels with nested requiredFields/requiredElements:
+	notifyNested: function(elementName, resolved) {
+		if (TBE_EDITOR.nested.field[elementName]) {
+			var i, nested, element, fieldLevels, fieldLevelIdent, nestedLevelType, nestedLevelName;
+			fieldLevels = TBE_EDITOR.nested.field[elementName].level;
+			TBE_EDITOR.nestedCache = {};
+
+			for (i=fieldLevels.length-1; i>=0; i--) {
+				nestedLevelType = fieldLevels[i][0];
+				nestedLevelName = fieldLevels[i][1];
+				fieldLevelIdent = TBE_EDITOR.getNestedLevelIdent(fieldLevels[i]);
+					// 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 {
+					continue;
+				}
+					// Set the icons:
+				if (resolved) {
+					if (TBE_EDITOR.checkNested(fieldLevelIdent)) {
+						TBE_EDITOR.setImage(element, TBE_EDITOR.images.clear);
+					} else {
+						break;
+					}
+				} else {
+					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);
+				}
+			}
+		}
+	},
+	// Check all the input fields on a given level of nesting - if only on is unfilled, the whole level is marked as required:
+	checkNested: function(nestedLevelIdent) {
+		var nestedLevel, isClean;
+		if (nestedLevelIdent && TBE_EDITOR.nested.level && TBE_EDITOR.nested.level[nestedLevelIdent]) {
+			nestedLevel = TBE_EDITOR.nested.level[nestedLevelIdent];
+			if (!nestedLevel.clean) {
+				if (typeof nestedLevel.item == 'object') {
+					$H(nestedLevel.item).each(
+						function(pair) {
+							if (isClean || typeof isClean == 'undefined') {
+								isClean = (
+									TBE_EDITOR.checkElements('required', false, pair.value[0], pair.value[1]) &&
+									TBE_EDITOR.checkElements('range', false, pair.value[0], pair.value[1])
+								);
+							}
+						}
+					);
+					if (typeof isClean != 'undefined' && !isClean) {
+						return false;
+					}
+				}
+				if (typeof nestedLevel.sub == 'object') {
+					$H(nestedLevel.sub).each(
+						function(pair) {
+							if (isClean || typeof isClean == 'undefined') {
+								isClean = TBE_EDITOR.checkNested(pair.key);
+							}
+						}
+					);
+					if (typeof isClean != 'undefined' && !isClean) {
+						return false;
+					}
+				}
+					// Store the result, that this level (the fields on this and the sub levels) are clean:
+				nestedLevel.clean = true;
+			}
+		}
+		return true;
+	},
+	getNestedLevelIdent: function(level) {
+		return level.join('::');
+	},
 	addActionChecks: function(type, checks) {
 		TBE_EDITOR.actionChecks[type].push(checks);
 	},
-	
 	// Regular TCEforms JSbottom scripts:
 	loginRefreshed: function() {
 		var date = new Date();
@@ -213,18 +406,30 @@
 		if (TBE_EDITOR.getElement(theRecord,field,'required') && document[TBE_EDITOR.formname][theField])	{
 			if (TBE_EDITOR.checkElements('required', false, theRecord, field)) {
 				TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.clear);
+				TBE_EDITOR.notifyNested(theField, true);
 			} else {
 				TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.req);
+				TBE_EDITOR.notifyNested(theField, false);
 			}
 		}
 		if (TBE_EDITOR.getElement(theRecord,field,'range') && document[TBE_EDITOR.formname][theField]) {
 			if (TBE_EDITOR.checkElements('range', false, theRecord, field))	{
 				TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.clear);
+				TBE_EDITOR.notifyNested(theField, true);
 			} else {
 				TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.req);
+				TBE_EDITOR.notifyNested(theField, false);
 			}
 		}
+			// Activate trigger
+		if (TBE_EDITOR.getElement(theRecord,field,'trigger') && document[TBE_EDITOR.formname][theField]) {
+			var condElement = TBE_EDITOR.getElement(theRecord,field,'trigger');
+			for (var i = 0; i < condElement['trigger'].size(); i++) {
+				TBE_EDITOR.fieldChanged(table,uid,condElement['trigger'][i],el);
+			}
+		}
 		
+
 		if (TBE_EDITOR.isPalettedoc) { TBE_EDITOR.setOriginalFormFieldValue(theField) };
 	},
 	setOriginalFormFieldValue: function(theField) {
@@ -274,7 +479,7 @@
 		if (!TBE_EDITOR.checkElements('required', false)) { OK = 0; }
 		// $reqRangeCheck
 		if (!TBE_EDITOR.checkElements('range', false)) { OK = 0; }
-				
+
 		if (OK || sendAlert==-1) {
 			return true;
 		} else {
@@ -297,7 +502,13 @@
 		TBE_EDITOR.checkElements('range', true);
 	},
 	setImage: function(name,image) {
+		var object;
 		if (document[name]) {
+			object = document[name];
+		} else if (document.getElementById(name)) {
+			object = document.getElementById(name);
+		}
+		if (object) {
 			if (typeof image == 'object') {
 				document[name].src = image.src;
 			} else {
Index: D:/workspace-typo3/typo3/typo3_src-svn/typo3/template.php
===================================================================
--- D:/workspace-typo3/typo3/typo3_src-svn/typo3/template.php	(revision 2547)
+++ D:/workspace-typo3/typo3/typo3_src-svn/typo3/template.php	(working copy)
@@ -1707,6 +1707,7 @@
 				$isActive = strcmp($def['content'],'');
 
 				$mouseOverOut = ' onmouseover="DTM_mouseOver(this);" onmouseout="DTM_mouseOut(this);"';
+				$requiredIcon = '<img id="'.$id.'-'.$index.'-REQ" src="clear.gif" width="10" height="10" hspace="4" alt="" />';
 
 				if (!$foldout)	{
 						// Create TAB cell:
@@ -1715,6 +1716,7 @@
 							($isActive ? '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>' : '').
 							$def['icon'].
 							($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
+							$requiredIcon.
 							$this->icons($def['stateIcon'],'margin-left: 10px;').
 							($isActive ? '</a>' :'').
 							'</td>';
@@ -1726,6 +1728,7 @@
 							($isActive ? '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>' : '').
 							$def['icon'].
 							($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
+							$requiredIcon.
 							($isActive ? '</a>' : '').
 							'</div>';
 				}
