Translations
Info
All page names need to be in English.
en da  de  fr  it  ja  km  nl  ru  zh

Form Structure for TYPO3 4.3

From TYPO3Wiki
Jump to: navigation, search

Form Syntax

Current syntax

The current syntax for form definition with the FORM cObj is something like this:

Title | *title=select | Mr,Mrs,Ms
Name | *name=input

Each line represents a form field. They are separated either by a line break or by a double pipe character (||). Parameters for each form field are separated by a single pipe character (|). The number and type of parameters depend on the field type.

Extending the syntax

Form structure

In my eyes the most critical missing piece is a possibility to give structure to the form, by grouping fields together in a nested structure. Whether the depth of this structure should be unlimited or predefined is a matter for debate.

To start the discussion, I am proposing to introduce three levels: sections, groups and rows. The syntax could look like this (indentation added for clarity):

---section---|Personal information
    ---group---
        ---row---
            Gender | gender=radio | Male=M,Female=F
            Last name | lastname=input,20
            First name | firstname=input,20
    ---group---
        ---row---
            Address | address=textarea,50,3
        ---row---
            Zip code | zip=input,6
            City | city=input,25
            Country | country=input,15
    ---group---
---section---|What you say
    ---group---
        ---row---
            Address | address=textarea,50,3
---section---
    ---group---
        ---row---
            Validate | validate=submit
            Reset | clear=reset
Give some TypoScript configuration, the resulting HTML could look something like that:
TS TypoScript:
<div class="allWrap">
	<form name="testForm">
		<fieldset class="sectionWrap">
			<legend>Personal information</legend>
			<div class="groupWrap">
				<div class="rowWrap">
					<ol>
						<li>
							<label>Gender</label>
							<ol>
								<li><input type="radio" name="gender" id="genderF" value="F" /><label for="genderF">Female</label></li>
								<li><input type="radio" name="gender" id="genderM" value="M" /><label for="genderM">Male</label></li>
							</ol>
						</li>
						<li><label for="lastname">Last name</label><input type="text" name="lastname" id="lastname" size="20" /></li>
						<li><label for="firstname">First name</label><input type="text" name="firstname" id="firstname" size="20" /></li>
					</ol>
				</div>
			</div>
			<div class="groupWrap">
				<div class="rowWrap">
					<ol>
						<li><label for="address">Address</label><textarea name="address" id="address" rows="3" cols="50"></textarea></li>
					</ol>
				</div>
				<div class="rowWrap">
					<ol>
						<li><label for="zip">Zip code</label><input type="text" name="zip" id="zip" size="6" /></li>
						<li><label for="city">City</label><input type="text" name="city" id="city" size="25" /></li>
						<li><label for="country">Country</label><input type="text" name="country" id="country" size="15" /></li>
					</ol>
				</div>
			</div>
		</fieldset>
		<fieldset class="sectionWrap">
			<legend>What you say</legend>
			<div class="groupWrap">
				<div class="rowWrap">
					<ol>
						<li><label for="comments">Comments</label><textarea name="comments" id="comments" rows="3" cols="50"></textarea></li>
					</ol>
				</div>
			</div>
		</fieldset>
		<fieldset class="sectionWrap">
			<div class="groupWrap">
				<div class="rowWrap">
					<ol>
						<li><input type="submit" name="submit" value="Validate" /></li>
						<li><input type="reset" name="reset" value="Reset" /></li>
					</ol>
				</div>
			</div>
		</fieldset>
	</form>
</div>

Such a structure allows for interesting variations by just changing the CSS. Here are 2 examples, with background colors to highlight the various structural elements.

Example form 1-v2.png

This corresponds to the following
CSS styles:
* {
	font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
	font-size: 12px;
}
form legend {
	font-size: 16px;
	font-weight: bold;
}
form ol {
	list-style: none;
	margin: 0px;
	padding: 0px;
}
form ol li {
	float: left;
	padding: 4px;
}
form label {
	display: block;
	font-weight: bold;
}
form ol ol label {
	display: inline;
	font-weight: normal;
}
.rowWrap {
	background-color: #ffdcb0;
	float: left;
	clear: both;
	border: 1px solid #ff3fcb;
	margin-bottom: 2px;
}
.groupWrap {
	background-color: #baffb9;
	padding: 8px;
	float: left;
	clear: both;
	border: 1px solid #0bb124;
	margin-bottom: 4px;
}
.sectionWrap {
	background-color: #b2e3fd;
	padding: 8px;
	float: left;
	clear: both;
	border: 1px solid #603bc9;
	margin-bottom: 8px;
}

With just a small change (namely removing clear: both; from .groupWrap and adding a little right margin, the form becomes:

Example form 2-v2.png

Discussion points

The above is an example given to foster discussion. Maybe the proposed syntax is ridiculous, but the principle should be discussed. I think having levels of grouping would be a real boon. Then with some TypoScript any level of grouping could be rendered as one wishes. One open question is "How many levels of grouping appear necessary?":

  1. should it be a fixed number?
  2. should it be unlimited?

I think the first option is better, because the second one is too open and unnecessarily complicated. But if going for the first option, the number and significance of each level should be defined (as in the example, the groupings are "row", "group", "section"; maybe there's a need for "page" too?).

Helper libraries

As a proof of concept (but used in an actual project, in a early stage), I have started developing some helper classes to generate forms for the FE as a FORM cObj, rather than using such stuff as fe_adminLib.inc (yes I know, it does more than just displaying forms).

This is packaged in an extension called "advancedform" which I have released to the TER as experimental to foster discussion. It is also available on typo3xdev [1].

Form builder

Class tx_advancedform_formelements contains methods to generate the various types of fields. It becomes easy to generate FORM syntax with the help of this class. Example for a hidden field:
PHP script:
$formHelper = t3lib_div::makeInstance('tx_advancedform_formelements');
	// Define wrapper for field names
$formHelper->setPrefix('tx_myext_pi1');
$formStructure = '';
$formStructure .= $formHelper->addHidden('viewType', 'run');
...

Note the idea of being able to set a prefix so that form fields have the proper syntax for being taken up as piVars when submitting the form to a page containing the corresponding FE plugin.

TCA converter

Obviously we already have a structure that defines form fields, it's the TCA. It would be extremely convenient to be able to transform the TCA information to FORM syntax. Class tx_advancedform_tcatoforms does this, although it is far from complete yet.

The example code below extracts information from a FlexForm and transforms it to FORM syntax by a simple call to class tx_advancedform_tcatoforms:
PHP script:
$dataStructureArray = t3lib_BEfunc::getFlexFormDS($GLOBALS['TCA']['tx_myext_pi1']['columns']['formdata']['config'], array(), 'tx_myext_pi1');
$sheet = $dataStructureArray['sheets']['sDEF']['ROOT'];

	// Get object to transform TCA data to FORM definition
$tcaConverter = t3lib_div::makeInstance('tx_advancedform_tcatoforms');

	// Convert TCEforms info to FORM cObj info
$formStructure = '';
foreach ($sheet['el'] as $field => $fieldData) {
	$formStructure .= $tcaConverter->columnToForm($field, $fieldData['TCEforms']);
}

Trying to transform all possible TCA options to FORM syntax may not be necessary, but it does show the limitations of the current FORM syntax, in particular in terms of validation options.