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

Formidable

From TYPO3Wiki
(Redirected from Formidable documentation)
Jump to: navigation, search

<< Back to Extension manuals page

[edit]

This page belongs to the FORM cObj and RAD with TYPO3 project (category Project)

Author: Jerome Schneider (typo3dev@ameos.com)
Extension key: ameos_formidable
Document status: draft
Major revision: TER 0.8.0
Minor revision: See page's Last modified date
Prerequisites:

notice - Open Content License

This document is published under the Open Content License

The content is related to TYPO3 - a GNU/GPL CMS/Framework available from typo3.org


notice - Draft

Change the {{draft}} marker to {{review}} when you need a reviewer for text and TypoScript. info

warning - Message

Formidable has a new home for all it's related stuff: http://formidable.typo3.ug
Documentation will still stay on this wiki page, though

Contents

Introduction

This document presents the API ameos_formidable

Home page of the project: http://formidable.typo3.ug

FORMidable is a development framework used to create applications where business-logic is separated from the design and from the PHP-code.

It's configured in XML. So basically, you create a plugin, create an XML configuration file, call the FORMidable in your plugin giving XML file path as parameter and the API executes what you configured. And you're done.

It heavily relies on default behaviors so the conf can be really short. But you can also customize every single feature if you need tailor made application.

Extensions using formidable: see search-results in TER

What you can do with FORMidable

Mainly automated forms for your website.

But what is an application, concretely ? Well:

  • Flexible design, textfields, formfields, and much more
  • Links, buttons, composite formfields, events to interact with the user
  • Data management (create, update, delete ), data browsing, data searching, ...


The point is that every web application is based on this stuff. FORMidable can (loves) handle this for you.


Screenshots

  • Simple creation form

(here, fe_user account creation)

Formidable-Documentation-Shot-1.png


  • Simple form, edition mode

Formidable-Documentation-Shot-2.png

  • Highly customized forms and search forms

Formidable-Documentation-Shot-3.png

  • Search + list of matching records

Formidable-Documentation-Shot-4.png

  • Details of a record

Formidable-Documentation-Shot-5.png

  • Anything else with links, buttons, images, textfields, ...

Formidable-Documentation-Shot-6.png


How does it work ?

An application is entirely described in an XML file. This conf defines a lot of subsections, to configure all the elements that make your application work.

Namely:

  • renderlets: objects that will be displayed in your application ( text field, listbox, link, image, button, ... )
  • validators: objects checking if the data returned by a renderlet is valid, or not ( required, email, unique in db, ... )
  • renderer: one per application ; will process the HTML provided by renderlets ( dev layout, templated layout, ... )
  • datahandler: one per application; will execute something with produced data ( insert in base, send mail, search in database, ... )
  • actionlets: objects that will be executed when datahandler finishes it's job ( redirect to a page, send an email to someone, generate a report, ... )


As said before, FORMidable needs XML as a configuration. Let's see what's inside this XML.

Integration of FORMidable in my plugin

Before you can use FORMidable in your plugin you must include the Formidable API. In your plugin php-file, just before the class declaration, add:

PHP script:
require_once(PATH_formidableapi);

To use FORMidable in your code, you have to create a FORMidable object and to initialize it with some arguments:

  • $this (always) : this parameter will be used to keep the reference to your plugin inside FORMidable
  • path to your xml file
  • uid of the record to edit, (optional, only if you want FORMidable to edit this record)
PHP script:
    $this->oForm = t3lib_div::makeInstance("tx_ameosformidable");
    $this->oForm->init(
        $this,
        t3lib_extmgm::extPath($this->extKey) . "xml/form1.xml",
        25    // uid of the record to edit ( if edition needed ;)
    );
And then you have to get the generated HTML by calling the render() method of this object.
PHP script:
    $sHtml = $this->oForm->render();

And you're done !

Quick FORMidable:XML syntax

A typical XML looks like this


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<formidable version="0.8.0"
	xmlns:datahandler="http://www.ameos.com/formidable/080/datahandler"
	xmlns:datasource="http://www.ameos.com/formidable/080/datasource"
	xmlns:renderer="http://www.ameos.com/formidable/080/renderer"
	xmlns:renderlet="http://www.ameos.com/formidable/080/renderlet"
	xmlns:validator="http://www.ameos.com/formidable/080/validator"
	xmlns:actionlet="http://www.ameos.com/formidable/080/actionlet">
	<meta>
		<name>Create/edit an FE user</name>
		<form formid="myuserform"/>
		<debug>true</debug>
		<displaylabels>true</displaylabels>
        </meta>
        <control>
		<datahandler:DB>
			<tablename>fe_users</tablename>
			<keyname>uid</keyname>
		</datahandler:DB>
		<renderer:STANDARD/>
	</control>
	<elements>
		<renderlet:TEXT name="username" label="User name"/>
		<renderlet:PASSWORD name="password" label="Password"/>
		<renderlet:SUBMIT label="Submit"/>
	</elements>
</formidable>

There are always 3 main sections in the XML ( 4 with the root ) . Each one of these 3 sections is required.

1 meta: global informations about the whole applications

2 control: holds the configuration for the datahandler (required), renderer (required) and actionlets (optional)

3 elements: section containing the renderlets

Each tag defining any renderlet / validator / renderer / datahandler / actionlet has to be declared as a part of the corresponding namespace ( renderlet:LISTBOX ; datahandler:DB ; renderer:TEMPLATE ; ... ). The second part of those tags, after the colon, defines the type of this tag, inside the namespace.

Each tag must be defined in lowercase, except for types of objects inside namespaces ( renderlet:LISTBOX, datahandler:RAW, ... ). What is called a boolean in the following XML REF is a string “true” or “false”, lowercased. What is called userobj is a tag that defines either:

  • a callback to a PHP function inside an object
  • a section on PHP code to execute inside a CDATA tag, returning something or not
  • a section of TypoScript inside a CDATA tag.

Userobj are optional in most of the cases ; they give the ability to the developper to feed it's application with dynamically generated values rather than static XML ones.

XML REF

Renderlets

TODO

* added overrideSql method
* added _translatable() and i18n_shouldNotTranslate()
* added (experimental) support for custom and labelcustom on /data/items/item
* added support for programmaticaly defined events with initProgEvents()
* added support fo programatically defined server event in _hasThrown()
* added mode "orlike" in overrideSql() for searching with OR comparisons between words in a field
* /search/onfields is now userobjable in overrideSql(), thanx to Manuel Rego Casasnovas ; see lists.typo3.org/pipermail/typo3-project-formidable/2007-June/000502.html
* childs initialization has been moved to method initChilds(), for childs re-init after renderlet init() if needed
* added mecanism for re-initalization of childs before rendering, for fresh display when displaying modalbox
* _getAjaxEvent(): added support for new namespace of event parameters rowInput::
* _getElementHtmlId(): adds a suffix to html id for repeated inputs (usefull for new params rowInput::)
* renderChildsBag() is now able to render templates on childs with /childs/template
* added /childs/autowrap=boolean ; allows to wrap child elements in default tag structure if no template for childs is provided
* _parseTemplateCode() is now able to substitute subparts like <!-- ###myrenderlet### begin--> ... <!-- ###myrenderlet### end--> instead of {myrenderlet} to allow templating childs in main template using subparts
* childs are now wrapped in <div class="formidable-rdrstd-rdtwrap">|</div> in default rendering (without template on childs)
* added the new concept of checkpoints
* added .label.tag to all renderlets, containing <label for="...">mylabel</label>


