FormView use HTML parser Jericho. Here FormView process :
FormView use displayers which must implement interface IHTMLDisplayer to update HTML element swith behaviour (READ-WRITE, READ-ONLY, INVISIBLE, ...) and characteristics fields (MAXLENGTH, REQUIRED, and DATE) :
public interface IHTMLDisplayer { /** * Return name of displayer for specific HTML element. Name of displayer must be the same name of HTML element. * (eg : return <b>select</b> if you want implement displayer for HTML select element. * Use character <b>_</b> if you want filter about element type HTML. * (eg : return input_text for displayer input type="text") * @return name of displayer */ public String getName(); /** * Return attribute names to parse * for a displayer. Eg : name,id * @return */ public String getAttributesName(); /** * Transform current HTML element by adding (before, after HTML element) another HTML content, by adding HTML attribute * to HTML element or by replacing HTML element by another HTML content. * @param field characteristics (MAXLENGTH, REQUIRED, DATE). ATTENTION !!! this parameter can be null, when field are not * defined into XML config form-view.xml. * @param defaultBehaviour global behaviour of your form. * @param contextValuesMap Map which contains keys/values context, which can be use to generate HTML (eg: key=${maxlength} * value=50, you can use into HTML String <input maxlength="${maxlength}" /> and replace key by * value to generate <input maxlength="50" />. * @param htmlElement HTML (in) element * @param htmlOutputDocument HTML output document which contains the whole HTML content after trenasformation. */ public void processHTML(FieldView field, String defaultBehaviour, Map contextValuesMap, Element htmlElement, OutputDocument htmlOutputDocument); }
By default, FormView implements displayers DisplayerConfig class, which can be customize into XML file displayers-config.xml.
FormView DisplayerConfig use XML file displayers-config.xml to update HTML elements. By default, FormView use net.sourceforge.formview.displayer.displayers-config.xml. With DisplayerConfig, you define a displayer for each element HTML that you want manage, like this :
<?xml version="1.0" encoding="UTF-8"?> <displayers-config> <!-- HTML input type="text" --> <displayer name="input_text" > .... </displayer> .... </displayers-config>
Name of displayer is the name of HTML element (input, select, radio...). For HTML elements input, which have several types (text, hidden, button...), name of your displayer must start with input followed by character _ and followed by type (text, hidden...).
For each displayer, you define HTML update switch characteristics field and behaviour. HTML update means :
HTML update depends on :
.... <displayer name="input_text" > <property name="required" behaviours="READ-WRITE" > <insertAfterElement> <![CDATA[ * ]]> </insertAfterElement> </property> <property name="maxlength" behaviours="READ-ONLY,READ-WRITE" > <insertAttribute name="maxlength" > <![CDATA[${maxlength}]]> </insertAttribute> </property> <property name="date" behaviours="READ-WRITE" > <insertAfterElement> <![CDATA[<img src="/${contextPath}/img/calendar.gif" >]]> </insertAfterElement> </property> .... </displayer> ....
Attribute behaviours on XML property is not required. Use it if you want update HTML, on particular behaviour (READ-WRITE, READ-ONLY,....).
Variables ${maxlength} and ${contextPath} will be replace by value of maxlength of field and context path of WEB Application, while HTML render. See section Context value for more informations.
.... <displayer name="input_text" > .... <behaviour name="READ-ONLY" > <insertAttribute name="readonly" > <![CDATA[readonly]]> </insertAttribute> <insertAttribute name="title" > <![CDATA[${elementValue}]]> </insertAttribute> <insertAttribute name="class" > <![CDATA[readonly]]> </insertAttribute> </behaviour> .... </displayer> ....
Variable ${elementValue} will be replace by value of element, while HTML render. See section Context value for more informations.
It's possible to manage condition if and foreach in your behaviour. For instance for manage select at READ-ONLY behaviour :
By default name HTML attribute is used to dectect the field to transform with displayer config (input type="text" name="inputName" /). But it's possible to manage other HTML attribute like id, or for (for the label). So you could set BOLD the label for a REQUIRED field (input) and set RED the label when your field (input) has ERROR.
If you have this HTML :
<label for="inpuName" > Input Name : </label> <input type="text" name="inputName" id="inputName" />
If input inputName have ERROR, with FormView, you can generate this HTML :
<label for="inpuName" class="error" > Input Name : </label> <input type="text" name="inputName" id="inputName" class="error" />
For manage it, you must set attributesName (which can be separated with ,) into displayer element like this :
<!-- HTML label --> <displayer name="label" attributesName="for" > <property name="required" behaviours="READ-WRITE" > <insertAttribute name="class" > <![CDATA[required]]> </insertAttribute> </property> <behaviour name="INVISIBLE" > <replaceElement><![CDATA[ ]]></replaceElement> </behaviour> <behaviour name="ERROR" > <insertAttribute name="class" > <![CDATA[error]]> </insertAttribute> </behaviour> </displayer>
Here an example of XML displayers-config.xml file for HTML elements select and input (type="text") :
<?xml version="1.0" encoding="UTF-8"?> <displayers-config> <!-- HTML select --> <displayer name="select" > <property name="required" behaviours="READ-WRITE,ERROR" > <insertAfterElement> <![CDATA[ <font class="required" >(*)</font>]]> </insertAfterElement> </property> <behaviour name="READ-ONLY" > <if test="${multiple != null}" > <!-- Generate list of input hidden to keep options selected after post of form --> <forEach items="${optionsSelected}" var="currentOption" > <replaceElement> <![CDATA[<input type="hidden" name="${elementName}" value="${currentOption.value}" />]]> </replaceElement> </forEach> <!-- Generate list of option label to display --> <forEach items="${optionsSelected}" var="currentOption" > <replaceElement> <![CDATA[<input type="text" name="${elementName}Label" value="${currentOption.label}" readonly="readonly" class="readonly" title="${currentOption.label}" /><br/>]]> </replaceElement> </forEach> </if> <if test="${multiple == null}" > <replaceElement> <![CDATA[<input type="hidden" name="${elementName}" value="${optionValue}" /> <input type="text" name="${elementName}Label" value="${optionLabel}" readonly="readonly" class="readonly" title="${optionLabel}" />]]> </replaceElement> </if> </behaviour> <behaviour name="INVISIBLE" > <replaceElement><![CDATA[ ]]></replaceElement> </behaviour> <behaviour name="ERROR" > <insertAttribute name="class" > <![CDATA[error]]> </insertAttribute> </behaviour> </displayer> <!-- HTML input type="text" --> <displayer name="input_text" > <property name="required" behaviours="READ-WRITE,ERROR" > <insertAfterElement> <![CDATA[ <font class="required" >(*)</font>]]> </insertAfterElement> </property> <property name="maxlength" behaviours="READ-ONLY,READ-WRITE,ERROR" > <insertAttribute name="maxlength" > <![CDATA[${maxlength}]]> </insertAttribute> </property> <property name="date" behaviours="READ-WRITE" > <insertAfterElement> <![CDATA[ <img src="${contextPath}/img/calendar.gif" >]]> </insertAfterElement> </property> <behaviour name="READ-ONLY" > <insertAttribute name="readonly" > <![CDATA[readonly]]> </insertAttribute> <insertAttribute name="title" > <![CDATA[${elementValue}]]> </insertAttribute> <insertAttribute name="class" > <![CDATA[readonly]]> </insertAttribute> </behaviour> <behaviour name="INVISIBLE" > <replaceElement><![CDATA[ ]]></replaceElement> </behaviour> <behaviour name="ERROR" > <insertAttribute name="class" > <![CDATA[error]]> </insertAttribute> </behaviour> </displayer> </displayers-config>
Context values, are variable which can be used into displayer-config. By default, FormView is able to manage variables :
It's possible to add your custom variable with class WEBFormViewUtil, like this :
WEBFormViewUtil.addContextValue(servletContext, "myVariableName", myVariableValue);
You can after use it your variable ${myVariableName} into displayer-config.