Back to top

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
documentation:rack:reference:forms [2018/05/25 18:32] – created Martijn Luinstradocumentation:rack:reference:forms [2023/08/31 21:20] (current) Martijn Luinstra
Line 3: Line 3:
 Rack provides a set of classes enable form handling and rendering in ''include/form.php''. This page discusses the public form API. Rack provides a set of classes enable form handling and rendering in ''include/form.php''. This page discusses the public form API.
  
-===== Form objects =====+===== Form class =====
  
 +The core of Rack's form system is the ''%%Form%%'' class. All interactions with a form and it's fields should happen through this class, or one of its subclasses.
  
 +==== Initialization ====
  
 +The constructor of the form class takes two arguments, the form's name (which is an id-like string) and a lists of 
 +fields. The latter may be left out, as fields can be added through the ''%%add_field($field_name, $field)%%'' and ''%%add_fields($fields)%%'' functions.
  
 +If the form has been submitted, the fields will automatically be filled with the submitted data once they're added to the form. If needed, this process can be manually executed by calling the function ''%%initizize()%%'' on the form object.
 +
 +Sometimes, it may be desirable to populate the fields with default data. This can be done through the ''%% populate_field($field_name, $values)%%'' and ''%%populate_fields($values)%%'' functions, which set the values of the fields without overwriting submitted data.
 +
 +==== Validation ====
 +
 +Forms can be validated through their ''%%validate()%%'' function, which will return ''%%true%%'' if the form has been submitted and all fields have valid input and will return ''%%false%%'' otherwise.
 +
 +When custom validation is needed, this should generally be done by subclassing the ''%%Form%%'' class and overriding its ''%%validate()%%'' function. In some specific cases, it may be more desirable to subclass a single ''%%Field%%'' class and override its ''%%validate()%%'' function instead.
 +
 +==== Rendering ====
 +
 +There are tree main rendering strategies supported. Automatic rendering, semi-automatic rendering and manual rendering. Automatic rendering can be done calling the function ''%%render($action=null, array $attributes=[])%%'', which allows for customizing the arguments of the ''<form>'' tag.
 +
 +Semi-automatic rendering can be done by manually calling the function ''%%render_field($key, array $attributes=[], array $error_attributes=[], array $parent_attributes=[])%%'' for every field of the form. This renders the form according to the following template
 +
 +<code php>
 +<div $parent_attributes>
 +   <label></label>
 +   <field $attributes> 
 +   <span $error_attributes></span> // for each error
 +</div>
 +</code>
 +
 +Manual rendering can be achieved by iterating over the form's fields and calling the field's ''%%render(array $attributes=[])%%'' and ''%%render_label()%%'' functions. The field's errors should then also be rendered manually.
 +
 +(Semi) Automatic can be customized by subclassing the ''%%Form%%'' class and overriding its render functions. Rack already provides a class to render forms compatible with Bootstrap 3, called ''%%Bootstrap3Form%%''
 +
 +==== Public functions ====
 +
 +The ''%%Form%%'' class exposes the following public functions:
 +
 +  * ''%%__construct($name, array $fields=[])%%''
 +  * ''%%initialize()%%''
 +  * ''%%is_submitted()%%''
 +  * ''%%validate()%%''
 +  * ''%%render(array $attributes=[], $action=null)%%''
 +  * ''%%render_field($key, array $attributes=[], array $error_attributes=[], array $parent_attributes=[])%%''
 +  * ''%%add_field($field_name, $field)%%'' and ''%%add_fields($fields)%%''
 +  * ''%%delete_field($field_name)%%''
 +  * ''%%get_field($field_name)%%'' and ''%%get_fields()%%''
 +  * ''%%get_name()%%''
 +  * ''%%get_value($field_name)%%'' and ''%%get_values()%%''
 +  * ''%%set_value($field_name, $value)%%'' and ''%%set_values($values)%%''
 +  * ''%%populate_field($field_name, $values)%%'' and ''%%populate_fields($values)%%''
 +
 +===== Fields =====
 +
 +==== Field class ====
 +
 +The ''%%Field%%'' class provides the base implementation for all fields supported by Rack. Its constructor has the following signature ''%%__construct($label, $optional=false, array $attributes=[], $name='', $form=null)%%''. It should be noted that fields are required by default and the attributes used for rendering the HTML tag of the field (e.g. ''<input>'') can be provided on intialization.
 +
 +In the default validation strategy, validation fails (returns ''%%false%%'') if…
 +  * …the field is not optional and empty (a string only containing whitespace counts as empty)
 +  * …the ''maxlength'' HTML5 attribute is set and the value is a string that is longer than the defined ''maxlength''
 +  * …the ''minlength'' HTML5 attribute is set and the value is a string that is shorter than the defined ''minlength''
 +In all other cases, validation succeeds (returns ''%%true%%''). Field subclasses may extend or override this strategy.
 +
 +It should be noted that required fields will render the HTML5 ''required'' attribute.
 +
 +==== Supported fields ====
 +
 +=== InputField ===
 +
 +A general implementation of the HTML ''<input>'' element. The constructor has the custom signature ''%%__construct($type, $label, $optional=false, array $attributes=[], $name='', $form=null)%%'', where ''%%$type%%'' corresponds to the HTML ''type'' attribute. ''%%InputField%%'' does not implement custom validation.
 +
 +=== TextAreaField ===
 +
 +An implementation of the HTML ''<textarea>'' element. ''%%TextAreaField%%'' does not implement a custom constructor or custom validation.
 +
 +
 +=== SelectField ===
 +
 +An implementation of the HTML ''<select>'' element. The constructor has the custom signature ''%%__construct($label, $options, $optional=false, array $attributes=[], $name='', $form=null))%%'', where ''%%$options%%'' is an array containing all options of the field. The following snippet demonstrates the accepted formats for the ''%%$options%%'' array.
 +
 +<code php>
 +$options = [
 +   // 1) Single value: <option>Option Name</option>
 +   'Option Name',
 +   // 2) Value mapped to display name: <option value="option_value">Option Name</option>
 +   'option_value' => 'Option Name',
 +   // 3) Single value, with attributes: <option class="class_name" disabled>Option Name</option>
 +   ['Option Name', ['disabled', 'class' => 'class_name']],
 +   // 4) Value mapped to display name with attributes: <option value="option_value" class="class_name" disabled>Option Name</option>
 +   'option_value' => ['Option Name', ['disabled', 'class' => 'class_name']],
 +];
 +</code>
 +
 +''%%SelectFields%%'' does implement custom validation, which fails if…
 +  * …the field is not optional and no value has been submitted
 +  * …the selected value does have the ''disabled'' HTML attribute.
 +
 +Validation succeeds in all other cases.
 +
 +Please do note that due to PHP limitations, it is impossible to render options with integer keys (array keys) or options with string keys that contain integer values (e.g. ''%%"8"%%'' or ''%%"22"%%'').
 +
 +=== CheckBoxField ===
 +
 +Subclass of ''%%InputField%%'' to render ''<input type="checkbox">'' fields. This class does not implement a custom constructor, but it does implement custom validation which fails if the field is not optional and the value is empty.
 +
 +''%%CheckBoxField%%'' implements an additional render function ''%%render_with_label(array $attributes=[])%%'' which renders the field as:
 +
 +<code php>
 +<label>
 +  <input type="checkbox" $attributes>
 +  $label_text
 +</label>
 +</code>
 +
 +=== StringField ===
 +
 +Subclass of ''%%InputField%%'' to render ''<input type="text">'' fields. ''%%StringField%%'' does override the ''%%InputField%%'' constructor to have the same signature as the ''%%Field%%'' constructor. It does not implement custom validation.
 +
 +=== EmailField ===
 +
 +Subclass of ''%%InputField%%'' to render ''<input type="email">'' fields. ''%%EmailField%%'' does override the ''%%InputField%%'' constructor to have the same signature as the ''%%Field%%'' constructor. 
 +
 +''%%EmailField%%'' does implement custom validation, which fails if…
 +  * …the field is not optional and no value has been submitted
 +  * …the value is a valid email address if it would be sanitized.
 +
 +**WARNING!** This fields value is NOT sanitized. You should sanitize it (''%%$value = filter_var($value, FILTER_SANITIZE_EMAIL);%%'') before using it!
 +
 +=== DateField ===
 +
 +Subclass of ''%%InputField%%'' to render ''<input type="date">'' fields. ''%%StringField%%'' implements a custom constructor with the signature ''%%__construct($label, $format, $optional=false, array $attributes=[], $name='', $form=null)%%'', where ''%%$format%%'' is a format string accepted by [[http://php.net/manual/en/datetime.createfromformat.php|DateTime::createFromFormat]].
 +
 +''%%DateField%%'' does implement custom validation, which fails if…
 +  * …the field is not optional and no value has been submitted
 +  * …the value does not satisfy the provided format
 +
 +
 +=== NumberField ===
 +
 +Subclass of ''%%InputField%%'' to render ''<input type="number">'' fields. ''%%NumberField%%'' does override the ''%%InputField%%'' constructor to have the same signature as the ''%%Field%%'' constructor.
 +
 +''%%NumberField%%'' does implement custom validation, which fails if…
 +  * …the default implementation of ''validate()'' fails
 +  * …the value is not numeric
 +  * …the ''max'' HTML5 attribute is set and the value is greater than the defined ''max''
 +  * …the ''min'' HTML5 attribute is set and the value is greater than the defined ''min''

documentation/rack/reference/forms.1527273127.txt.gz · Last modified: 2022/04/03 14:00 (external edit)