Section: "html" generator
^ Displaying a form in a template |
− Table of content
The html
generator relies on jquery. Specifically some fields and its
javascript depend heavily on it.
It is the default jelix generator for jForms. html
is the name to give to
{form}
and {formfull}
template plugins, if needed.
Builder options ¶
Options you can give in an array as the fifth argument of {form}
and
{formfull}
:
errorDecorator
: the name of the javascript object which handles error messagesmethod
: the HTTP method ('get' or 'post'). By default: 'post'.plugins
: the list of plugins to use to display some of controls. This is an associative array that have controls id as key, and the plugin name as value. Plugins are "formwidget" plugins.attributes
: list of HTML attributes to add on the<form>
element. ex:array('attributes'=>array('class'=>'myclass'))
widgetsAttributes
: list of HTML attributes to add on each widget. keys are controls refs, and values are associative arrays of attribute names with attribute values.
Personnalizing the display of controls ¶
Styling via existing CSS classes ¶
Each type of control is generated y a dedicated formwidget plugin.
HTML elements generated by these plugins have CSS classes (see below). You can then style as you want.
Custom HTML attributes ¶
You can add some html attributes on the HTML element generated with
ctrl_control
. To do it, add a second parameter to the ctrl_control
tag:
it should be an array ('attribute name'=>'attribute value')
. Give ""
as first parameter when ctrl_control
is used inside a formcontrols
loop.
<td>{ctrl_control 'lastname', array('class'=>'myclass', 'placeholder'=>'your name'}</td>
Note: on other generator than 'html', this array can be an array of other type of informations.
You can indicate these attributes into the option widgetsAttributes
of the generator. If the control is
into a {formcontrols}
loop, it avoids to add some {if_ctrl}
etc.
{form $form, 'module~action', array(), 'html', array(
'widgetsAttributes'=> array(
'lastname' => array('class'=>'myclass', 'placeholder'=>'your name'}
)}
Create/using other widget ¶
Probably you don't want the HTML as it is generated. The solution is
then to use an other plugin, that you developped or retrieved. You'll indicate
its name in the plugins options of {form}
.
{form $form, 'module~action', array(), 'html', array('plugins'=> array('myctrl'=>'superfield'))}
In this example, the widget plugin "superfield" will be used to generate the control "myctrl".
A plugin formwidget implements the interface jelix\forms\HtmlWidget\WidgetInterface
and can be inherits from the class jelix\forms\HtmlWidget\WidgetBase
.
See existing plugins and this interface to understand the creation of this kind of plugins.
Customizing messages display ¶
jForms deals with two types of messages:
- error messages generated by form checking
- help messages accessible through interrogative point
Error messages are displayed on the top of the form by default. You can customize
this behaviour. Transmit your own javascript messages display function to
{form}
or {formfull}
plugins.
Error messages display ¶
To customize display of error messages, you shall define a javascript object implementing 3 methods:
start
, called when checking process starts.addError
, called when an error is found. it receives ajFormsControl
argument, which contains infos about the erroneous control, and an error code. the latter equals 1 if user has not edited a required control, 2 if its content is invalid.end
, called when checking process ends.
You're obviously free to do whatever you need/want in those methods. As for
example, you could add the error messages to an error lists ( <ul>
located
in your html page):
function MyErrorDecorator(){
}
MyErrorDecorator.prototype = {
start : function() {
},
addError : function(control, messageType) {
var message='';
if (messageType == 1) {
message = control.errRequired;
}
else if (messageType == 2) {
message = control.errInvalid;
}
else {
message = "Error on '"+control.label+"' field";
}
var item = document.createElement("li");
item.appendChild(document.createTextNode(message));
document.getElementById("errors").appendChild(item);
},
end : function() {
}
}
Then, declare your MyErrorDecorator object in the options parameters of form
or formfull
:
{form $form, 'mymodule~default:save', array(), 'html',
array("errorDecorator"=>"MyErrorDecorator")}
...
{/form}
Details about jFormsControl object passed to addError()
(named control above),
and its properties:
name
: control or field namelabel
: its labeldatatype
: its data type (type attribute in your XML file)required
: boolean, true if requiredreadonly
: boolean, true if readonlyerrInvalid
: invalid error message defined in your XML fileerrRequired
: required error message defined in your XML filehelp
: help message defined in your XML file
Since Jelix 1.6.17, you can also declare your decorator as default error decorator for all forms. Indicate its name into the configuration:
[tplplugins]
defaultJformsErrorDecorator = MyErrorDecorator
Help messages display ¶
Help messages are displayed in a CSS help balloon when the mouse is hover the help image.
If you want to customize them, you need to provide your own CSS/javascript.
Adding javascript code ¶
You can add behaviors to any controls with javascript, with your prefered js library (jForms uses jQuery), by including your JS files in the page.
All generated fields have an id. Ids are composed names: "jforms_module_formname_controlref". For example, for a control with the ref "address", declared in the form "identity" provided the "users" module, the id of the generated field is: "jforms_users_identity_address".
The <form>
element is also generated with an id, composed with the name of the
module and the name of the jforms form: "jforms_module_formname". In our
example, the id is "jforms_users_identity".
Knowing that, you can retrieve all fields and the form element with the
document.getElementById()
function.
You can also use the jFormsJQ
object. See below.
Javascript object jFormsJQ ¶
The generated Javascript code for the form is mainly based on the
use of a JS object jFormsJQ
, from which you can access to
other JS objects corresponding to fields.
The first object you can retrieve, is the object corresponding to
the form itself. You should then call jFormsJQ.getForm()
with the form id.
var f = jFormsJQ.getForm("jforms_users_identity");
Then you can access to some functions
f.setErrorDecorator(new MyErrorDecorator); // see above
f.addSubmitHandler(function(event){...}); // see below
f.updateDynamicList("ctrlref"); // to refresh a listbox generated
// dynamically by jforms
var c = f.getControl("ctrlref"); // retrieve of the js object of a control
The js object of a control has some properties:
c.name; // the "ref" value
c.label; // its label
c.required; // indicate if it is required
c.errInvalid; // message when the content is invalid
c.errRequired; // message when the content is required
c.readOnly; // true ou false.
Some objects have additionnal properties depending of their type.
Check during a submit ¶
To add additional check or to run anything you want during the submit event,
you should not to use an event listener, but you should add a "submit handler"
on the javascript jforms object. A submit handler is a function, accepting a DOM
event as parameter, and returning true
if the form can be submitted, else false
.
You add a submit handler with the function addSubmitHandler
on the jforms
object.
Here is an example to add a confirmation message:
jQuery(document).ready(function(){
jFormsJQ.getForm("the_id_of_formelement").addSubmitHandler(function(ev){
return window.confirm("Do you really want to submit this data?");
});
});
By default, the handler is executed after the check on data. If you want to add
the handler before the check, indicate true as second parameter to
addSubmitHandler
.
All handlers (and the data check) are executed, even if one handler or the data checker return false. If you want to stop the execution of handlers following your's, just throw an exception.
jQuery and your application ¶
HTML generator forces jQuery inclusion on every HTML response including a jForm. Thus, if you already link to jQuery script elsewhere in your appplication, such as in your common response, you should take care to include the very same script. Otherwise, your user will download it twice.
Example in a common response :
$this->addJSLink(jApp::urlJelixWWWPath().'jquery/jquery.js');
Usefull CSS classes ¶
Here is a reference of classes attributes generated by jforms.
jforms-table
: class of <table> generated with formfulljforms-submit-buttons
: class of <div> generated with formfull, and containing submit/reset buttonsjforms-submit
: class of each submitjforms-reset
: class of each resetjforms-hidden
: class of each hidden fieldjforms-error-list
: class of error messages list(ul) .jforms-label
: class of each <label>jforms-required
: class of each required control <label>jforms-error
: class of each <label> and fields whose controls are erroneousjforms-readonly
: class of each readonly controlsjforms-value
: class of <span> displaying fields value.jforms-help
: class of <span> containing help llinks.jforms-chkbox
: class of each <span> wrapping a checkbox widget of a checkboxes control.jforms-radio
: class of each <span> wrapping a radio widget of a radiobuttons control.jforms-ctl-xxx
: class of each checkbox of a checkboxes control, class of each radio of a radiobuttons control (xxx equals ref of current control).jforms-captcha-question
: class of each <span> wrapping a captcha question...jforms-table-group
: class of a <group> control table.jforms-choice
: class of an items list in a <choice> control.jforms-item-controls
: class of each <span> wrapping an item widget of a <choice> control.jforms-submit-buttons
: class of <div> generated with formfull, and containing submit/reset buttonsjforms-submit
: class of each submitjforms-reset
: class of each reset
.jforms-table {}
.jforms-hidden {}
.jforms-error-list {}
.jforms-label {}
.jforms-required {}
.jforms-error {}
.jforms-readonly {}
.jforms-value {}
.jforms-help {}
.jforms-chkbox {}
.jforms-radio {}
.jforms-ctl-xxx {} /* xxx must be replaced by your control ref */
.jforms-captcha-question {}
.jforms-table-group {}
.jforms-choice {}
.jforms-item-controls {}
.jforms-submit-buttons {}
.jforms-submit {}
.jforms-reset {}