NEW rdt_i18n
  * automatically handles translated records factorisation in lists with typoscript processed country flags
  * can be fully customized with recombine
  * added config to be able to change default flag icons / labels
  * now automaticaly forced to renderOnly to avoid bugs in lister when working on a compiled table
  * completely changed the internal way of handling automated events generation on rdt_i18n language flags, by using the new notion of programmaticaly defined events
  * now values that don't correspond to a renderlet also are updated into sys_language childs when replicating changes on childs for non-translatable records of default-language


NEW rdt_modalbox
  * Removed param $sHtml in function majixShowBox	
  * added mecanism for re-initalization of childs before rendering, for fresh display when displaying modalbox
  * added a call to oDataHandler->refreshAllData() in majixShowBox(), for fresh data before rendering

NEW rdt_tinymce
  * added support for EXT:my_ext_key like path in contentCss property
  * can now give additional external config with /addconfig

NEW rdt_upload
  * added complete rewrite of file upload
  * takes as arguments
    <data
        targetdir="C:/Program Files/TYPO3_4.1.1/htdocs/Quickstart/uploads/"
        overwrite="true/false"
        cleanfilename="true/false"
        multiple="true/false"
    />
  * added {myrdt.filelist.ul} template channel
  * getServerPath() now allows to pass a filename as parameter

NEW rdt_box
  * added rdt_box
  * rdt_box is now default true on activelistable
  * {LLL:EXT:...} tags are now substituted in html property of the box
  * renderChildsBag() is now able to render templates on childs with /childs/template
  * _parseTemplateCode() is now able to substitute subparts like <!-- ###myrenderlet### begin--> ... <!-- ###myrenderlet### end--> instead of {myrenderlet} to allow templating childs in main template using subparts
  * added /childs/autowrap=boolean ; allows to wrap child elements in default tag structure if no template for childs is provided

NEW rdt_lister
  * creation of the brand new concept of renderlet-based list
  * lot easier to set-up
  * several listers can be used in the same xml file
  * completely useable without javascript
  * lot of work on accessibility, uses GET urls to trigger sorts and page navigation
  * can be cached by typo3, if used in a USER ( not USER_INT ) plugin, and property /cachehash="true"
  * can be interfaced with a renderlet:SEARCHFORM or directly to a datasource ( typically datasource:DB )
  * some behaviors known in datahandler:LISTER have been ported, some will be, some have been modified
  * great care has been accorded to improve performance thru usage of references in internal jobs, and by complete rewrite of the DATA engine
  * added french translation for list actions on sort/browse
  * list recursivity possible
  * activelistable is now default TRUE, to allow lister recursivity
  * now supports /process on columns, to allow disabling a column on some condition
  * renderonly is now always TRUE

NEW rdt_searchform
  * creation of the brand new concept of renderlet-based searchform
  * multiple searchforms can now be used simultaneously in the same xml file
  * acts as a filter between renderlet:LISTER and datasource:DB

renderlet:*

This conf applies to all renderlets. Some renderlets might redefine default values for these properties, though.

Property Data type Description Default Advice
/name string [a-zA-Z0-9_-]

Name and id of the field in the form.

Name of the corresponding column in the database, also.

If none given, an anonymous name will be automatically generated.

You have to give a name if you want to be able to place the HTML produced by this renderlet into an HTML template ( if you don't know the name, you can't use its tag in the template )

random anonymous Always give a name unless YNWYD.

/label

string, <userobj>

Label of the field which will be displayed in your application


You can give here also a locallang formated string for localization, like LLL:EXT:........


See <control>/displaylabels


empty string

Always try to use LLL:EXT localized strings

/readonly

boolean, <userobj>

Whether or not to allow modifications on this field.



If true, default behavior is to display the human-readable value of this renderlet.


false


/renderonly

boolean, <userobj>

Whether or not to consider data produced by this formfield in the datahandler.


More specifically, means should FORMidable insert / update this field in the DB if used with datahandler:DB, or filter results on this column/value when used for searching records with the datahandler:LISTER.

false

Useful when the renderlet value is not meant to be inserted in the database, for instance a formfield used only to build the interface.

/type

string

This property is a system property. It's automatically set to the type of the renderlet declared in the <renderlet:XYZ> tag, where here type would be set to XYZ.


You don't have to declare it, but if you need to, you can modify it at runtime using modifiers.


See modifiers, xml pre-compilation.

renderlet type inside the namespace, lowercased


/custom

string, <userobj>

This property is a placeholder where you can place anything you want to be inserted in the HTML of the renderlet.


Typically, this will be inserted in the HTML tag of the renderlet;


for instance,


<custom>class=”red”</custom>

will be, for a renderlet:TEXT HTML, used like this:


<input type='text” class=”red” ....>

empty string


/wrap

string, <userobj>

Works like the typoscript .wrap property.


You can append parts of HTML before and after the render of your renderlet using this wrap.


|

If used with renderer:TEMPLATE, you can use template tags inside the wrap if needed :)

/process

boolean, <userobj>

This boolean will give you the possibility to tell FORMidable not to evaluate this renderlet at runtime, meaning that you will be able to use complex tests to determine if the application should or not consider this field.

true

Useful when you can't use modifiers because needed informations about whether or not to use this renderlet are not available at pre-compilation time

/recombine

<userobj> TS

This tag allows user to give a TS template that will be used to generate the graphical layout of this renderlet.


The TS template can use an automatically generated params property that will holds all the distinct HTML parts of this renderlet

	<recombine>
	    <userobj>
		<ts><![CDATA[
	  10 = COA
	  10 {

	    5 = TEXT
	    5.value < params.label
	    5.wrap = <div>|</div>
	    
	    10 = TEXT
	    10.value < params.input
	    10.wrap = <div class='myclass'>|</div>
	  }
	     ]]>

</userobj> </recombine> </TS>


See multichannel-template for more informations about what's available in the params property.

empty

REALLY powerful if you need tailor-made graph layout for your application.

/activelistable

boolean, <userobj>

If true and if used with datahandler:LISTER, the renderlet will be displayed as a fully functional form field in the list.


If false and used with datahandler:LISTER, the renderlet will be displayed as a human-readable readonly value in the list.

false

Set to true on renderlet LINK, BUTTON, ... if you want them to be displayed as active links or button in your list ;

/data

XML subconf

This tag is the placeholder of all configuration that deals with available data, defaultvalue of the renderlet, available items for listboxes, checkboxes groups, ...

empty


/data/defaultvalue

string, <userobj>

Defines the default value for this renderlet.


If set, it will be used only when the form has not been already submitted ( first display ) and when in creation mode ( not edition mode )


See value / default value management

empty


/data/value

string, <userobj>

Defines the value for this renderlet.


If set, the renderlet will allways use what's returned by /data/value as a value, no matter what the user give in the form field

empty


/data/items

XML subconf

Placeholder for the collection of items that will be used by the renderlet.


Items are typically the items of a listbox, radiobuttons group or checkboxes group.


You can dynamically give an array of items to the renderlet using a <userobj> tag defined at /data/userobj. If userobjed, returned value must be an array structured like:

	Array(
	   Array("caption" => "Item 1", "value" => "1"),
	   Array("caption" => "Item 2", "value" => "2"),
	   Array("caption" => "Item 3", "value" => "3"),
	)

See /data/items/item

empty

Makes sense only when the renderlet has to deal with a collection of items

/data/items/item

XML subconf

Placeholder for an item in the collection


See /data/items/item/caption and /data/items/item/value



/data/items/item/caption

string, <userobj>

Defines the caption of this item. Can be a LLL:EXT locallang string.

empty string


/data/items/item/value

string, <userobj>

Defines the value of this item.

