The guide to the Form library.
Forms are build from arrays, called skeletons. They provide information about the fields of the form as well as the form itself. Pass the skeleton to the constructor, then call render()
on the form object to render the form HTML.
"Skeletons" can contain "form arguments" which are string values with keys that begin with an underscore. They can also contain "fieldDefs" which define a field, are array values and have keys that begin with letters.
For example, the following form has a title textbox, a body textarea and a submit button. It will submit via POST.
$skeleton['_method'] = 'POST';
$skeleton['title'] = [
'_title' => 'Title'
, 'type' => 'text'
];
$skeleton['body'] = [
'_title' => 'Body'
, 'type' => 'textarea'
];
$skeleton['submit'] = [
'_title' => 'Submit'
, 'type' => 'submit'
];
$form = new \SeanMorris\Form\Form($skeleton);
echo $form->render();
Forms can be populated with both the setValues()
and validate()
methods. Pass the coresponding array of input values into one or the other to fill values with user data.
Calling validate()
will also populate the forms errors if there are any validators attached to the fields. validate()
itself returns booleans, but the errors()
method can be called to get the list of errors generated.
If no value is provided to the setValues
or validate
method call, then the form will populate itself from $_GET or $_POST, depending on which method it is set to use (node: this defaults to GET).
if(!$form->validate($_POST))
{
$errors = $form->errors();
}
Specify GET or POST to set the request type. Defaults to GET.
PUT and DELETE are valid but will not be supported by most browsers.
$skeleton['_method'] = 'POST';
Set _action to submit the form to a URL other than the one it is served from.
$skeleton['_action'] = '/submit/to/path';
Set a theme to render the form and its fields. If its not supplied, SeanMorris\Form\Theme\Theme
will be used.
A theme class name can also be passed as the first param to the render()
method, which will override the value provided in the skeleton.
$skeleton['_theme'] = 'Namespace\ThemeClass';
-or-
$form->render('Namespace\ThemeClass');
Elements without a type
key will render as text inputs, but it is still recommeneded to supply the type for text fields.
If necesary, see EXTENDING if new fieldtypes need to be created.
$skeleton['someString'] = [
'_title' => 'String'
, 'type' => 'text'
];
Checkbox fields will simply render a checkbox with a value of 1 when checked.
$skeleton['image'] = [
'_title' => 'Image'
, 'type' => 'checkbox'
];
Fieldsets contain other fields.
$children['childA'] = [
'_title' => 'Child Field A'
, 'type' => 'text',
];
$children['childB'] = [
'_title' => 'Child Field B'
, 'type' => 'text',
];
$skeleton['fieldset'] = [
'_title' => 'Fields'
, 'type' => 'fieldset'
, '_children' => $children
];
Fieldsets can encapsulate their children with the _array
key. In the following example, The value of childA
will be submitted as fieldset[childA]
:
$children['childA'] = [
'_title' => 'Child Field A'
, 'type' => 'text',
];
$skeleton['fieldset'] = [
'_title' => 'Fields'
, 'type' => 'fieldset'
, '_children' => $children
, '_array' => TRUE
];
$skeleton['image'] = [
'_title' => 'Image'
, 'type' => 'file'
];
File fields will be populated with stdClass
type values when submitted. The object will have the following format:
stdClass Object (
[name] => elemental.jpg
[type] => image/jpeg
[tmp_name] => /tmp/php5QegRw
[error] => 0
[size] => 76521
)
Hidden
Hidden fields are passed to the browser but not rendered.
$skeleton['id'] = [
'type' => 'hidden'
, 'value' => $someVar
];
Password type fields will never render their own value, for security reasons.
$skeleton['password'] = [
'_title' => 'Password'
, 'type' => 'password'
];
Radio button fields take the special _options
key. It is an associative array of keys to values. Keys are the actual values submitted, and values are displayed to the user.
$skeleton['eyeColor'] = [
'_title' => 'Eye Color'
, 'type' => 'radios'
, '_options' => [
'blue' => 'Blue'
, 'brown' => 'Brown'
, 'green' => 'Green'
, 'hazel' => 'Hazel'
]
];
Select fields work almost the same way as field of the radios
type. You can also use the multiple
key (recommended value of which is also "multiple"
) to automatically append a []
to the submitted name, and allow the user to select multiple values.
$skeleton['eyeColor'] = [
'_title' => 'Eye Color'
, 'type' => 'Select'
, '_options' => [
'blue' => 'Blue'
, 'brown' => 'Brown'
, 'green' => 'Green'
, 'hazel' => 'Hazel'
]
];
Text fields are simple. Attributes like maxlength
or autocomplete
can be specified as keys.
$skeleton['someString'] = [
'_title' => 'String'
, 'type' => 'text'
, 'maxlength' => 120
, 'autocomplete' => 'off'
];
Textarea fields are almost as simple as text fields. Attributes like rows
and cols
can be specified as keys.
$skeleton['someString'] = [
'_title' => 'String'
, 'type' => 'text'
, 'rows' => 10
];
New fields can be created by extending the base class SeanMorris\Form\Field
The _class
key takes class name to use for the field. If you want to render the field with a custom template, see EXTENDING for advanced topics.
All you need to do is build the field's definition like you would as an element of a skeleton, and pass it on to parent::__construct($fieldDef, $form);
.
namespace SeanMorris\Form\Test\Extension;
class NameField extends \SeanMorris\Form\Field
{
public function __construct($fieldDef, $form)
{
$fieldDef += [
'type' => 'text'
, '_regex' => [
'/^[a-zA-Z]$/' => '%s must consist of only letters.'
]
];
parent::__construct($fieldDef, $form);
}
}
Usage:
$skeleton['fieldName'] = [
'_title' => 'First Name'
, '_class' => 'SeanMorris\Form\Test\Extension\NameField'
, 'rows' => 10
];
Validation is simple. There are a few validators that can be used with some special field skeleton keys.
Special key: _required
.
The required validator simply take an error message, to be displayed when the field is not filled in. If %s
or %1$s
appears in the message, it will be replaced with the field title.
$skeleton['title'] = [
'_title' => 'Title'
, 'type' => 'text'
, '_required' => '%s - Required.'
];
Special key: _email
.
The Email Validator take a single error string. If %s
or %1$s
appears in the message, it will be replaced with the field title.
$skeleton['email'] = [
'_title' => 'Email'
, 'type' => 'text'
, '_email' => '%s must be a valid email.'
];
Special key: _range
.
The Range Validator take an array of 3 keys, mapped to their error strings. The smaller numerical key is the minimum value of the input, the larger is the maxiumum. The string key 'nan' specifies the error to display when a non numerican value is submitted. If %s
or %1$s
appears in the message, it will be replaced with the field title.
$skeleton['testField'] = [
'type' => 'number'
, '_title' => 'Test Field'
, '_range' => [
0 => '%s must be at least 0.'
, 10 => '%s must be no greater than 10.'
, 'nan' => '%s must be a numberical value.'
]
];
Class SeanMorris\Form\Validator\Regex
Special key: _regex
.
The Regex validator takes an array of error messages, keyed by regex patterns. If the input value doesn't match any pattern, its error will be raised. If %s
or %1$s
appears in the message, it will be replaced with the field title.
$skeleton['password'] = [
'type' => 'password'
, '_title' => 'Password'
, '_confirm' => [
'confirmPassword' => '%s and %s must match.'
]
];
$skeleton['confirmPassword'] = [
'type' => 'password'
, '_title' => 'Confirm Password'
];
Class SeanMorris\Form\Validator\Confirm
Special key: _confirm
.
The confirm validator take an array of error messages keyed by field name. The keys refer to other fields that must be submitted with the same value as the main field, as in a password confirmation field. Multiple fields may be specified as confirmation fields, for extra certainty.
If %1$s
appears in the message, it will be replaced with the field title, and if %2$s
appears in the message, it will be replaced with the confirmation field title. If simply %s
is used, the first %s
will be replaced with the main field title, and the second %s
with the confirmation field's.
$skeleton['testField'] = [
'type' => 'password'
, '_title' => 'Password'
, '_confirm' => [
'/.{8,}/' => '%s must be at least 8 characters'
]
];
Class SeanMorris\Form\Validator\OptionFilter
Special key: _optionFilter
.
The OptionsFilter validator ensures radio/select fields are not filled with anything except the provided values. The validator take an error message to be displayed when the field does not have a valid value. If %s
or %1$s
appears in the message, it will be replaced with the field title.
$skeleton['select'] = [
'type' => 'radios'
, '_title' => 'Options'
, '_options' => [
'option_1' => 1
, 'option_2' => 2
, 'option_3' => 3
]
, '_optionFilter' => 'Invalid value for %s.'
];
New validators can be created by extending the base class SeanMorris\Form\Validator\Validator
The _validators
key takes an array keyed by validator class names. The values are passed to the validator constructors as arguments. See EXTENDING for more information on customization.
namespace SeanMorris\Form\Test\Extension;
class NameValidator extends \SeanMorris\Form\Validator\Validator
{
public function __construct($errorMessage)
{
$this->errorMessage = $errorMessage;
}
public function validate($form, $field = NULL)
{
parent::validate($form, $field);
$value = $field->value();
if(isset($value) && strlen($value) && !preg_match('/^[A-Za-z]+$/', $value))
{
$this->errors[] = $this->errorMessage;
}
return !$this->errors;
}
}
Usage:
$skeleton['name'] = [
'_title' => 'Name'
, 'type' => 'text'
, '_validators' => [
'SeanMorris\Form\Test\Extension\NameValidator' => '%s must contain only letters.'
]
];
You can extend the Form class to create a Reusable Form. You'll need to override the constructor to intercept the $skeleton. You can then build the form on the existing skeleton. You can use the skeleton array submitted to the constructor to allow fields to be added on the fly. See EXTENDING for more information on customization.
Just remember to call the parent constructor afterward.
class ReusableForm extends \SeanMorris\Form\Form
{
public function __construct($skeleton = [])
{
$skeleton['_method'] = 'POST';
$skeleton['name'] = [
'_title' => 'Name'
, 'type' => 'text'
];
parent::__construct($skeleton);
}
}
$form = new ReusableForm();
For the field type list, validator list, and usage guide read DOCS.
For the guide to extending the library to create new field types, read EXTENDING.