empty string


/search

XML subconf

Useful only when used with datahandler:LISTER


Placeholder for configuring a specific way for the LISTER to search inside the database for this value.


Default search is:


if value not empty: rdt_name LIKE '%rdt_value%'

empty


/search/overridesql

string, <userobj>

Redefines the portion of SQL given by this renderlet to the datahandler:LISTER to override the default LIKE search


Example: You would like the search results to be filtered on some criteria if our checkbox renderlet is checked in the searchform ; do something like this:

	<renderlet:CHECKSINGLE
	 name="xmasspecific"
	 label="Display only Xmas specific items">
	    <onclick submit="true"/>
	    <search>
		<overridesql>
		    <userobj>
			<php><![CDATA[
			
  return "(xmasflag=1 OR (santaflag=1 AND eventdate='" . strftime("%Y") . "-12-25'))";

			]]></php>
		    </userobj>
		</overridesql>
	    </search>
	</renderlet:CHECKSINGLE>

/search/mode

string

One of startswith, googlelike


startswith: search only records within this column starting with value


googlelike: search words like value records with AND logic and full string if surrounded by quotes

empty

Use the renderlet:CHOOSER with this to have a nice alphabetical-hash selector

/search/onfields

string

Comma-separated list of columns to search on in the database

empty


/onclick, /onmouseover, /on...

string, <userobj>

Client & Server Events handling.


See section “Events” for more informations

empty


/validators

XML subconf

Placeholder for the collection of validators for this renderlet. See the section Validators for more informations



/confirm

string

Enter the name of an other renderlet if you want a field to confirm the value of another field. Typically used for password validation.



Examples

Note: screenshots of these examples are made using renderer:STANDARD

Plain renderlet:

    <renderlet:TEXT>
        <name>favcolor</name>
        <label>Favourite color</label>
    </renderlet:TEXT>

Which is equivalent to (always prefer this one ;) :

    <renderlet:TEXT name="favcolor" label="Favourite color"/>

This renders as:

Formidable-Documentation-Example-1.png

Renderlet with defaultvalue, custom & wrap

	<renderlet:TEXT name="favcolor" label="Favourite color">
	    <custom>style="background-color: yellow; border: 4px orange dashed;"</custom>
	    <data defaultvalue="red"/>
	    <wrap><![CDATA[

		<div style="background-color: pink;">This will be place before my textbox</div>
		<div style="margin: 10px; background-color: cornflowerblue">|</div>
		<div style="background-color: tomato;">And this, after. Thank you Mr. Wrap !</div>    

	    ]]></wrap>
	</renderlet:TEXT>

Renders as:

Formidable-Documentation-Example-2.png


Using userobj for defaultvalue and label

	<renderlet:TEXT name="favcolor">
	    <label>
		<userobj>
		    <php><![CDATA[

		$sTime = strftime("%H:%M:%S");
		return "It's " . $sTime . " already ! Time to tell us your favorite color!";


		    ]]></php>
		</userobj>
	    </label>
	    <custom>style="background-color: yellow; border: 4px orange dashed"</custom>
	    <data>
		<defaultvalue>
		    <userobj>
			<php><![CDATA[

		$aColors = array(
		    "red",
		    "blue",
		    "green",
		    "purple",
		);

		return $aColors[array_rand($aColors)];

			]]></php>
		    </userobj>
		</defaultvalue>
	    </data>
	    <wrap><![CDATA[

		<div style="background-color: pink;">This will be place before my textbox</div>
		<div style="margin: 10px; background-color: cornflowerblue">|</div>
		<div style="background-color: tomato;">And this, after. Thank you Mr. Wrap !</div>    

	    ]]></wrap>
	</renderlet:TEXT>

Renders as:

Formidable-Documentation-Example-3.png


$this->_oParent usage in userobj (from mail-list)

The trick is that you have access to your plugin in formidable. When in a userobj, $this->_oParent refers to your plugin

So you can set, in your plugin, before calling formidable:

$this->toto = "Hello, World !";

and in formidable, in the userobj where you need it:

echo($this->_oParent->toto); // or whatever php here

Using recombine

Note: Recombine deactivates the wrap, so we dont use wrap here, only TS template

We give here only the <recombine> tag for this example. To get the full example XML for this renderlet, replace the <wrap> tag in the previous example with this <recombine> tag.
TS TypoScript:
	<recombine>
	    <userobj>
		<ts><![CDATA[

	10 = COA
	10 {
		10 = TEXT
		10.value < params.input
		10.wrap (
			This is processed by a Typoscript template :)<br />
			<div style="background-color: red;">|</div>
		)

		20 = TEXT
		20.value < params.label
		20.wrap (
		    <div>
		      The label of this renderlet is: <b style="background-color: black; color: white;">|</b>
		      <br />
		      <div>Can you figure out the possibilities ?</div>
		    </div>
		)

		30 = TEXT
		30.value < params.help
		30.wrap (
		   <div style="background-color: silver;">
		     This is an array of the available HTML-channels properties for a TEXT renderlet.<br />
		     |
		     <i>See Documentation at <b>Multichannel Templates</b> for more informations</i>
		   </div>
		)
	}

	10.wrap (
		<div style="background-color: pink; padding: 10px;">
			Everything inside this pink box is the render of the renderlet:TEXT<br />
			|
		</div>
	)
		]]>

</userobj> </recombine> </TS>

Renders as:

Formidable-Documentation-Example-4.png

renderlet:TEXT

No special conf. See renderlet:*


renderlet:TEXTAREA

TODO
render(): added template channels
  .value.nl2br
  .value.htmlspecialchars
  .value.htmlspecialchars.nl2br

No special conf. See renderlet:*

Renders as:

Formidable-Documentation-Example-5.png

renderlet:PASSWORD

No special conf. See renderlet:*

Renders as:

Formidable-Documentation-Example-6.png

renderlet:DATE

TODO

* added userobj support in date format for internationalization, cf. [TYPO3-project-formidable] "Internationalize date format" message of Manuel Rego Casasnovas
* /data/datetime/displaytime is now default FALSE
* /allowmanualedition is now deprecated by /data/datetime/allowmanualedition
* /data/datetime/allowmanualedition is now default FALSE
* added the %@ date format token in js, which returns the absolute timestamp of the selected day at 00:00:00
* added it's own js class for specialization of majixReplaceData()
* added /data/datetime/emptystring configuring the text to display when no date selected with allowmanualedition="false"
* calendar icon displays before field
* modified the way UTC timestamp at midnight is generated
* corrected polish translations thanks to Pawel Bandura (http://lists.typo3.org/pipermail/typo3-project-formidable/2007-July/000621.html)

All configuration specific to this renderlet is found in /data/datetime/

This renderlet is designed to handle timestamps. It takes timestamp as an input, and returns timestamp as a value, plus human readable date as an HTML output.

Property

Data type

Description

Default

Advice

/data/datetime/format

strftime() string

Strftime like string used to customize the display of the date. See http://www.php.net/strftime

required


/data/datetime/locale

LOCALE string

Locale code string to localize the date display See http://www.php.net/setlocale

system LOCALE


/data/datetime/displaytime/

boolean

Whether or not to display the time selector in the js-calendar.

false


Examples

Plain renderlet:DATE

	<renderlet:DATE name="birthdate" label="Birth date">
		<data>
			<datetime format="%m/%d/%Y"/>
		</data>
	</renderlet:DATE>

Renders as:

Formidable-Documentation-Example-7.png


Renderlet:DATE with time selector, userobj'd defaultvalue and custom property

	<renderlet:DATE name="birthdate" label="Birth date">
		<custom>style='width: 200px;'</custom>
		<data>
			<datetime format="The date is %m-%d-%Y %H:%M:%S" displaytime="true"/>
			<defaultvalue>
				<userobj>
					<php><![CDATA[   return mktime(13, 45, 23, 1, 1, 1998);   ]]></php>
				</userobj>
			</defaultvalue>
		</data>
	</renderlet:DATE>

Renders as:


Formidable-Documentation-Example-8.png

renderlet:FILE

* added /linktofile=boolean, default true
* /data/targetdir is now userobj'able thanks to manuel rego casasnovas ; see lists.typo3.org/pipermail/typo3-project-formidable/2007-June/000432.html

Property:

Data type:

Description:

Default:

Advice

/data/targetdir

string

path to the directory where files will be uploaded, relative to the root path of the site;


Typically: typo3temp/tx_myext_pi1/

required

Note: uploaded file will be stored in the /data/targetdir/ directory. If filename already exists, it will be automatically renamed, suffixed with _(number) (look at the examples)

Examples

Plain renderlet:FILE

	<renderlet:FILE name="photo" label="Upload your photo">
		<data targetdir="typo3temp/"/>
	</renderlet:FILE>

Renders as:


Formidable-Documentation-Example-9.png

Here, this file has been uploaded 8 times in the same folder, so it was suffixed _7. The link points to the file.

renderlet:UPLOAD

Similar to renderlet:FILE, but offers more possibilities in file handling.

Property:

Data type:

Description:

Default:

Advice

/data/targetdir

string

path to the directory where files will be uploaded, relative to the root path of the site;


Typically: typo3temp/tx_myext_pi1/

required

/data/overwrite

boolean

Overwrite if file exists or rename it

false

/data/cleanfilename

boolean

Clean file name if weird chars are found

false

/data/multiple

boolean

allow field to contain multiple files, comma-separated value

false

Examples

Plain renderlet:UPLOAD

	<renderlet:UPLOAD name="photo" label="Upload your photo">
		<data targetdir="typo3temp/" /> 
	</renderlet:UPLOAD>

renderlet:LISTBOX, renderlet:CHECKBOX, renderlet:RADIOBUTTON

TODO

renderlet:LISTBOX
* added call to overrideSql in sql build
* implemented multiple listbox ability with /multiple=true/false thanks to Manuel Rego Casanovas (lists.typo3.org/pipermail/typo3-project-formidable/2007-May/000308.html)
* modified majixReplaceData() to be able to use either caption/value item arrays or more concise key=>value item arrays
* majixSetAllSelected() for listbox multiple="true"
* render(): added .value and .caption template channels

These renderlets use a collection of items to do their job. Items can be preceded with an empty value with addBlank.

<renderlet:LISTBOX name="listcity" label="ville" addBlank="--Mylist Item --" />

compare: http://lists.typo3.org/pipermail/typo3-project-formidable/2010-January/001830.html

Property

Data type

Description

Default

Advice

/data/items

XML subconf

See renderlet:*/data/items

required

See renderlet:*/data/items

renderlet:CHECKBOX returns a list of selected items values comma-separated as data.

Examples

Plain renderlet:LISTBOX

	<renderlet:LISTBOX name="myexgirlfriends" label="My ex girlfriends">
		<data>
			<items>
				<item caption="" value=""/>
				<item caption="Laetitia" value="laetitia"/>
				<item caption="Pamela" value="pamela"/>
				<item caption="Juddy" value="juddy"/>
			</items>
		</data>
	</renderlet:LISTBOX>

Renders as:

Formidable-Documentation-Example-10.png

renderlet:LISTBOX using defaultvalue and userobj'd list of items

	<renderlet:LISTBOX name="myexgirlfriends" label="My ex girlfriends">
		<data defaultvalue="juddy">
			<items>
				<item caption="" value=""/>
				<item caption="Laetitia" value="laetitia"/>
				<item caption="Pamela" value="pamela"/>
				<item caption="Juddy" value="juddy"/>
			</items>
			<userobj>
				<php><![CDATA[

		$aPre = array("Ash", "Ma", "Mela", "So", "Mama", "Juli");
		$aPost = array("ley", "donna", "nie", "fia", "mia", "anna");
		$aItems = array();
		for($k = 0; $k < 5; $k++) {
			
			$sPre = $aPre[array_rand($aPre)];
			$sPost = $aPost[array_rand($aPost)];
			$aItems[] = array(
				"caption" => $sPre . $sPost,
				"value" => strtolower($sPre . $sPost),
			);
		}
		return $aItems;
				]]></php>
			</userobj>
		</data>
	</renderlet:LISTBOX>

Renders as:

Formidable-Documentation-Example-11.png

renderlet:CHECKBOX, multiple defaultvalues

	<renderlet:CHECKBOX name="myexgirlfriends" label="My ex girlfriends">
		<data defaultvalue="juddy,pamela">
			<items>
				<item caption="Laetitia" value="laetitia"/>
				<item caption="Pamela" value="pamela"/>
				<item caption="Juddy" value="juddy"/>
			</items>
			<userobj>
				<php><![CDATA[

		$aPre = array("Ash", "Ma", "Mela", "So", "Mama", "Juli");
		$aPost = array("ley", "donna", "nie", "fia", "mia", "anna");
		$aItems = array();
		for($k = 0; $k < 5; $k++) {
			
			$sPre = $aPre[array_rand($aPre)];
			$sPost = $aPost[array_rand($aPost)];
			$aItems[] = array(
				"caption" => $sPre . $sPost,
				"value" => strtolower($sPre . $sPost),
			);
		}
		return $aItems;
				]]></php>
			</userobj>
		</data>
	</renderlet:CHECKBOX>

Renders as:

Formidable-Documentation-Example-12.png

renderlet:CHECKSINGLE

TODO

* now uses only 0 or 1 as a value ; see lists.typo3.org/pipermail/typo3-project-formidable/2007-June/000440.html
* added support for custom labels in renderonly of single checkbox, thanks to Manuel Rego Casanovas (additional infos: lists.typo3.org/pipermail/typo3-project-formidable/2007-May/000343.html)
	used like this:
	<renderlet:CHECKSINGLE name="test" label="LLL:EXT:my_extlocallang.xlf:test" renderonly="true">
		<labels>
			<checked>LLL:EXT:my_extlocallang.xlf:test.checked</checked>
			<nonchecked>LLL:EXT:my_extlocallang.xlf:test.nonchecked</nonchecked>
		</labels>
	</renderlet:CHECKSINGLE>

No special conf. See renderlet:*

renderlet:CHECKSINGLE automatically returns 1 if the checkbox is checked, 0 if not.

renderlet:CHOOSER

Renders as a list of push-button links. Selected value is returned by the renderlet. Submits automatically on change event.

Property

Data type

Description

Default

Advice

/wrapitem

wrap string

Wrap property for items ( except selected item when /wrapselected given )

|


/wrapselected

wrao string

Wrap property for selected item

/wrapitem


/separator

string

String used for separating each items of the list

&#124; ( equals to pipe )


Examples

Plain renderlet:chooser

	<renderlet:CHOOSER name="nbres">
		<data defaultvalue="50">
			<items>
				<item caption="15" value="15"/>
				<item caption="50" value="50"/>
				<item caption="100" value="100"/>
			</items>
		</data>
		<wrap><![CDATA[display: | per page]]></wrap>
		<wrapselected><![CDATA[<span style='font-size: 20px;'>|</span>]]></wrapselected>
		<wrapitem><![CDATA[<span>|</span>]]></wrapitem>
		<separator><![CDATA[ - ]]></separator>
	</renderlet:CHOOSER>

Renders as:

Formidable-Documentation-Example-13.png

renderlet:LINK

TODO

* searchable="false" by default now

Hint: With <pageid>5</pageid> (5 is an example ID) you make a link to the TYPO3 Page with the UID 5.

Displays as a link. Can also return URL only.

Useful for creating links with events handling. ( See events section ).

NOTE: for being displayed in a list managed by datahandler:LISTER, has to be set as /activelistable (= true).

See renderlet:*/activelistable for more informations.

Property:

Data type:

Description:

Default:

Advice

/url

string, <userobj>

Url to be used in the link.


If not given,and if the renderlet value ( see /data/defaultvalue & /data/value ) is an URL, then the renderlet value will be used for /url

javascript:void(0);


/urlonly

boolean, <userobj>

Whether or not to return only the URL

false


/label

string, <userobj>

If given, will be used as the caption of the link. If not, value will be used.


empty


/custom

string, <userobj>

Use /custom to insert target if you need to

empty


/readonly

boolean

A renderlet:LINK is always readonly

true (cannot be changed)


/renderonly

boolean

As its value can't change, a renderlet:LINK cannot be saved in database. It can hold a value but only for programming commodities.

true (cannot be changed)


Examples

Plain renderlet:LINK

	<renderlet:LINK name="mylink" label="Go to my website" url="http://www.ameos.com/"/>

Renders as:

Formidable-Documentation-Example-14.png


Renderlet link with userobj and no label

	<renderlet:LINK name="mylink">
		<url>
			<userobj>
				<php><![CDATA[

		return t3lib_div::locationHeaderUrl(
			$this->_oParent->pi_getPageLink(
				$GLOBALS["TSFE"]->id,
				"",
				array(
					"someparameter" => 1
				)
			)
		);
				]]></php>
			</userobj>
		</url>
	</renderlet:LINK>

Notes: in a PHP userobj, $this always points to the FORMidable object, and $this->_oParent always points to the plugin calling FORMidable. See FORMidable CORE programming for more informations.

Renders as:

Formidable-Documentation-Example-15.png

renderlet:BUTTON

A button useful for handling events. See events section for more information.

Property

Data type

Description

Default

Advice

/renderonly

boolean

Always true

true


/readonly

boolean

Always true

true


/activelistable

boolean, <userobj>

Redefines default value as true ( different of renderlet:* )

true

We want a button to be listable by default

renderlet:IMAGE

TODO

* can now handle default image thru /defaultpath
* rewrite of path management system ; can now handle pathes like:
  /absolute/path/to/image.png
  http://localdomain/image.png
  http://foreigndomain/image.png
  EXT:ameos_formidable/res/images/too_cool.png
  typo3conf/ext/ameos_formidable/res/images/too_cool.png
  /typo3conf/ext/ameos_formidable/res/images/too_cool.png

Used for displaying image in your application. What else ? ;)

Property

Data type

Description

Default

Advice

/path

string, <userobj>

Path to the image; relative to path site; without starting slash


Or an evaluated path like EXT:my_ext/images/image.gif

required


/imageconf

TS <userobj>

Typoscript used to reprocess image before displaying. See examples.


Some effects are available in FORMidable base pack. They are defined in EXT:ameos_formidable/ext_typoscript_setup.txt

empty


Examples

Plain renderlet:IMAGE

    <renderlet:IMAGE>
        <path>EXT:ameos_testform/res/atari.jpg</path>
    </renderlet:IMAGE>

Renders as:

Formidable-Documentation-Example-16.png

renderlet:IMAGE with imageconf (basepack's shaded effect) and width 100px max

	<renderlet:IMAGE>
		<path>EXT:ameos_testform/res/atari.jpg</path>
		<imageconf>
			<userobj>
				<ts><![CDATA[

				10 < config.tx_ameosformidable.res.shared.xml.imageprocess.shaded
				10.file.50.file < params.relwebpath
				10.file.50.file.width = 100m
				]]></ts>
			</userobj>
		</imageconf>
	</renderlet:IMAGE>

Renders as:

Formidable-Documentation-Example-17.png

renderlet:IMAGE with imageconf (basepack's rounded effect) and width 100px max

	<renderlet:IMAGE>
		<path>EXT:ameos_testform/res/atari.jpg</path>
		<imageconf>
			<userobj>
				<ts><![CDATA[

				10 < config.tx_ameosformidable.res.shared.xml.imageprocess.rounded
				10.file.10.file < params.relwebpath
					10.file.10.file.width = 100m
				]]></ts>
			</userobj>
		</imageconf>
	</renderlet:IMAGE>

Renders as:

Formidable-Documentation-Example-18.png

renderlet:SUBMIT

Renders as a submit button

Property

Data type

Description

Default

Advice

/mode

string, one of submit, refresh, draft, test

See events section for more informations

submit

Validators

A validator is an object that will check the validity of a data produced by a renderlet against specified criteria.

They are declared inside a renderlet configuration, in an xml tag named <validators>, which is a placeholder for one or several <validator>.

Each validator has a type declared inside the validator namespace.

Ex: validator:DB, a validator of type DB that checks conditions inside database ; validator:NUM, checking numerical constraints on data; ...

A validator returns TRUE if data is OK, FALSE in the other case.

NOTE: Each validator returns TRUE if the data is empty, except the validator:STANDARD/required, returning FALSE if the data is empty. This allows to reject data only if given.

If validator returns FALSE, it also produce an error message corresponding to what's given in subsection <message> of the validator. You can use plain messages or localized LLL:EXT: ... locallang strings if needed.

Example

Note: screenshots of these examples are made using renderer:STANDARD

	<renderlet:TEXT name="email" label="Your email address">
		<validators>
			<validator:STANDARD>
				<required message="Email address is required"/>
				<email message="Email address not valid"/>
			</validator:STANDARD>
			<validator:DB>
				<unique message="This email is already used in database"/>
			</validator:DB>
		</validators>
	</renderlet:TEXT>

In this example, user has to enter it's email address; FORMidable will check if email is given, then if valid, then if not already in database for unicity.

Renders:

Formidable-Documentation-Example-19.png

After submitting:

Formidable-Documentation-Example-20.png

Let's give some weird data:

Formidable-Documentation-Example-21.png

The datahandler will not process data until everything is valid in the form.

Displaying errors like this is the way renderer:STANDARD does by default. To have nicer, customized error messages, use renderer:TEMPLATE


validator:STANDARD

TODO

* added minsize validator

This validator does the usual data-checks.

Property

Data type

Description

Default

Advice

/required


Checks that data is not empty

empty

/authentified


Checks that fe-user is authentified

empty


/maxsize/value

integer

Checks that data length is < to value


For text-like renderlets, checks the char length. For listbox/checkbox/radiobutton fields, checks the number of checked items.

empty


/sameas/value

string

Value has to be the name of an other renderlet. Checks that the value for this renderlet is the same that the value for the given renderlet.

empty

Useful when checking password confirmation

/email


Checks that data is a valid email address



/userobj

<userobj>

Executes the userobj for checking data. If you can't do it using hardcoded valitadors, use this validator.


The userobj has to return TRUE if valid, FALSE if not.


See example below



Examples

validator:STANDARD/userobj

This example demonstrates how to perform custom validation on data:

	<renderlet:TEXT name="email" label="Your email adress">
		<validators>
			<validator:STANDARD>
				<userobj message="Sorry, we don't want hotmailers here">
					<php><![CDATA[

					$sValue = array_pop(func_get_args());

					if(!empty($sValue)) {

						if(strstr(strtolower($sValue), "@hotmail.com")) {
						   return FALSE;
						}
					}
					return TRUE;
					]]></php>
				</userobj>
			</validator:STANDARD>
		</validators>
	</renderlet:TEXT>

Renders as:

Formidable-Documentation-Example-22.png

validator:DB

TODO
* unique can now be used without defining value=true

Checks DB related conditions.

To be used only with datahandler:DB

Property

Data type

Description

Default

Advice

/unique


Checks that data is unique inside the table for this column.

empty


validator:FILE

TODO
* now compatible with rdt_file and rdt_upload (single and multiple modes)

Checks FILE related conditions.

Useful for checking file after upload.

NOTE: WARNING: if file is rejected by any of validator:FILE, it will be deleted by FORMidable.

USE only for user-uploaded files. Not meant to test files existing on the server. They would be deleted.

Property:

Data type:

Description:

Default:

Advice

/extension/value

string csv

Checks that file extension matches one of the list. Takes comma-separated list of file extensions to be matched.

empty


/filesize/value

integer

Checks that filesize is below or equal to given filesize. Filesize in Bytes.

empty


validator:NUM

Checks numeric related conditions.

Property

Data type

Description

Default

Advice

/islower/value

integer

Checks that data is a number lower than given number.

empty


/ishigher/value

integer

Checks that data is a number higher than given number.

empty


/isbetween/value

string csv

Checks that data is a number between given lower and upper bound, comma-separated.


validator:PREG

Checks validity of data against regex pattern. (See http://www.php.net/regex) Credit for this validator goes to Jérémy Lecour ( jeremy.lecour(a)nurungrandsud(dt)com )

Property

Data type

Description

Default

Advice

/pattern/value

string regex

Checks data validity against regex. If pattern prefixed with !, then condition is reversed.

empty

Control

TODO
* <datasources />

The <control> section of the XML is just a placeholder for the datahandler, the renderer and optionally actionlets. See datahandler, renderer and actionlets.

Datahandlers

TODO
* created VOID datahandler for consistency with renderer:VOID ; does absolutely nothing with data
* _P(): added fieldname parameter in method _P()
* Added standard internationalization (i18n) management main_datahandler, dh_db, dh_lister : i18n support ( thru /datahandler/i18n/use="true" ; /datahandler/i18n/sys_language_uid="something" )
* added bunch of i18n_ functions
* added refreshStoredData(), refreshFormData(), refreshFormDataManaged() and refreshAllData()

Datahandler's job is to do something with the data produced by your application. Quite cool, huh ?

datahandler will be executed only when form is submitted and all validators are GO.

There are several datahandlers available.

datahandler:DB

TODO in this section
* Added standard internationalization (i18n) management main_datahandler, dh_db, dh_lister : i18n support ( thru /datahandler/i18n/use="true" ; /datahandler/i18n/sys_language_uid="something" )
* /i18n/update_childs_on_save="true" => manages synchronization of data with translated records for renderlets defining /i18n/translate="false"
* added /process/afterinsertion

This is the most used datahandler. Designed to insert / update records into the given table. This datahandler works by default in CREATION mode. This means that it will insert form-data into the given table. To make it work in EDITION mode, when instanciating FORMidable, give the uid of the record you need to edit as a parameter.

Like this:

	$this->oForm = t3lib_div::makeInstance("tx_ameosformidable");
	$this->oForm->init(
		$this,
		t3lib_extmgm::extPath($this->extKey) . "xml/form.xml",
		25    // uid of the record to edit
	);

(See Integration of FORMidable in my plugin for more informations about this)

Property

Data type

Description

Default

Advice

/tablename

string

Name of the DB table to work on.

required


/keyname

string

Name of the primary key in the given table.

required


/process/beforeinsertion

<userobj>

Define a userobj here if you want to alter the data that are to be inserted / updated into the database.

Takes an array of values as an input, returns an array of values as an output.

See example below.

empty

Useful when you want to add system fields to your table row, like pid, crdate, ...


If you want to cancel the modification of the data in DB, return an empty array() here

Examples

Simple datahandler:DB working on fe_users table

    <datahandler:DB>
        <tablename>fe_users</tablename>
        <keyname>uid</keyname>
    </datahandler:DB>

datahandler:DB adding pid and crdate to the record using /process/beforeinsertion

    <datahandler:DB>
        <tablename>fe_users</tablename>
        <keyname>uid</keyname>
        <process>
            <beforeinsertion>
                <userobj>
                    <php><![CDATA[

		       	$aData = func_get_arg(1);
	
			$aData["pid"] = 343;
			$aData["crdate"] = time();
		        
                        return $aData;
                    ]]></php>
                </userobj>
            </beforeinsertion>
        </process>
    </datahandler:DB>

datahandler:RAW

The job of datahandler:RAW is to give produced data to another data processor (typically a method of your plugin).

Useful if you want to use formidable as an interface manager, but still process data yourselves.

Property

Data type

Description

Default

Advice

/callback

<userobj>

Userobj to be executed to process form-data.

Reminder: you can access to your plugin using: $this->_oParent in the PHP code of the userobj

required


datahandler:LISTER

warning - Message

The datahandler:LISTER is obsolete now, and has been replaced with renderlet:LISTER. See http://formidable.typo3.ug/features/the-mighty-lister.html
TODO

* added userobj support on comparison in additional wheres
* modified the way the lister generates pagination, pager has it's own template now
* /ifempty is now userobj'able
* Added standard internationalization (i18n) management main_datahandler, dh_db, dh_lister : i18n support ( thru /datahandler/i18n/use="true" ; /datahandler/i18n/sys_language_uid="something" )
* automatic management of filtering records on sys_language_uid if i18n activated ; filters on /datahandler/i18n/sys_language_uid if defined, or on current FE language if not
* recombine now applies also to activelistable renderlets displayed in lists
* additional wheres elements can now be better conditioned
* added _processBeforeDisplay() ; rows can be altered before display in list

The job of datahandler:LISTER is to display a list of records selected in a table AND (optionally) to apply search filters to this selection to turn your form into a searchform.

The idea is to use the form generated by FORMidable as a searchform. Of course the searchform is to be used only when needed, because you can also just list the data of a table without search.

Property

Data type

Description

Default

Advice

/tablename

string

The name of the table to work on

required


/keyname

string

Name of the primary key of this table

required


/template

XML subconf

Placeholder for the template configuration of the list

empty

Optional; if none given, the LISTER will try to build a default template for displaying records

/template/path

string, <userobj>

The path to the HTML template file

required

EXT:my_ext/template.html

/template/subpart

string, <userobj>

The subpart of this template to work on.

required

Something like ###MY_LIST###

/template/customtags

XML subconf

Placeholder for custom tags that will be added to each row of the list. Collection of <tag>

empty


/template/customtags/tag

XML subconf

An item that will describe something to add to each row of the list

empty


/template/customtags/tag/name

string

Name of the tag that will be searched and substituted in every line of the list

required


/template/customtags/tag/value

string, <userobj>

The value that will be inserted in the template for each line. See example below

required


/search

XML subconf

Placeholder for configuring all the aspects of the search within records.

empty


/search/atstartup

boolean, <userobj>

Whether or not to display list at first display of the application. If false, list will be displayed only after first submit.

true


/search/keepinsession

boolean, <userobj>

Whether or not to keep list of uids matching search criteria (if any) in session for further usage.

false

See FORMidable CORE API programming

/search/sql

XML subconf

Placeholder for modifying / overriding the SQL query executed to fetch records.

empty


/search/sql/query

string, <userobj>

SQL query that will be used to fetch records from the database

empty

Use it with a <userobj> to build custom query if needed

See FORMidable CORE API programming

/search/sql/wheres

XML subconf

Placeholder for defining SQL conditions that will be added to the one that FORMidable will automatically build for fetching records.

empty


/search/sql/wheres/beginbrace

XML tag

Adds a “(“ to the SQL query. Define it like this:

<beginbrace />

empty


/search/sql/wheres/beginbrace

XML tag


empty


/search/sql/wheres/endbrace

XML tag

Adds a “)“ to the SQL query. Define it like this:

<endbrace />

empty


/search/sql/wheres/where

XML subconf


empty


/search/sql/wheres/where/term

string

Column to apply the additional where

required


/search/sql/wheres/where/comparison

string

Type of comparison that will be executed between this term and its value.

One of: IN, NOT IN, =, <, >, <=, >=, !=

Note that you'll need to place <, >, <= and >= in a CDATA tag to keep the XML parser happy

required

You don't need to care about quotes or braces here, FORMidable will automatically add what your conf needs to be SQL valid.

/search/sql/wheres/where/value

string, <userobj>

The value this term will be compared to.

required


/search/sql/wheres/logic

string

One of: AND, OR



/process

XML subconf

Placeholder for data processing directives

empty


/process/beforesearch

<userobj>

Takes an array of values to search as an input, returns the modified array of values.

empty

See datahandler:DB/process/beforeinsertion

/process/duringlisterraw

<userobj>

Process raw database values for each row that are to be displayed in the list.

Takes an array of values to search as an input, returns the modified array of values.

empty

See datahandler:DB/process/beforeinsertion

/process/duringlister

<userobj>

Process human readable values for each row that are to be displayed in the list.

Takes an array of values to search as an input, returns the modified array of values.

empty

See datahandler:DB/process/beforeinsertion

/pager

XML subconf

Placeholder for all the configuration that deals with dispatching data across several pages.

empty


/pager/sort/

XML subconf

Placeholder for sorting configuration

empty


/pager/sort/field

string

Default table column on which data will be sorted at first display.

/keyname


/pager/sort/dir

string

Default direction on which data will be sorted at first display.

One of: ASC, DESC

DESC


/pager/rows

XML subconf

Placeholder for configuration

empty


/pager/rows/perpage

number, <userobj>

Number of records to display per page

5


/pager/rows/maximum

number, <userobj>

Maximum number of records to fetch

empty


/pager/rows/toomany

string, <userobj>

String that will be displayed if the number of records fetch is greater than /pager/rows/maximum ( if defined ).

If this property is not defined, the LISTER will just limit it's display to the /pager/rows/maximum ( if defined ).

If used in a userobj, params are given telling how much records have been counted (numrows), and how many records can be handled at max(maximum).

See getting parameter into userobj for more informations.

empty


/pager/rows/active

string

Subpart handler in the list template to be used for displaying active line ( if the LISTER is combined with another form using datahandler:DB for editing records found in the list ).

Something like ###ROWACT###

empty


/pager/rows/alternate

string csv

Comma-separated string of template subpart handlers to be used alternatively to display all the lines of the list.

Something like ###ROW1###,###ROW2###

required if LISTER used with template


/pager/rows/window

number

Number of pages to display in the pager for navigating thru pages



/callback

<userobj>

<userobj> that will be called to give the produced list HTML to your plugin.

typically something like:

	$aParams = array_pop(func_get_args());
	$this->_oParent->sListHTML = $aParams["HTML"];
	// $this->_oParent allways point to your plugin
	// this way the HTML for the list is stored
	// in a member var of your plugin for further usage

We do this because the main render() method of FORMidable that you call in your plugin returns only the HTML generated for the form;

NOTE: render() method returns the HTML if the renderer of this application did not returned anything, which is the case when you use renderer:VOID ; in that case ( when you don't want a searchform and the list, but just the list ) you don't have to provide this /callback as render() method will return the list HTML.

See renderer:VOID for more informations about how to do searchform-less lists.


See demo extensions for concrete examples of the LISTER

Datasources

TODO

* added new concept of datasource

ds_db
* far more efficient, and compatible with renderlet:LISTER and renderlet:SEARCHFORM
* now support GROUP BY statements in given sql query

ds_phparray
* added a new type of datasource handling php arrays as a source of data ; used with /bindsto => userobj returning phparray
* capable of handling sorts and limits

Renderers

TODO

* <style> tag adds dynamic CSS file to page

Renderers are the glue that sticks all the HTML generated parts together. Let's snort some renderers.

renderer:VOID

The simplest renderer of all. It does nothing with the generated HTML.

Useful when you want to display a LIST using a lister without displaying any searchform.

No configuration for this one.

renderer:STANDARD

The renderer used at development time. It takes the HTML parts generated by renderlets and validators, and display them separated by line breaks wrapped in <p /> HTML tags.


No configuration.

renderer:TEMPLATE

TODO

* added error sub-channels on the errortag, like errors.myrenderlet, for more flexibility in design
* errors are now available in wrapped span tag thru .tag template channel

The most powerful renderer available for FORMidable. Takes a template file as an input and inserts HTML parts by substituting stuff like {my_marker} with the corresponding HTML.

Tags are formatted like this: {my_renderlet_name}

Each renderlet renders it's full layout ; the produced HTML will be accessible using the syntax {my_renderlet_name}.

But there is more to a renderlet output than meets the eye. See Multichannel-template to have more information about this.

Property

Data type

Description

Default

Advice

/template

XML subconf

Placeholder for the template configuration of the list

required


/template/path

string, <userobj>

The path to the HTML template file

required

EXT:my_ext/template.html

/template/subpart

string, <userobj>

The subpart of this template to work on.

required

Something like ###MY_FORM###

/template/errortag

string

The tag that will be susbtituted to insert errors into template.

Something like this:

    <errortag>myerrortag</errortag>

Note: FORMidable sets automatically a cssdisplay channel to this tag, which will contain block if there were errors in the data user gived, or none in the other case. Set to none at first display.This way you can display or not the container of the errors easily if needed, doing something like this:

    <div style="display: {myerrortag.cssdisplay};">
        <p>Some fields have not been correctly completed:</p>
        <span style="color: red;">{errors}</span>
    </div>

This way the div and it's content will be displayed only if there were errors. See multichannel-template for more informations about this kind of feature.


Multichannel-template

Each renderlet renders it's full layout. It's available in the template using this marker syntax {my_renderlet_name}.

But each renderlet has also a lot of other informations to give about it's job than just the compiled HTML.

So Multichannel-template is a way to access these informations in your template using a simple dotted notation in your template.

Example: I would like to display the label of my renderlet in a red span after the field itselves

You would do something like this, in your HTML template:

    {my_renderlet_name.input}<br />
    <span style='background-color: red'>{my_renderlet_name.label}</span>

There are plenty of these HTML bonuses inside each one of the renderlets. To know exactly what's available on a renderlet, use the .help channel of this renderlet in your template.


Like this: {my_renderlet_name.help} This way you can totally reshape the layout of a renderlet within your template.

See also /renderlet:*/recombine for a TS approach on using these channels.

Events

TODO

* new notion of programmaticaly defined events
* new onload events on renderlets

Event:inline
* inline js events now use JSON to serialize js statements

There are 3 types of events in formidable: client, server and ajax

They are declared on renderlets, and bind to standard Javascript events on form fields ( like onclick, onmouseover, ... )

A typical event is defined like this:

    <renderlet:BUTTON label="Press me!">
        <onclick runat="ajax">
            <userobj>
                <php><![CDATA[

                    return $this->majixDebug("Hello, World!");

                ]]></php>
            </userobj>
        </onclick>
    </renderlet:BUTTON>


Client events

TODO

* added the possibility of CLIENT onload events on renderlets
* pseuso-param clientData::

Are used when no page refresh nor PHP processing is required to do what has to be done ( typically hiding divs in page, but could be a lot other things )

Are generated as static javascript when the whole HTML is generated

Cannot be conditional ( meaning you cannot provide if-conditions on wheter to execute task A or task B inside the event when fired )

Closer look

You provide a php-userobj to tell Formidable what to do when button clicked. This PHP is executed when page is generated, returning an array of majix tasks to execute, and resulting JS is statically embeded in the page.

Logical scheme

  • Formidable reads XML configuration for the button
  • F. generates the whole collection of majix things to execute as a static string of javascript
  • When button is clicked, the static JS is attached to onclick is executed

Ajax events

TODO

* Changed ajaxevent; it's now possible to request params from the current line if displayed in a lister;
	Syntax: <onwhatever runat="ajax" params="rowData::uid, rowData::pid">
* added support for onload ajax events on renderlets
* mainrenderer::_getAjaxEvent(): added support for new namespace of event parameters rowInput::
* json encode() doesn't utf8_encode() strings anymore; assuming utf8-in, utf8-out
* reference to parent object can now be kept in ajax context, if /needparent=true on event; default false
* AJAX events cannot be used on cached pages as there's no session initialized

Require TYPO3 4.x for it's Ajax support thru eID mechanism

Don't require formidable to refresh the whole page ( meaning a true browser page-refresh )

Are used when :

  • the things to execute are too complicated to be processed by client event only

OR / AND

  • you want to execute PHP when event is fired ( like: changing the status of something in the database, sending a mail, all you can do with PHP actually )

OR / AND

  • you may have different tasks executed depending on whatever you want ( data in the page, hour of the day, random, you name it ) ; for this you can ask the event to fetch data on page, before asking the PHP server what to do through an ajax request, if needed ( params="uid, title, ..." )

Closer look

You provide a php-userobj to tell Formidable what to do when button clicked. It's a mix of client-event and server event, as it requires no page refresh to be processed (like the client event) and still requires PHP dynamic execution to process things (like server-event).

Like for the server event, when page is generated, the userobj is not executed, but formidable rather notices that an ajax event has been declared on the button. And so formidable generates an ajax-event header ( small piece of javascript ) asking formidable to execute an ajax request to the server when the event is fired. When button is clicked, ajax request is sent, userobj is executed, and an array of majix tasks to execute in the browser are sent back ; kinda like the browser asks "This guy clicked the button, what should I do now ?" and the server responds "You have to change the value of this, hide this, display this, etc"

Logical scheme

  • Formidable reads XML configuration for the button
  • F. generates an ajax-event header and attach it to the onclick event
  • When clicked, parameters are fetched (if any declared), and an ajax request is sent to the server ( page don't refreshes )
  • Your PHP-userobj receives the ajax request, inspects the parameters (if any) and executes what has to be executed.
  • If returned by the userobj, the array of majix tasks to execute by the browser are sent back thrugh the ajax request

Server events

TODO

* changed default server event checkpoint to after-init ( as this point corresponded to end in previous revisions )
* added function _getServerEventParams() to grab params from outside formidable when event is triggered
* server events are executed by new checkPoint() method
* server event default-checkpoint is now before-render ( this checkpoint suits most needs )

Are used when the whole page has to be refreshed to process the event

Typically used to motorize edit buttons, as edition *requires* (for now) a page refresh

Closer look

You provide a php-userobj to tell Formidable what to do when button clicked. The PHP is not executed when page is generated. Formidable will rather notice that a server event is declared, and will automatically attach a tiny piece of JS code (that is, the server-event header) on the onclick event for the button. When the button is clicked, this JS is executed, placing data in the POST telling formidable that the onclick-event of the button has been fired, and then making the page refresh. When PHP receives the POST of the just submitted page, it notices that this server event has been thrown, and will then execute the attached PHP do what you wanted it to do on button click.

Logical scheme

  • Formidable reads XML configuration for the button
  • F. generates a server-event header ( tiny piece of JS ) and places it on our button's onclick event
  • When clicked, parameters are fetched (if any declared), page refreshes and F. executes the PHP code attached to the event fired (determined by the sent server-event header)

Majix

TODO

tx_ameosformidable
	* majixRefresh()
	* majixScrollTo()
	* majixSendToPage()
	* majixDebug() to help construction of ajax events

mainrenderlet
	* majixDisplayBlock()
	* majixDisable()
	* majixEnable()
	* majixVisible()
	* majixHidden()
	* majixDisplayDefault() to use instead of majixDisplayBlock() to avoid apparition of line-breaks after processed html tags


rdt_listbox
	* majixReplaceData() modified to be able to use either caption/value item arrays or more concise key=>value item arrays
	* majixSetSelected() added to be able to select value in lisbox with client and ajax events
	* majixSetAllSelected() added for listbox multiple="true"
	
rdt_date
	* majixReplaceData() added it's own js class for specialization

Formidable CORE

TODO

* added concept of sandbox
* now sandbox can extend existing class using extends property, like this :<sandbox extends="EXT:my_extkey/class.someclass.php::className">/*php class here*/</sandbox>
* sandbox can now be defined without a userobj definition for altering the class that it extends
* sandbox->init(), if existing, is now passed the form object &ref as first arg
* added function toRelPath() wich converts EXT:my_ext_key and other paths to path
* modified toRelPath() ; automatically adding / before the given path if needed
* toRelPath() calls have been replaced by toWebPath()
* added /meta/oninit userobj ; used for executing code at formidable init()
* added backendHeaders() method to inject header data when used in backend module; has to be called like this after all forms have been rendered: tx_ameosformidable::backendHeaders(&$this);
* the last part of version number will correspond to SVN revision
* added (experimental) feature XPATH:/path/to/xml/config in xml, allowing xml config to reference itselves
* added toServerPath()
* added _removeStartingSlash()
* added _removeEndingSlash()
* update to prototype 1.5.1.1
* update to scriptaculous 1.7.1 beta 3
* initialization of formidable js in now much faster thanks to pseudo onDOMReady event (instead of onload)
* full xhtml 1.1 strict compatibility for forms/lists
* modified _substLLLInHtml() to be able to process pure LLL:EXT refs without {} wrapped around
* _parseTemplateCode() is now able to substitute subparts like <!-- ###myrenderlet### begin--> ... <!-- ###myrenderlet### end--> instead of {myrenderlet} to allow templating childs in main template using subparts
* better management of charsets
* included xml files can now define an xml prologue with proper charset ; if none defined, fall-back to utf8
* cache of xml is handled thru 2 new methods, file_readBin() and file_writeBin(), allowing true UTF8 on file system
* better management of xml-cache
	files are written in utf8, assuming utf8-in (no more utf8_encode)
	files are red in utf8, assuming utf8-in (no more utf8_decode)
	cache hash of file is now determined upon absolute xml-path + mod_time of xml file + api version of formidable ; boosts perfs and assures no-problems of cache between versions
* includexml can now be conditioned with a userobj on /condition, returning boolean TRUE for inclusion, FALSE for bypass inclusion
* formidable can now be used with TS config, using initFromTs()

Formidable in the TYPO3 backend

TODO

* added backendHeaders() method to inject header data when used in backend module; has to be called like this after all forms have been rendered: tx_ameosformidable::backendHeaders(&$this);

Related links