Class Documentation

Overview

To build and display your form you'll have to include 4 php code blocks:

  1. First block at the very beginning of your page to include Form.php and build the form.
  2. Second block in your <head></head> section to call required css files for plugins.
  3. Third block in <body></body> section to render your form.
  4. Fourth block just before </body> to call required js files and js code to activate plugins.

Here is an example of page containing a form:

<?php

    // set namespace
    use phpformbuilder\Form;

    // start session
    session_start();

    // include Form.php
    include_once rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . '/phpformbuilder/Form.php';

    // instanciate form and add fields
    $form = new Form('my-form', 'horizontal', 'novalidate', 'material');
    $form->addInput('text', 'user-name', 'Your Name', 'name', 'required=required');
    [...]
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My form</title>

    <!-- Bootstrap CSS -->
    <link href="../assets/css/bootstrap.min.css" rel="stylesheet">
    <?php

    // call css files for plugins
    $form->printIncludes('css');
    ?>
    </head>
    <body>
    <h1 class="text-center">My form</h1>
    <div class="container">
    <div class="row">
    <div class="col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3">
    <?php

    // render the form
    $form->render();
    ?>
    </div>
    </div>
    </div>
    <!-- jQuery -->
    <script src="//code.jquery.com/jquery.js"></script>
    <!-- Bootstrap JavaScript -->
    <script src="../assets/js/bootstrap.min.js"></script>
    <?php

    // call required js files and js code to activate plugins
    $form->printIncludes('js');
    $form->printJsCode();
    ?>
    </body>
    </html>

            

Frameworks

All options are ready to use, and will generate HTML markup according to the chosen framework.

The default framework is Bootstrap 4.

Bootstrap 3

$form = new Form('my-form', 'horizontal', 'novalidate', 'bs3');

Bootstrap 4 Default

$form = new Form('my-form', 'horizontal', 'novalidate');

Material Design

Material Design forms are built with Materialize framework.

Material Design forms forms can be used both on pages built with Materialize and on pages built with Bootstrap 4.

  • If your website uses Materialize framework:
    $form = new Form('my-form', 'horizontal', 'novalidate', 'material');
  • If your website uses Bootstrap 4 framework:
    $form = new Form('my-form', 'horizontal', 'novalidate', 'material');
    
    // materialize plugin
    $form->addPlugin('materialize', '#my-form');

Foundation - v6.4 or higher, with XY grid

$form = new Form('my-form', 'horizontal', 'novalidate', 'foundation');

More details about __construct() here: Main functions > General > Construct

About optimization (CSS & JS dependencies)

Without PHP Form Builder, your page loads the plugin dependencies (CSS and Javascript files) one by one.
If your form uses 5 plugins, you will need to call at least 10 files (5 CSS + 5 Javascript),
which considerably increases the loading time.

PHP Form Builder groups and compresses all the CSS and Javascript dependencies into a single CSS | Javascript file.

Your page will therefore only call 2 dependency files. Efficiency is maximum, no matter how many plugins you use.

Javascript dependencies can also be loaded with the excellent loadjs library.

Detailed explanations are available here: Optimization (CSS & JS dependencies)

Options

Overview

PHP Form Builder Options are defining HTML wrappers and classes.
Default options are Bootstrap 4 options.
Each can be overwritten the way you want to match other framework

For example, with Bootstrap, each group (label + element) has to be wrapped into a <div class="form-group"></div> and to have a .form-control class

We also need do add .col-sm-x & .control-label to labels,
and to wrap elements with <div class="col-sm-x"></div>.

All will be easily done with Form options.

if needeed, wrappers can contain 2 html elements.
This can be done with elementsWrapper, checkboxWrapper and radioWrapper.

To add input wrapper, see addInputWrapper function.

Default options (Bootstrap 4)

$options = array(
    'ajax'                         => false,
    'deferScripts'                 => true,
    'elementsWrapper'              => '<div class="form-group"></div>',
    'formInlineClass'              => 'form-inline',
    'formHorizontalClass'          => 'form-horizontal',
    'formVerticalClass'            => '',
    'checkboxWrapper'              => '<div class="form-check"></div>',
    'radioWrapper'                 => '<div class="form-check"></div>',
    'helperWrapper'                => '<small class="form-text text-muted"></small>',
    'buttonWrapper'                => '<div class="form-group"></div>',
    'centeredButtonWrapper'        => '<div class="form-group text-center"></div>',
    'centerButtons'                => false,
    'wrapElementsIntoLabels'       => false,
    'wrapCheckboxesIntoLabels'     => false,
    'wrapRadiobtnsIntoLabels'      => false,
    'elementsClass'                => 'form-control',
    'wrapperErrorClass'            => '',
    'elementsErrorClass'           => 'is-invalid',
    'textErrorClass'               => 'invalid-feedback',
    'verticalLabelWrapper'         => false,
    'verticalLabelClass'           => 'form-control-label',
    'verticalCheckboxLabelClass'   => 'form-check-label',
    'verticalRadioLabelClass'      => 'form-check-label',
    'horizontalLabelWrapper'       => false,
    'horizontalLabelClass'         => 'col-form-label',
    'horizontalLabelCol'           => 'col-sm-4',
    'horizontalOffsetCol'          => '',
    'horizontalElementCol'         => 'col-sm-8',
    'inlineCheckboxLabelClass'     => 'form-check-label',
    'inlineRadioLabelClass'        => 'form-check-label',
    'inlineCheckboxWrapper'        => '<div class="form-check form-check-inline"></div>',
    'inlineRadioWrapper'           => '<div class="form-check form-check-inline"></div>',
    'inputGroupAddonClass'         => 'input-group',
    'btnGroupClass'                => 'btn-group',
    'requiredMark'                 => '<sup class="text-danger">* </sup>',
    'openDomReady'                 => 'jQuery(document).ready(function($) {',
    'closeDomReady'                => '});'
);

Example of generated HTML code for each option with Bootstrap 4 framework

ajax if true, render() will generate json code to load with Ajax
deferScripts if true the plugins scripts loading will be deferred
elementsWrapper <div class="form-group">
[<label> ... </label>]
[<input>]
</div>
formInlineClass <form class="form-inline" [...]>
formHorizontalClass <form class="form-horizontal" [...]>
formVerticalClass <form class="form-vertical" [...]>
checkboxWrapper <div class="checkbox">
[<label>]
[<input type="checkbox">[text]]
[</label>]
</div>
radioWrapper <div class="radio">
[<label>]
[<input type="radio">]
[</label>]
</div>
helperWrapper <span class="help-block">[Help text]</span>
buttonWrapper <div class="form-group">
[<label> ... </label>]
[<button> ... </button>]
</div>
centeredButtonWrapper <div class="form-group text-center">
[button]
</div>
centerButtons if true, the form buttons will be automatically centered horizontally.
wrapElementsIntoLabels <label>[input | textarea | ...]</label>
wrapCheckboxesIntoLabels <label>[checkbox]</label>
wrapRadiobtnsIntoLabels <label>[radio]</label>
elementsClass <input class="form-control" [...]>
wrapperErrorClass <div class="[form-group] has-error">
elementsErrorClass <input class="[form-control] error-class" [...]>
textErrorClass <p class="text-danger"> ... </p>
verticalLabelWrapper if true, the labels will be wrapped in a <div class="verticalLabelClass">
verticalLabelClass <div class="verticalLabelClass">[label]</div>
verticalCheckboxLabelClass <label for="[fieldname]" class="verticalCheckboxLabelClass">[text]</label>
verticalRadioLabelClass <label for="[fieldname]" class="verticalRadioLabelClass">[text]</label>
horizontalLabelWrapper if true, the labels will be wrapped in a div with the column class instead of having the column class themselves
horizontalLabelClass,
horizontalLabelCol
<label class="col-sm-4 control-label">...</label>
horizontalOffsetCol // when label is empty, automaticaly offsetting field container
<div class="col-sm-offset-4 [col-sm-8]">
[<input>]
</div>
horizontalElementCol <div class="col-sm-8">
[<input>]
</div>
inlineRadioLabelClass <label class="radio-inline">...</label>
inlineCheckboxLabelClass <label class="checkbox-inline">...</label>
inlineCheckboxWrapper <div class="form-check form-check-inline">
[input type="checkbox"]
[label]
</div>
inlineRadioWrapper <div class="form-check form-check-inline">
[input type="radio"]
[label]
</div>
inputGroupAddonClass <div class="input-group">[input with addon]</div>
btnGroupClass <div class="btn-group">...</div>
requiredMark // required markup is automaticaly added on required fields
<label>my required text<sup class="text-danger"> *</sup></label>
openDomReady
(if not using jQuery,
changes the code your plugins
will be wrapped in)
$(document).ready(function() {
closeDomReady });

Customizing for other framework

If you want to use PHP Form Builder with another framework like Semantic-UI, Pure, Skeleton, UIKit, Milligram, Susy, Bulma, Kube, ..., you have to change the options to match your framework HTML & CSS classes:

$options = array(
    // your options here
);

$form->setOptions($options);

If you always use the same framework, the best way is to create a custom function with your custom config in FormExtended class.

Main functions

General

construct

$form = new Form($form_ID, $layout = 'horizontal', $attr = '', $framework = 'bs4');
    /**
    * Defines the layout (horizontal | vertical | inline).
    * Default is 'horizontal'
    * Clears values from session if self::clear has been called before
    * Catches posted errors
    * Adds hidden field with form ID
    * Sets elements wrappers
    *
    * @param string $form_ID   The ID of the form
    * @param string $layout    (Optional) Can be 'horizontal', 'vertical' or 'inline'
    * @param string $attr      (Optional) Can be any HTML input attribute or js event EXCEPT class
    *                          (class is defined in layout param).
    *                          attributes must be listed separated with commas.
    *                          Example : novalidate,onclick=alert(\'clicked\');
    * @param string $framework (Optional) bs3 | bs4 | material | foundation
    *                          (Bootstrap 3, Bootstrap 4, Material design, Foundation >= 6.4)
    * @return $this
    */

options

Call setOptions() only if you change defaults options

Go to Options for more details

$form->setOptions($options);
    /**
    * Sets form layout options to match your framework
    * @param array $user_options (Optional) An associative array containing the
    *                            options names as keys and values as data.
    */

Mode (production vs. development)

Default mode is production.

$form->setMode($mode);
    /**
     * set the form mode to 'development' or 'production'
     * in production mode, all the plugins dependencies are combined and compressed in a single css or js file.
     * the css | js files are saved in plugins/min/css and plugins/min/js folders.
     * these 2 folders have to be wrirable (chmod 0755+)
     * @param string $mode 'development' | 'production'
     * @return $this
     */

Detailed explanations available here: Optimization (CSS & JS dependencies)

Method

Default method is POST.

Call setMethod() only if you change default method

$form->setMethod($method);
    /**
    * set sending method
    * @param string $method POST|GET
    */

Action

Default action is htmlspecialchars($_SERVER["PHP_SELF"]).

htmlspecialchars prevents attackers from exploiting the code by injecting HTML or Javascript code (Cross-site Scripting attacks) in forms (recommended on http://www.w3schools.com/php/php_form_validation.asp)

Call setAction() only if you change default action

$form->setAction($url, [$add_get_vars = true]);
    /**
    * Redefines form action
    *
    * @param boolean $add_get_vars (Optional) if $add_get_vars is set to false,
    *                              url vars will be removed from destination page.
    *                              Example: www.myUrl.php?var=value => www.myUrl.php
    */

Start Fieldset

Start your fieldset with optional legend.
Don't forget to call endFieldset to end your fieldset.

You can add several fieldsets on the same form.

$form->startFieldset('legend', $fieldset_attr = '', $legend_attr = '');
    /**
    * Starts a fieldset tag.
    * @param string $legend (Optional) Legend of the fieldset.
    * @param string $fieldset_attr (Optional) Fieldset attributes.
    * @param string $legend_attr (Optional) Legend attributes.
    */

End Fieldset

$form->endFieldset();
    /**
    * Ends a fieldset tag.
    */

startDependentFields

Start a dependent fields block.
dependent fields block is hidden and will be shown if $parent_field changes to one of $show_values.
Don't forget to call endDependentFields to end your Dependent Fields block.

if $inverse is true, dependent fields will be shown if any other value than $show_values is selected

Each Dependent fields block can include one or several dependent fields blocks.

Dependent fields MUST NOT START with the same fieldname as their parent field.

$form->startDependentFields($parent_field, $show_values[, $inverse = false]);
    /**
    * Start a hidden block
    * which can contain any element and html
    * Hiden block will be shown on $parent_field change
    * if $parent_field value matches one of $show_values
    * @param  string $parent_field name of the field which will trigger show/hide
    * @param  string $show_values  single value or comma separated values which will trigger show.
    * @param  boolean $inverse  if true, dependent fields will be shown if any other value than $show_values is selected.
    * @return void
    */

Live examples with code are available here: jquery-plugins.php#dependent-fields-example

endDependentFields

$form->endDependentFields();
    /**
    * Ends Dependent Fields block.
    */

$attr argument

Several element functions use a $attr argument.

The $attr argument accepts any html attribute or javascript event.

Use comma separated values (see examples below).

Examples

    $form->addInput('text', 'name', '', 'Your name: ', 'id=my-id, placeholder=My Text, required=required');
    $form->addInput('password', 'pass', '', 'Your password: ', 'required=required, pattern=(.){7\,15}');
    $form->addTextarea('my-textarea', '', 'Your message: ', 'cols=30, rows=4');
    $form->addBtn('button', 'myBtnName', 1, 'Cancel', 'class=btn btn-danger, onclick=alert(\'cancelled\');');

Elements

Input

$form->addInput($type, $name [, $value = '', $label = '', $attr = '']);
    /**
    * Adds input to the form
    *
    * @param string $type Accepts all input html5 types except checkbox and radio:
    *                      button, color, date, datetime, datetime-local,
    *                      email, file, hidden, image, month, number, password,
    *                      range, reset, search, submit, tel, text, time, url, week
    * @param string $name The input name
    * @param string $value (Optional) The input default value
    * @param string $label (Optional) The input label
    * @param string $attr (Optional) Can be any HTML input attribute or js event.
    *                                attributes must be listed separated with commas.
    *                                If you don't specify any ID as attr, the ID will be the name of the input.
    *                                Example: class=my-class,placeholder=My Text,onclick=alert(\'clicked\');
    */

Input Groups

Input Groups allow to have several inputs / selects on the same line in horizontal forms.

Up to 12 elements can be grouped.

2 ways to set arguments:

  •     // 1st way: each fieldname as argument
        $form->groupInputs('street', 'zip', 'countries');
  •     // 2nd way: a single array including all fieldnames as argument
        $fields = array('street', 'zip', 'countries');
        $form->groupInputs($fields);

Always create your input group BEFORE creating the input elements.

$form->groupInputs($input1, $input2 [, $input3 = '', $input4 = '', $input5 = '', $input6 = '', $input7 = '', $input8 = '', $input9 = '', $input10 = '', $input11 = '', $input12 = '']);
    /**
    * Allows to group inputs in the same wrapper
    *
    * Arguments can be:
    *     -    a single array with fieldnames to group
    *     OR
    *     -    fieldnames given as string
    *
    * @param string|array $input1 The name of the first input of the group
    *                             OR
    *                             array including all fieldnames
    *
    * @param string $input2 The name of the second input of the group
    * @param string $input3 [optional] The name of the third input of the group
    * @param string $input4 [optional] The name of the fourth input of the group
    * @param string ...etc.
    */

Input Groups Example

    $form->startFieldset('Personal informations');
    $form->groupInputs('street', 'zip', 'countries');
    $form->setCols(3, 4);
    $form->addInput('text', 'street', '', 'Your address: ', 'placeholder=street,required=required');
    $form->setCols(0, 2);
    $form->addInput('text', 'zip', '', '', 'placeholder=zip code,required=required');
    $form->setCols(0, 3);
    $form->addOption('countries', '', 'Countries');
    $form->addOption('countries', 'United States', 'United States');
    $form->addOption('countries', 'Canada', 'Canada');
    $form->addOption('countries', 'France', 'France');
    $form->addSelect('countries', '', '');
    $form->endFieldset();
Personal informations

Textarea

$form->addTextarea($name, $value [, $label, $attr]);
    /**
    * Adds textarea to the form
    * @param string $name The textarea name
    * @param string $value (Optional) The textarea default value
    * @param string $label (Optional) The textarea label
    * @param string $attr (Optional) Can be any HTML input attribute or js event.
    *                                attributes must be listed separated with commas.
    *                                If you don't specify any ID as attr, the ID will be the name of the textarea.
    *                                Example: cols=30, rows=4;.
    */

Options for Select list

Always add your options BEFORE creating the select element

  1. 1 Add your options
  2. 2 Create your select
$form->addOption($selectName, $value, $txt [, $group_name, $attr]);
    /**
    * Adds option to the $select_name element
    *
    * @param string $select_name The name of the select element
    * @param string $value The option value
    * @param string $txt The text that will be displayed
    * @param string $group_name (Optional) the optgroup name
    * @param string $attr (Optional) Can be any HTML input attribute or js event.
    *                                attributes must be listed separated with commas.
    *                                If you don't specify any ID as attr, the ID will be the name of the option.
    *                                Example: class=my-class
    */

Select list

$form->addSelect($selectName, $label [, $attr = '', $displayGroupLabels = true]);

addSelect() function plays nice with bootstrap-select plugin and select2 plugin.

Just add selectpicker class for Bootstrap select or select2 class for Select2 plugin, data-attributes and phpformbuilder will do the job..

Don't forget to activate your plugins to add the required css/js files to your page.

    /**
    * Adds a select element
    *
    * IMPORTANT: Always add your options BEFORE creating the select element
    *
    * @param string $select_name The name of the select element
    * @param string $label (Optional) The select label
    * @param string $attr (Optional)  Can be any HTML input attribute or js event.
    *                                 attributes must be listed separated with commas.
    *                                 If you don't specify any ID as attr, the ID will be the name of the input.
    *                                 Example: class=my-class
    * @param string $displayGroupLabels (Optional) True or false.
    *                                              Default is true.
    */

Example with optgroup

    $form->addOption('select-with-groupnames', 'option-1', 'option 1', 'group 1');
    $form->addOption('select-with-groupnames', 'option-2', 'option 2', 'group 1', 'selected=selected');
    $form->addOption('select-with-groupnames', 'option-3', 'option 3', 'group 1');
    $form->addOption('select-with-groupnames', 'option-4', 'option 4', 'group 2');
    $form->addOption('select-with-groupnames', 'option-5', 'option 5', 'group 2');
    $form->addSelect('select-with-groupnames', 'Select please: ', '');

Example with multiple selections

    for ($i=1; $i < 11; $i++) {
        $form->addOption('myMultipleSelectName[]', $i, 'option ' . $i);
    }
    $form->addSelect('myMultipleSelectName[]', 'Select please:
(multiple selections)', 'multiple=multiple');

Country Select list

Always add your options BEFORE creating the select element

Country Select uses the bootstrap-select plugin, which requires Bootstrap's dropdown in your bootstrap.min.js

$form->addCountrySelect($select_name [, $label = '', $attr = '', $user_options = array()]);
    /**
    * adds a country select list with flags
    * @param array  $select_name
    * @param string $label        (Optional) The select label
    * @param string $attr         (Optional)  Can be any HTML input attribute or js event.
    *                             attributes must be listed separated with commas.
    *                             If you don't specify any ID as attr, the ID will be the name of the input.
    *                             Example: class=my-class
    * @param array  $user_options (Optional):
    *                             lang          : MUST correspond to one subfolder of [PLUGINS_DIR]countries/country-list/country/cldr/
    *                             *** for example 'en', or 'fr_FR'              Default: 'en'
    *                             flags         : true or false.              Default: true
    *                             *** displays flags into option list
    *                             flag_size     : 16 or 32                    Default: 32
    *                             return_value  : 'name' or 'code'            Default: 'name'
    *                             *** type of the value that will be returned
    *                             show_tick     : true or false
    *                             *** shows a checkmark beside selected options Default: true
    *                             live_search   : true or false               Default: true
    */

Live examples with code are available here:
jquery-plugins.php#bootstrap-select-example
jquery-plugins.php#select2-example

Radio Btns

  1. Add your radio buttons
  2. Call printRadioGroup
$form->addRadio($group_name, $label, $value [, $attr = '']);
    /**
    * Adds radio button to $group_name element
    *
    * @param string $group_name The radio button groupname
    * @param string $label The radio button label
    * @param string $value The radio button value
    * @param string $attr  (Optional) Can be any HTML input attribute or js event.
    *                      attributes must be listed separated with commas.
    *                      Example: checked=checked
    */

Print Radio Group

$form->printRadioGroup($group_name, $label [, $inline = true, $attr = '']);
    /**
    * Prints radio buttons group.
    *
    * @param string $group_name The radio button group name
    * @param string $label (Optional) The radio buttons group label
    * @param string $inline (Optional) True or false.
    *                                  Default is true.
    * @param string $attr (Optional) Can be any HTML input attribute or js event.
    *                       attributes must be listed separated with commas.
    *                       If you don't specify any ID as attr, the ID will be the name of the input.
    *                       Example: class=my-class
    */

Example

    $form->addRadio('myRadioBtnGroup', 'choice one', 'value 1');
    $form->addRadio('myRadioBtnGroup', 'choice two', 'value 2', 'checked=checked');
    $form->addRadio('myRadioBtnGroup', 'choice three', 'value 3');
    $form->printRadioGroup('myRadioBtnGroup', 'Choose one please', true, 'required=required');

Several plugins are available to replace the ugly browser default radio buttons with nice ones:

Checkboxes

  1. Add your checkboxes
  2. Call printCheckboxGroup
$form->addCheckbox($group_name, $label, $value [, $attr = '']);
    /**
    * Adds checkbox to $group_name
    *
    * @param string $group_name The checkbox groupname (will be converted to an array of indexed value)
    * @param string $label The checkbox label
    * @param string $value The checkbox value
    * @param string $attr  (Optional) Can be any HTML input attribute or js event.
    *                      attributes must be listed separated with commas.
    *                      Example: checked=checked
    */

Print Checkbox Group

$form->printCheckboxGroup($group_name, $label [, $inline = true, $attr = '']);
    /**
    * Prints checkbox group.
    *
    * @param string $var (Optional) description
    *
    * @param string $group_name The checkbox button group name
    * @param string $label (Optional) The checkbox group label
    * @param string $inline (Optional) True or false.
    *                                  Default is true.
    * @param string $attr (Optional) Can be any HTML input attribute or js event.
    *                       attributes must be listed separated with commas.
    *                       If you don't specify any ID as attr, the ID will be the name of the input.
    *                       Example: class=my-class
    */

Example

    $form->addCheckbox('myCheckboxGroup', 'choice one', 'value 1');
    $form->addCheckbox('myCheckboxGroup', 'choice two', 'value 2', 'checked=checked');
    $form->addCheckbox('myCheckboxGroup', 'choice three', 'value 3', 'checked=checked');
    $form->printCheckboxGroup('myCheckboxGroup', 'Check please: ', true, 'required=required');

Several plugins are available to replace the ugly browser default checkboxes with nice ones:

Buttons

For a single button, just call addBtn() and let $btnGroupName empty.

For button group, call addBtn() for each button, give a name to $btnGroupName, then call printBtnGroup()

$form->addBtn($type, $name, $value, $text [, $attr = '', $btnGroupName = '']);
    /**
    * Adds button to the form
    *
    * If $btnGroupName is empty, the button will be automaticaly displayed.
    * Otherwise, you'll have to call printBtnGroup to display your btnGroup.
    *
    * @param string $type The html button type
    * @param string $name The button name
    * @param string $value The button value
    * @param string $text The button text
    * @param string $attr (Optional) Can be any HTML input attribute or js event.
    *                                 attributes must be listed separated with commas.
    *                                 If you don't specify any ID as attr, the ID will be the name of the input.
    *                                 Example: class=my-class,onclick=alert(\'clicked\');
    * @param string $btnGroupName (Optional) If you want to group several buttons, group them then call printBtnGroup.
    *
    */

Print Btn Group

$form->printBtnGroup($btnGroupName);
    /**
    * Prints buttons group.
    *
    * @param string $btnGroupName The buttons group name
    * @param string $label (Optional) The buttons group label
    *
    */

Single button example

$form->addBtn('submit', 'myBtnName', 1, 'Submit form', 'class=btn btn-primary');

Button group example

    $form->addBtn('submit', 'mySubmitBtnName', 1, 'Submit form', 'class=btn btn-primary', 'myBtnGroup');
    $form->addBtn('button', 'myCancelBtnName', 0, 'Cancel', 'class=btn btn-danger, onclick=alert(\'cancelled\');', 'myBtnGroup');
    $form->printBtnGroup('myBtnGroup');

Custom HTML

You can add some html code at any place you want when creating your form.

This way, you can:

$form->addHtml($html [, $element_name = '', $pos = 'after']);
    /**
    * Adds HTML code at any place of the form
    *
    * @param string $html The html code to add.
    * @param string $element_name (Optional) If not empty, the html code will be inserted.
    *                                        just before or after the element.
    * @param string $pos (Optional) If $element_name is not empty, defines the position
    *                               of the inserted html code.
    *                               Values can be 'before' or 'after'.
    */

When your HTML is linked to an element, always call addHtml() BEFORE creating the element

To add helper texts icons buttons or any input group addon it'll be even better to use the shortcut functions:

Add HTML between elements

    $form->addInput('text', 'input-name', '', 'Your name: ');
    $form->addHtml('<p class="alert alert-danger">Your e-mail address is required</p>');
    $form->addInput('text', 'email', '', 'Your e-mail', 'required');

Your e-mail address is required

Prepend or append HTML to elements

    $form->addInput('text', 'input-name-2', '', 'Your name: ');
    $form->addHtml('<p class="form-text alert alert-danger">Your e-mail address is required</p>', 'email-2', 'after');
    $form->addInput('text', 'email-2', '', 'Your e-mail', 'required');

Your e-mail address is required

Custom html with input wrapper

wrapper can be one or two html elements

$form->addInputWrapper($html, $element_name);
    /**
    * Wraps the element with html code.
    *
    * @param string $html The html code to wrap the element with.
    *                     The html tag must be opened and closed.
    *                     Example: <div class="my-class"></div>
    * @param string $element_name The form element to wrap.
    */

Example

    $form->addInputWrapper('<div class="bg-dark rounded p-2"><div class="bg-white rounded p-2"></div></div>', 'imput-wrapped');
    $form->addInput('text', 'imput-wrapped', '', 'Input wrapped with custom divs');

Render

Renders the form.

Set $debug to true if you wants to display HTML code

Set $display to false if you wants to return HTML code but not display on page

$form->render([$debug = false, $display = true]);
    /**
    * Renders the html code of the form.
    *
    * @param boolean $debug   (Optional) True or false.
    *                         If true, the html code will be displayed
    * @param boolean $display (Optional) True or false.
    *                         If false, the html code will be returned but not displayed.
    *
    */

Ajax loading

PHP Form Builder allows you to load your forms with Ajax.

Loading in Ajax allows to:

  • integrate your forms in any html page
  • load the forms asynchronously, which is good for your page loading speed

To load your form with Ajax:

  1. 1 Create your form using the built-in PHP functions and save it in a php file somewhere on your server.
    Set the ajax option to true to enable Ajax loading.
    Here's a sample code:
    <?php
    
    use phpformbuilder\Form;
    use phpformbuilder\Validator\Validator;
    
    /* =============================================
        start session and include form class
    ============================================= */
    
    $form_id = 'my-form';
    
    session_start();
    include_once rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . '/phpformbuilder/Form.php';
    
    /* =============================================
        validation if posted
    ============================================= */
    
    if ($_SERVER["REQUEST_METHOD"] == "POST" && Form::testToken($form_id) === true) {
        // do stuff
    }
    
    /* ==================================================
        The Form
    ================================================== */
    
    $form = new Form($form_id, 'horizontal', 'data-fv-no-icon=true, novalidate');
    // $form->setMode('development');
    
    // enable Ajax loading
    $form->setOptions(['ajax' => true]);
    
    // add your fields & plugins here
    
    // render the form
    $form->render();
    
  2. 2 In your main file (html):
    Create a div with a specific id, for instance:
    <div id="ajax-form"></div>
  3. 3 In your main file (html):
    Add the Javascript code to load your form:
    
    
        <script>
        var $head= document.getElementsByTagName('head')[0],
            target = '#ajax-form'; // replace with the id of your div
    
        var loadData = function(data, index) {
            if (index <= $(data).length) {
                var that = $(data).get(index);
                if ($(that).is('script')) {
                    // output script
                    var script = document.createElement('script');
                    script.type = 'text/javascript';
                    if (that.src != '') {
                        script.src = that.src;
                        script.onload = function() {
                            loadData(data, index + 1);
                        };
                        $head.append(script);
                    } else {
                        script.text = that.text;
                        $('body').append(script);
                        loadData(data, index + 1);
                    }
                } else {
                    // output form html
                    $(target).append($(that));
                    loadData(data, index + 1);
                }
            } else {
                $.holdReady(false);
            }
        };
    
        $(document).ready(function() {
            $.ajax({
                url: 'ajax-forms/contact-form-1.php', // replace with the url of your php form
                type: 'GET'
            }).done(function(data) {
                $.holdReady(true);
                loadData(data, 0);
            }).fail(function(data, status, error) {
                console.log(error);
            });
        });
        </script>

You'll find an example here: https://www.phpformbuilder.pro/templates/bootstrap-4-forms/ajax-loaded-contact-form-1.html

useLoadJs

Use the great LoadJs library to load CSS & Javascript plugins dependencies.

This feature is great for optimization ; it requires to include the LoadJs Javascript library in your page

Details & sample codes here: jquery-plugins.php#optimization-with-loadjs

$form->useLoadJs($bundle = '');
    /**
    * load scripts with loadJS
    * https://github.com/muicss/loadjs
    * @param  string $bundle   optional loadjs bundle name to wait for
    * @return void
    */

Print plugins includes

The printIncludes() function is used to insert the CSS & Javascript files required by each plugin used in your form.

Call printIncludes() at the right places (generally css inside your <head></head> section, and js just before </body>.

If your form contains no plugin, no need to call this function.

printIncludes($type, $debug = false, $display = true, $combine_and_compress = true);
    /**
    * Prints html code to include css or js dependancies required by plugins.
    * i.e.:
    *     <link rel="stylesheet" ... />
    *     <script src="..."></script>
    *
    * @param string  $type                 value : 'css' or 'js'
    * @param boolean $debug                (Optional) True or false.
    *                                      If true, the html code will be displayed
    * @param boolean $display              (Optional) True or false.
    *                                      If false, the html code will be returned but not displayed.
    * @param boolean $combine_and_compress (Optional) True or false.
    *                                      If true, dependancies are combined and compressed into plugins/min/ folder.
    * @return $this
    */

About optimization

PHP Form Builder is conceived for maximum optimization and extremely fast loading time.

Detailed explanations available here: Optimization (CSS & JS dependencies)

Example with colorpicker plugin

    $form->addInput('text', 'my-colorpicker', '', 'ColorPicker: ');
    $form->addPlugin('colorpicker', '#my-colorpicker');

    // call this just before </head>
    $form->printIncludes('css');
<link href="../../phpformbuilder/plugins/colpick/css/colpick.css" rel="stylesheet" media="screen">

    $form->addInput('text', 'my-colorpicker', '', 'ColorPicker: ');
    $form->addPlugin('colorpicker', '#my-colorpicker');

    // call this just before </body>
    $form->printIncludes('js');
<script src="../../phpformbuilder/plugins/colpick/js/colpick.js"></script>

Print plugins JS code

Prints the JS code generated by the plugin.

If your form contains no plugin, no need to call this function.

$form->printJsCode($debug = false);
    /**
    * Prints js code generated by plugins.
    * @param boolean $debug   (Optional) True or false.
    *                         If true, the html code will be displayed
    * @param boolean $display (Optional) True or false.
    *                         If false, the html code will be returned but not displayed.
    */

Example with colorpicker plugin

    $form->addInput('text', 'my-colorpicker', '', 'ColorPicker: ');
    $form->addPlugin('colorpicker', '#my-colorpicker');
    $form->printJsCode();
    <script type="text/javascript">
        $(document).ready(function() {
            $("#my-colorpicker").colpick({
                onSubmit:function(hsb,hex,rgb,el) {
                    $(el).val('#'+hex);
                    $(el).colpickHide();
                }
            });
        });
    </script>

Set Cols

The setCols() function wraps label and fields with columns.

The columns can only be set in horizontal forms.

$form->setCols($labelsCols, $fieldsCols [, $breakpoint = 'sm']);

Bootstrap 4 auto column
Bootstrap 4 allows automatic-width columns.
To build automatic-width columns, set $fieldsCols to -1

    /**
    * Shortcut for
    * $options = array(
    *        'horizontalLabelCol'       => 'col-' . $breakpoint . '-' . $labelsCols,
    *        'horizontalOffsetCol'      => 'col-' . $breakpoint . '-offset-' . $labelsCols,
    *        'horizontalElementCol'     => 'col-' . $breakpoint . '-' . $fieldsCols,
    * );
    * $form->setOptions($options);
    *
    * @param number $labelsCols number of columns for label
    * @param number $fieldsCols number of columns for fields
    * @param string $breakpoint Bootstrap's breakpoints: xs | sm | md |lg
    *
    */

Example

$form->setCols(3, 9);
$form->addInput('text', 'username', '', 'Name');
Will generate the following markup:
    <div class="form-group row justify-content-end">
        <label for="username" class="col-sm-3 col-form-label">
            Name
        </label>
        <div class="col-sm-9">
            <input id="username" name="username" type="text" value=""  class="form-control">
        </div>
    </div>
Equivalent to:
    $options = array(
        'horizontalLabelCol'       => 'col-sm-3',
        'horizontalElementCol'     => 'col-sm-9'
    );
    $form->setOptions($options);
    $form->addInput('text', 'username', '', 'Name');

Bootstrap 4 automatic-width example

    $form->setCols(-1, -1, 'sm');
    $form->groupInputs('user-name', 'user-first-name');
    $form->addInput('text', 'user-name', '', 'Name', 'required, placeholder=Name');
    $form->addInput('text', 'user-first-name', '', 'First name', 'required, placeholder=First Name');

    $form->setCols(-1, -1); // without breakpoint
    $form->addIcon('user-email', '<i class="fa fa-envelope" aria-hidden="true"></i>', 'before');
    $form->addInput('email', 'user-email', '', '', 'required, placeholder=Email');
Will generate the following markup:
    <div class="form-group row justify-content-end">
        <label for="user-name" class="col-sm col-form-label">
            Name <sup class="text-danger">* </sup>
        </label>
        <div class="col-sm">
            <input id="user-name" name="user-name" type="text" value="" required placeholder="Name" class="form-control fv-group">
        </div>
        <label for="user-first-name" class="col-sm col-form-label">
            First name <sup class="text-danger">* </sup>
        </label>
        <div class="col-sm">
            <input id="user-first-name" name="user-first-name" type="text" value="" required placeholder="First Name" class="form-control fv-group">
        </div>
    </div>
    <div class="form-group row justify-content-end">
        <div class=" col-sm">
            <div class="input-group">
                <div class="input-group-prepend">
                    <span class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></span>
        </div>
        <input id="user-email" name="user-email" type="email" value="" required placeholder="Email" class="form-control">
    </div>

Add Helper

Adds helper text after the chosen field

$form->addHelper($helper_text, $element_name);

addHelper() MUST always be called BEFORE creating the element

    /**
    * Shortcut to add element helper text
    *
    * @param string $helper_text    The helper text or html to add.
    * @param string $element_name   the helper text will be inserted just after the element.
    */

Example

    $form->addHelper('Enter your last name', 'last-name');
    $form->addInput('text', 'last-name', '', 'Last name', 'required');
Enter your last name

Add Addon

Adds button or text addon before or after the chosen field

$form->addAddon($input_name, $addon_html, $pos);
    /**
    * shortcut to prepend or append button or text addon to an input
    * @param string $input_name the name of target input
    * @param string $addon_html  button or text addon html code
    * @param string $pos        before | after
    */

Example

    $addon = '<button class="btn btn-secondary" type="button" onclick="$(\'#input-with-button-after\').val(\'\');">cancel</button>';
    $form->addAddon('input-with-button-after', $addon, 'after');
    $form->addInput('text', 'input-with-button-after', '', 'Your name');

Add Icon

Adds an icon before or after the chosen field

$form->addIcon($input_name, $icon_html, $pos);
    /**
    * shortcut to prepend or append icon to an input
    * @param string $input_name the name of target input
    * @param string $icon_html  icon html code
    * @param string $pos        before | after
    */

Example

    $form->addIcon('username', '<i class="fa fa-user" aria-hidden="true"></i>', 'before');
    $form->addInput('text', 'username', '', 'Name');

centerButtons

Center buttons inside their wrapper

$form->centerButtons($center);
    /**
    * @param  boolean $center
    */

Example

    $form->centerButtons(true);
    $form->addBtn('submit', 'submit-btn', 1, 'Submit', 'class=btn btn-success');

E-mail Sending

sendMail() function

$sent_message = Form::send($options, $smtp_settings = array());

See details at E-mail Sending

Registering / Clearing values

Global registration process

PHP Form Builder manages the memorization of fields and posted values without you needing to take any action.

If your form is posted with errors (validation fails), the posted values are automatically displayed in the corresponding fields.

To set the default value of a field, it must be saved in the PHP session in this way:

$_SESSION['form-id']['field-name'] = 'my-value';

If the form is posted, the field will have the posted value. Otherwise it will have the default value registered in the PHP session.

Here's the global workflow:

  1. You create your form and add fields.
    PHP Form Builder registers each field name in PHP session: $_SESSION['form-id']['fields'][] = 'field-name';
  2. You post the form
  3. You validate the posted values: $validator = Form::validate('form-id');
  4. If the validation fails:
    The error messages are stored in PHP session: $_SESSION['errors'][$form_ID] as $field => $message
  5. You instanciate your form again:
    PHP Form Builder registers the posted values in PHP session: $_SESSION['form-id']['field-name'] = $_POST['my-value'];
    PHP Form Builder gets and displays the session value and the possible error for each field.

registerValues (static function)

When you instantiate a form, it automatically stores corresponding posted values in session unless you called clear function before creating your form.

Values are registered this way: $_SESSION['form-id']['field-name']

You can call Form::registerValues('form-id') manually at any time.

Form::registerValues('form-id');
    /**
    * register all posted values in session
    * @param string $form_ID
    *
    * ex: $_SESSION['form-id']['field-name'] = $_POST['field-name'];
    */

mergeValues (static function)

mergeValues is used to merge previously registered values in a single array.
Usefull for step forms to send all steps values by email or store into database for example.

Form::mergeValues(array('step-form-1', 'step-form-2', 'step-form-3'));
    /**
    * merge previously registered session vars => values of each registered form
    * @param  array $forms_array array of forms IDs to merge
    * @return array pairs of names => values
    *                           ex: $values[$field_name] = $value
    */

clear (static function)

Clears the corresponding previously registered values from session.

Form::clear('form-id');

Validation

Overview

PHP Form Builder comes with 2 distinct validation systems.

  1. PHP Validation
    Form is validated after being posted. This is a php validation, essential for security.
  2. jQuery Validation
    Fields are validated on the fly, for better User Experience.

Never forget: The only way to avoid security issues is PHP Validation.
Users can easily disable Javascript, and get around jQuery validation.

PHP Validation

Basics

To create a new validator object and auto-validate required fields, use this standard-code
(replace 'form-id' with your form ID)

    /* =============================================
    validation if posted
    ============================================= */

    if ($_SERVER["REQUEST_METHOD"] == "POST" && Form::testToken('form-id') === true) {

        // create validator & auto-validate required fields
        $validator = Form::validate('form-id');

        // additional validation
        $validator->maxLength(100)->validate('message');
        $validator->email()->validate('user-email');

        // check for errors
        if ($validator->hasErrors()) {
        $_SESSION['errors']['form-id'] = $validator->getAllErrors();
        } else {
            // validation passed, you can send email or do anything
        }
    }
$validator = Form::validate('form-id');
This loads Validator class, creates a new Validator object and validate required fields if any.
Required fields validation is automatic, nothing more to do.
    // additional validation
    $validator->maxLength(100)->validate('message');
    $validator->email()->validate('user-email');
Then we use $validator native methods for others validations
(email, date, length, ...)
    // check for errors
    if ($validator->hasErrors()) {
        $_SESSION['errors']['form-id'] = $validator->getAllErrors();
    }
If any error, we register them in session.
Error messages will be automatically displayed in form.

Dependent fields validation

Dependent fields validation is something really magic.

Form::validate() validates the required dependent fields only if their parent field value matches the condition to display them.

If you use additional validators, for example $validator->email()->validate('user-email'); you have to test if the field has to be validated or not according to your dependent fields conditions:

    if ($_POST['parent-field'] == 'value') {
        $validator->email()->validate('user-email');
    }

Php Validator Methods

To validate array, use the dot syntax.

Example: <select name="my-field[]" multiple="multiple">

    $validator->required()->validate('my-field.0');

    /* if at least 2 values must be selected: */

    $validator->required()->validate(array('my-field.0', 'my-field.1'));

The validation is done with blackbelt's php-validation class.

Complete documentation at https://github.com/blackbelt/php-validation.

I just added these features:

  • Captcha validation support for the included captcha plugin
  • Multilanguage support
  • Patterns validation for the included passfield plugin:
    • $validator->hasLowercase()->validate($field_name);
    • $validator->hasUppercase()->validate($field_name);
    • $validator->hasNumber()->validate($field_name);
    • $validator->hasSymbol()->validate($field_name);
    • $validator->hasPattern('/custom_regex/')->validate($field_name);

Available methods:

Requiredcaptcha($field, $message = null)
Added to validate included captcha plugin.
Requiredrecaptcha($secret_key, $message = null)
Added to validate included recaptcha plugin.
Requiredrequired($message = null)
The field value is required.
Optionalemail($message = null)
The field value must be a valid email address string.
Optionalfloat($message = null)
The field value must be a float.
Optionalinteger($message = null)
The field value must be an integer.
Optionaldigits($message = null)
The field value must be a digit (integer with no upper bounds).
Requiredmin($limit, $include = TRUE, $message = null)
The field value must be greater than $limit (numeric). $include defines if the value can be equal to the limit.
Optionalmax($limit, $include = TRUE, $message = null)
The field value must be less than $limit (numeric). $include defines if the value can be equal to the limit.
Requiredbetween($min, $max, $include = TRUE, $message = null)
The field value must be between $min and $max (numeric). $include defines if the value can be equal to $min and $max.
RequiredminLength($length, $message = null)
The field value must be greater than or equal to $length characters.
OptionalmaxLength($length, $message = null)
The field value must be less than or equal to $length characters.
Requiredlength($length, $message = null)
The field must be $length characters long.
Requiredmatches($field, $label, $message = null)
One field matches another one (i.e. password matching)
OptionalnotMatches($field, $label, $message = null)
The field value must not match the value of $field.
RequiredstartsWith($sub, $message = null)
The field must start with $sub as a string.
OptionalnotStartsWith($sub, $message = null)
The field must not start with $sub as a string.
RequiredendsWith($sub, $message = null)
THe field must end with $sub as a string.
OptionalnotEndsWith($sub, $message = null)
The field must not end with $sub as a string.
Optionalip($message = null)
The field value is a valid IP, determined using filter_var.
Optionalurl($message = null)
The field value is a valid URL, determined using filter_var.
Optionaldate($message = null)
The field value is a valid date, can be of any format accepted by DateTime()
RequiredminDate($date, $format, $message = null)
The date must be greater than $date. $format must be of a format on the page http://php.net/manual/en/datetime.createfromformat.php
RequiredmaxDate($date, $format, $message = null)
The date must be less than $date. $format must be of a format on the page http://php.net/manual/en/datetime.createfromformat.php
Optionalccnum($message = null)
The field value must be a valid credit card number.
RequiredoneOf($allowed, $message = null)
The field value must be one of the $allowed values. $allowed can be either an array or a comma-separated list of values. If comma separated, do not include spaces unless intended for matching.
RequiredhasLowercase($message = '')
The field value must contain at least 1 lowercase character.
RequiredhasUppercase($message = '')
The field value must contain at least 1 uppercase character.
RequiredhasNumber($message = '')
The field value must contain at least 1 numeric character.
RequiredhasSymbol($message = '')
The field value must contain at least 1 symbol character.
RequiredhasPattern($pattern, $message = '')
The field value must match regex.
Optionalcallback($callback, $message = '', $params = array())
Define your own custom callback validation function. $callback must pass an is_callable() check. $params can be any value, or an array if multiple parameters must be passed.
Required
: Empty fields are NOT VALID
Optional
: Empty fields are VALID

Validation examples

Validation examples code

Main validation code

    if ($_SERVER["REQUEST_METHOD"] == "POST" && Form::testToken('my-form-id') === true) {

        // create validator & auto-validate required fields
        $validator = Form::validate('contact-form-1');

        // additional validation
        $validator->email()->validate('email-field-name');

        // add custom message if you want:
        $validator->integer('You must enter a number')->validate('number-field-name');

        $validator->captcha('captcha')->validate('captcha-field-name');

        // check for errors
        if ($validator->hasErrors()) {
            $_SESSION['errors']['my-form-id'] = $validator->getAllErrors();
        }
    }

Checkboxes validation

If we want at least one checked:

    $form->addCheckbox('chk_group', 'check 1', 1);
    $form->addCheckbox('chk_group', 'check 2', 2);
    $form->addCheckbox('chk_group', 'check 3', 3);
    $form->printCheckboxGroup('chk_group', 'check one: ');

    /* Validation: */

    if(!isset($_POST['chk_group']) || !is_array($_POST['chk_group'])) {

        /* if none posted, we register error */

        $validator->required('check at least one checkbox please')->validate('chk_group');
    }

Trigger an error manually

If we want at least 2 checked:

    $form->addCheckbox('chk_group', 'check 1', 1);
    $form->addCheckbox('chk_group', 'check 2', 2);
    $form->addCheckbox('chk_group', 'check 3', 3);
    $form->printCheckboxGroup('chk_group', 'check at least 2: ');

    /* Validation: */

    if(!isset($_POST['chk_group']) || !is_array($_POST['chk_group']) || count($_POST['chk_group']) < 2) {

        /* if less than 2 posted, we create a tricky validation which always throws an error */

        $validator->maxLength(-1, 'Check at least 2 please')->validate('chk_group');
    }

Radio validation

    $form->addRadio('rating', 'Good', 'Good');
    $form->addRadio('rating', 'Fair', 'Fair');
    $form->addRadio('rating', 'Poor', 'Poor');
    $form->printRadioGroup('rating', 'Rate please: ', false, 'required=required');

    /* Validation: */

    $validator->required('Please rate')->validate('rating');
    

Multiple select validation

    $form->addOption('product-choice[]', 'Books', 'Books');
    $form->addOption('product-choice[]', 'Music', 'Music');
    $form->addOption('product-choice[]', 'Photos', 'Photos');
    $form->addSelect('product-choice[]', 'What products are you interested in ?
(multiple choices)', 'required=required, multiple=multiple, style=min-height:130px'); /* Validation: */ $validator->required('Please choose one or several product(s)')->validate('product-choice.0');

Recaptcha validation

    $form->addRecaptcha('YOUR_RECAPTCHA_KEY_HERE');

    /* Validation: */

    $validator->recaptcha('YOUR_RECAPTCHA_SECRET_KEY_HERE', 'Recaptcha Error')->validate('g-recaptcha-response');

Conditional validation

    if ($_SERVER["REQUEST_METHOD"] == "POST" && Form::testToken('my-form-id') === true) {

        // 'field_name' will be validated only if $_POST['parent_field_name'] === 'Yes'
        $_SESSION['my-form-id']['required_fields_conditions']['field_name'] = array(
            'parent_field'  => 'parent_field_name',
            'show_values'   => 'Yes',
            'inverse'       => false
        );

        // create validator & auto-validate required fields
        $validator = Form::validate('my-form-id');

        // check for errors
        if ($validator->hasErrors()) {
            $_SESSION['errors']['my-form-id'] = $validator->getAllErrors();
        }
    }

Validation multilanguage support

Default language is 'en' (English).

Current available languages are:

  • de
  • en
  • es
  • fr
  • pt_br

If you need other language support:

  1. Add your language to form/Validator/Validator.php => _getDefaultMessage($rule, $args = null)
  2. instantiate with your language as second argument:
    $validator = Form::validate('contact-form-1', 'fr');

If you add your own language, please share it so it can benefit to other users.

Real time Validation (jQuery)

Getting started

Real time Validation is done with formvalidation plugin.

  1. Call plugin like you would do with any other plugin:
    $form->addPlugin('formvalidation', '#my-form'); // replace "my-form" with your form name
  2. Fields with the following HTML5 types/attributes will be automatically validated:
        min="..."
        max="..."
        maxlength="..."
        minlength="..."
        pattern="..."
        required
        type="color"
        type="email"
        type="range"
        type="url"
    More details here: https://formvalidation.io/guide/plugins/declarative/#example-using-html-5-inputs-and-attributes
  3. To add any custom validation, use HTML5 attributes with validatorname and validator option:
    <?php
        $form->addInput('text', 'username', 'Username', '', 'data-fv-not-empty, data-fv-not-empty___message=The username is required and cannot be empty');

    Complete list of HTML5 validation attributes available at https://formvalidation.io/guide/plugins/declarative/#example-using-html-5-inputs-and-attributes

Validator icons

The jQuery validation plugin is configured to show feedback valid/invalid icons on the right of each field.

The default icons are:

  • Glyphicons for Bootstrap 3
  • Fontawesome icons for Bootstrap 4
  • Material icons for Material Design
  • Foundation icons for Foundation
You can disable them this way:
$form = new Form('booking-form', 'horizontal', 'data-fv-no-icon=true, novalidate');

DEBUG mode

In some complex cases you may want to see which fields are validated or not:

  1. Enable the DEBUG mode:
    $form = new Form('booking-form', 'horizontal', 'data-fv-debug=true, novalidate');
  2. Open your browser's console, fill some fields and/or post your form
  3. The form will not be submitted:
    in DEBUG mode submit is disabled.
    You'll see instead the validation results in your browser's console:
jquery validator debug console

Form Submission

When the user submits the form, the validator sends automatically the form if all the fields are valid.
If you want to disable this behavior add the data-fv-no-auto-submit attribute to your form:

$form = new Form('my-form', 'vertical', 'data-fv-no-auto-submit=true, novalidate');

Callback & jQuery validation API

The callback function allows to enable/disable validators and use the Form Validation plugin API the way you want.

Create a function named fvCallback - The validator plugin will call it as soon as it's ready.
Then you can use all the validator API.

  • The callback function name is fvCallback
  • The form validator instance can be found this way:
    var form = forms['my-form'];
    
    // form.fv is the validator
    form.fv.on('core.form.invalid', function() {
        // do stuff
    });

example of use:

<script type="text/javascript">
var fvCallback = function() {
    var form = forms['my-form'];

    // form.fv is the validator
    // you can then use the formvalidation plugin API
    form.fv.on('core.form.invalid', function() {
        // do stuff
    });
};
</script>

Multilanguage support

jQuery Validation languages files are in phpformbuilder/plugins/formvalidation/dist/js/language/

To set your language:

  1. Find your language file in phpformbuilder/plugins/formvalidation/dist/js/locales/
  2. Add the validation plugin this way:
    $js_replacements = array('%language%' => 'fr_FR');
    $form->addPlugin('formvalidation', '#form-name', 'default', $js_replacements);
    where fr_FR is the name of your language file.

E-mail Sending

sendMail function (static)

$sent_message = Form::sendMail($options, $smtp_settings = array());
    /**
    * Send email with posted values and custom content
    *
    * Tests and secures values to prevent attacks (phpmailer/extras/htmlfilter.php => HTMLFilter)
    * Uses custom html/css template and replaces shortcodes - syntax : {fieldname} - in both html/css templates with posted|custom values
    * Creates an automatic html table with vars/values - shortcode : {table}
    * Merges html/css to inline style with Pelago Emogrifier
    * Sends email and catches errors with Phpmailer
    * @param  array  $options
    *                     sender_email                    : the email of the sender
    *                     sender_name [optional]          : the name of the sender
    *                     reply_to_email [optional]       : the email for reply
    *                     recipient_email                 : the email destination(s), separated with commas
    *                     cc [optional]                   : the email(s) of copies to send, separated with commas
    *                     bcc [optional]                  : the email(s) of blind copies to send, separated with commas
    *                     subject                         : The email subject
    *                     isHTML                          : Send the mail in HTML format or Plain text (default: true)
    *                     textBody                        : The email body if isHTML is set to false
    *                     attachments [optional]          : file(s) to attach : separated with commas, or array (see details inside function)
    *                     template [optional]             : name of the html/css template to use in phpformbuilder/mailer/email-templates/
                                                 (default: default.html)
    *                     human_readable_labels [optional]: replace '-' ans '_' in labels with spaces if true (default: true)
    *                     values                          : $_POST
    *                     filter_values [optional]        : posted values you don't want to include in the e-mail automatic html table
    *                     custom_replacements [optional]  : array to replace shortcodes in email template. ex : array('mytext' => 'Hello !') will replace {mytext} with Hello !
    *                     sent_message [optional]         : message to display when email is sent
    *                     debug [optional]                : displays sending errors (default: false)
    *                     smtp [optional]                 : use smtp (default: false)
    *
    * @param  array  $smtp_settings
    *                         host :       String      Specify main and backup SMTP servers - i.e: smtp1.example.com, smtp2.example.com
    *                         smtp_auth:   Boolean     Enable SMTP authentication
    *                         username:    String      SMTP username
    *                         password:    String      SMTP password
    *                         smtp_secure: String      Enable TLS encryption. Accepted values: tls|ssl
    *                         port:        Number      TCP port to connect to (usually 25 or 587)
    *
    * @return string sent_message
    *                         success or error message to display on the page
    */

The fields named *-token and *submit-btn are automatically filtered.
This means that the posted values will not appear in the email sent.

Minimal Example

The following code will :

  • Load default email template phpformbuilder/mailer/email-templates/default[.html/.css]
  • Replace template shortcode {table} with an automatic html table with vars/ posted values
  • Merge html/css to inline style with Pelago Emogrifier
  • Send email and catch errors with Phpmailer
    $options = array(
        'sender_email'     =>  'contact@phpformbuilder.pro',
        'recipient_email'  =>  'john.doe@gmail.com',
        'subject'          =>  'contact from PHP Form Builder'
    );
    $sent_message = Form::sendMail($options);

Your message has been successfully sent !

Example with SMTP

    $smtp_settings = array(
        host        => 'smtp1.example.com',
        smtp_auth   => true,
        username    => 'myname',
        password    => 'mypassword',
        smtp_secure => 'tls',
        port        => 25
    );

    $options = array(
        'sender_email'     =>  'contact@phpformbuilder.pro',
        'recipient_email'  =>  'john.doe@gmail.com',
        'subject'          =>  'contact from PHP Form Builder',
        'smtp'             =>  true
    );
    $sent_message = Form::sendMail($options, $smtp_settings);

Your message has been successfully sent !

Example with custom template

    // Create 'my-custom-template.html' and 'my-custom-template.css' in the 'phpformbuilder/mailer/email-templates-custom/' folder
    // You can use shortcodes in your HTML template, they will be automatically replaced with the posted values.
    // For instance, {user-email} will be replaced with the real $_POST['user-email'] value.

    // You can use the special {table} shortcode to display a complete table with all the posted fieldnames / values.

    // Then:

    $email_config = array(
        'sender_email'    => 'contact@phpformbuilder.pro',
        'sender_name'     => 'PHP Form Builder',
        'recipient_email' => addslashes($_POST['user-email']),
        'subject'         => 'Contact From PHP Form Builder',
        'template'        => 'my-custom-template.html',
        'filter_values'   => 'submit-btn, token',
        'debug'           => true
    );
    $sent_message = Form::sendMail($email_config);

Your message has been successfully sent !

Example with Text Email (no template, no HTML)

    $email_config = array(
        'sender_email'    => 'contact@phpformbuilder.pro',
        'sender_name'     => 'PHP Form Builder',
        'recipient_email' => addslashes($_POST['user-email']),
        'subject'         => 'Contact From PHP Form Builder',
        'textBody'        => $_POST['message'], // textBody is required or the message won't be sent.
        'isHTML'          => false,
        'debug'           => true
    );
    $sent_message = Form::sendMail($email_config);

Your message has been successfully sent !

Full Example using styled template

The following code will :

  • Load a styled email template phpformbuilder/mailer/email-templates/contact[.html/.css]
  • Replace template shortcodes including header image and colors with the values set in $replacements
  • Replace others template shortcodes with posted values
  • Merge html/css to inline style with Pelago Emogrifier
  • Send email and catch errors with Phpmailer
    // server path for attachments
    $path = rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . '/phpformbuilder/images/uploads/';

    $replacements = array(
        'tpl-header-image'              => 'https://www.phpformbuilder.pro/assets/images/phpformbuilder-sandy-stone-600-160.png',
        'tpl-page-background'           => 'url(https://www.phpformbuilder.pro/assets/images/noisy-sandy-stone.png) repeat #002f2f',
        'tpl-content-dark-background'   => '#a7a37e',
        'tpl-content-light-background'  => '#f9f8e9',
        'tpl-content-dark-text'         => '#333333',
        'tpl-content-light-text'        => '#f9f8e9',
        'tpl-content-accent-text'       => '#f9f8e9',
        'tpl-content-accent-background' => '#198181',
        'user-name'                     => 'Name',
        'user-first-name'               => 'First name',
        'user-email'                    => 'Email'
    );

    $email_config = array(
        'sender_email'        => 'contact@phpformbuilder.pro',
        'sender_name'         => 'PHP Form Builder',
        'reply_to_email'      => 'contact@phpformbuilder.pro',
        'recipient_email'     => addslashes($_POST['user-email']),
        'cc'                  => 'john.doe@email.com, 2nd.cc@email.com',
        'bcc'                 => 'another.one@email.com',
        'subject'             => 'Contact From PHP Form Builder',
        'attachments'         => $path . $_POST['files'][0],
        'template'            => 'contact-styled.html',
        'filter_values'       => 'email-styles, submit-btn, token',
        'values'              => $_POST,
        'custom_replacements' => $replacements,
        'debug'               => true
    );
    $sent_message = Form::sendMail($email_config);

Your message has been successfully sent !

To create custom email templates:

  1. Copy/paste an existing html/css template from phpformbuilder/mailer/email-templates/ and save it into phpformbuilder/mailer/email-templates-custom/ (or create a new html file + a new css file with both same name)
  2. Use the shortcode {table} in your html template if you want to add an automatic html table with all posted values
  3. (And/Or) Put fieldnames between braces in your template.
    They'll be replaced automatically with posted values.
    For example: Hello {user-first-name} {user-name}
  4. [optional] You can use the custom_replacements option to replace specific texts in email with specific values
  5. Call sendMail() function and set your html template in template option

How to replace array values using sendMail() function

To replace values posted in array in custom email template, best way is to create non-array indexed values, then add them in sendMail custom_replacements option

Example using array values

<?php
    /*
    Example with 3 posted colors
    Email template will use {color_1}, {color_2}, {color_3}
    */

    // create index
    $i = 1;

    // loop through posted values
    foreach ($_POST['color'] as $color) {

        // name indexed variable and give it posted value
        $var = 'color_' . $i;
        $$var = $color;

        // increment index
        $i++;
    }

    $options = array(
        // [...]
        'custom_replacements'  => array(
            'color_1' => $color_1,
            'color_2' => $color_2,
            'color_3' => $color_3
        ),
        // [...]
    );

    $sent_message = Form::sendMail($options);

Your message has been successfully sent !

Attachments Examples

Examples using FileUpload plugin

The path of the uploaded files is defined in the fileuploader plugin configuration (variable $fileUpload_config) when you instantiate the fileuploader plugin

To get the information about the uploaded file you have to call the function FileUploader::getPostedFiles

Single file:

    // at the beginning of your file
    use fileuploader\server\FileUploader;
    include_once rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . 'phpformbuilder/plugins/fileuploader/server/class.fileuploader.php';

    // once the form is validated
    $options = array(
        [...]
    );

    if (isset($_POST['user-file']) && !empty($_POST['user-file'])) {
        // set the filepath according to the path defined in the fileuploader plugin configuration
        $path = rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . '/file-uploads/';

        // get the posted filename
        $posted_file = FileUploader::getPostedFiles($_POST['user-file']);
        $filename    = $posted_file[0]['file'];

        // add the attachment to the email
        $options['attachments'] = $path . $filename;
    }

    $msg = Form::sendMail($options);

Multiple files separated with commas:

    // at the beginning of your file
    use fileuploader\server\FileUploader;
    include_once rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . 'phpformbuilder/plugins/fileuploader/server/class.fileuploader.php';

    // once the form is validated
    $options = array(
        [...]
    );

    if (isset($_POST['user-files']) && !empty($_POST['user-files'])) {
        // set the filepath according to the path defined in the fileuploader plugin configuration
        $path = rtrim($_SERVER['DOCUMENT_ROOT'], DIRECTORY_SEPARATOR) . '/file-uploads/';

        // get the posted filename
        $posted_files = FileUploader::getPostedFiles($_POST['user-files']);
        $attachments = array();
        foreach ($posted_files as $pf) {
            $filename = $pf['file'];
            $attachments[] = $path . $filename;
        }

        // add the attachments to the email
        $options['attachments'] = implode(',', $attachments);
    }

    $msg = Form::sendMail($options);

Examples using input type="file"

Single file:

    $form->addInput('file', 'myFile', '', 'file: ');

    $attachments = array(
        array(
            'file_path' => $_FILES['myFile']['tmp_name'],
            'file_name' => $_FILES['myFile']['name']
        )
    );

    $options = array(
        [...]
        'attachments' => $attachments,
        [...]
    );

    $msg = Form::sendMail($options);

Multiple files:

    $form->addInput('file', 'myFile', '', 'file: ');
    $form->addInput('file', 'mySecondFile', '', 'file: ');

    $attachments = array(
        array(
            'file_path' => $_FILES['myFile']['tmp_name'],
            'file_name' => $_FILES['myFile']['name']
        ),
        array(
            'file_path' => $_FILES['mySecondFile']['tmp_name'],
            'file_name' => $_FILES['mySecondFile']['name']
        )
    );

    $options = array(
        [...]
        'attachments' => $attachments,
        [...]
    );
    $msg = Form::sendMail($options);

Database Utilities

Jeff L. Williams's Mysql class is in database folder.

Complete Mysql class doc with examples queries is in phpformbuilder/documentation/mysql-class-doc/

Available online here: https://www.phpformbuilder.pro/documentation/mysql-class-doc/Mysql-documentation.html

Configure your localhost/production access in phpformbuilder/database/db-connect.php, and you're ready to connect.

Examples

Database Select Example

    use phpformbuilder\database\Mysql;

    require_once 'phpformbuilder/database/db-connect.php';
    require_once 'phpformbuilder/database/Mysql.php';

    $db = new Mysql();
    $qry = 'SELECT * FROM table';
    $db = new Mysql();
    $db->query($qry);
    $db_count = $db->rowCount();
    if (!empty($db_count)) {
        while (! $db->endOfSeek()) {
            $row = $db->row();
            $value_1[] = $row->field_1;
            $value_2[] = $row->field_2;
        }

        // remove comment to show $value_1
        // var_dump($value_1);
    }

Database Insert

Database Insert Example

    use phpformbuilder\database\Mysql;

    require_once 'phpformbuilder/database/db-connect.php';
    require_once 'phpformbuilder/database/Mysql.php';

    $db = new Mysql();
    $insert['ID'] = Mysql::SQLValue('');
    $insert['username'] = Mysql::SQLValue($_POST['username']);
    $insert['useremail'] = Mysql::SQLValue($_POST['useremail']);
    $insert['userphone'] = Mysql::SQLValue($_POST['userphone']);

    if (!$db->insertRow('YOUR_TABLE', $insert)) {
        $msg = '<p class="alert alert-danger">' . $db->error() . '<br>' . $db->getLastSql() . '</p>' . " \n";
    } else {
        $msg = '<p class="alert alert-success">1 row inserted !</p>' . " \n";
    }

    echo $msg;

Database Update

Database Update Example

    use phpformbuilder\database\Mysql;

    require_once 'phpformbuilder/database/db-connect.php';
    require_once 'phpformbuilder/database/Mysql.php';

    $db = new Mysql();

    $filter['ID'] = Mysql::sqlValue($_POST['ID'], Mysql::SQLVALUE_NUMBER);

    $update['username'] = Mysql::SQLValue($_POST['username']);
    $update['useremail'] = Mysql::SQLValue($_POST['useremail']);
    $update['userphone'] = Mysql::SQLValue($_POST['userphone']);

    if (!$db->UpdateRows('YOUR_TABLE', $update, $filter)) {
        $msg = '<p class="alert alert-danger">' . $db->error() . '<br>' . $db->getLastSql() . '</p>' . " \n";
    } else {
        $msg = '<p class="alert alert-success">Database updated successfully !</p>' . " \n";
    }

    echo $msg;

Database Delete

Database Delete Example

    use phpformbuilder\database\Mysql;

    require_once 'phpformbuilder/database/db-connect.php';
    require_once 'phpformbuilder/database/Mysql.php';

    $db = new Mysql();

    $filter["ID"] = Mysql::sqlValue($_POST['ID'], Mysql::SQLVALUE_NUMBER);

    if (!$db->deleteRows('YOUR_TABLE', $filter)) {
        $msg = '<p class="alert alert-danger">' . $db->error() . '<br>' . $db->getLastSql() . '</p>' . " \n";
    } else {
        $msg = '<p class="alert alert-success">1 row deleted successfully !</p>' . " \n";
    }

    echo $msg;

Security

Protection against XSS (Cross-Site Scripting)

How it works

  1. When form is created, each fieldname is registered in session
  2. When form is posted, each posted value is registered in session.
  3. If validation is ok, call Form::clear('form-name'); to clear all previously registered values
  4. If validation fails, form will fill fields using user posted values stored in session, protected using htmlspecialchars().

To display posted values on your pages, always protect with htmlspecialchars(): htmlspecialchars($_POST['value'])

To register posted values into your database:

  • protect with addslashes(): addslashes(htmlspecialchars($_POST['value']))
  • or just with addslashes id you want to keep html intact: addslashes($_POST['value'])
  • or use built-in Mysql class protection

Protection against CSRF (Cross-Site Request Forgeries)

Security token is automatically added to each form.

Token is valid for 1800 seconds (30mn) without refreshing page.

Validate posted token this way:

    if(Form::testToken('my-form-id') === true) {
        // token valid, no CSRF.
    }

Extending main class

Extending PHP Form Builder allows to create a complete form or form parts using a single customized function.

Created form or parts can be validated the same way, using a single customized function.

Very useful if you want for example:

  • Create a complete contact form and use it on several projects
  • Create several similar fields in a single form
  • Create and reuse several fields in different forms

See live examples with code in Templates

See phpformbuilder/FormExtended.php code

Chaining methods

All public non-static methods can be chained.

The classic way:

/* ==================================================
    The Form
    ================================================== */

    $form = new Form('contact-form-2', 'vertical', 'novalidate');
    $form->startFieldset('Please fill in this form to contact us');
    $form->addInput('text', 'user-name', '', 'Your name: ', 'required');
    $form->addInput('email', 'user-email', '', 'Your email: ', 'required');
    $form->addHelper('Enter a valid US phone number', 'user-phone');
    $form->addInput('text', 'user-phone', '', 'Your phone: ', 'required, data-fv-phone, data-fv-phone-country=US');
    $form->addTextarea('message', '', 'Your message: ', 'cols=30, rows=4, required');
    $form->addPlugin('word-character-count', '#message', 'default', array('%maxAuthorized%' => 100));
    $form->addCheckbox('newsletter', 'Suscribe to Newsletter', 1, 'checked=checked');
    $form->printCheckboxGroup('newsletter', '');
    $form->addRecaptcha('recaptcha-code-here');
    $form->addBtn('submit', 'submit-btn', 1, 'Submit', 'class=btn btn-success');
    $form->endFieldset();
    $form->addPlugin('icheck', 'input', 'default', array('%theme%' => 'square-custom', '%color%' => 'green'));

    // jQuery validation
    $form->addPlugin('formvalidation', '#contact-form-2');

Using chained methods:

$form = new Form('contact-form-2', 'vertical', 'novalidate');
$form->startFieldset('Please fill in this form to contact us')->addInput('text', 'user-name', '', 'Your name: ', 'required')
    ->addInput('email', 'user-email', '', 'Your email: ', 'required')
    ->addHelper('Enter a valid US phone number', 'user-phone')
    ->addInput('text', 'user-phone', '', 'Your phone: ', 'required, data-fv-phone, data-fv-phone-country=US')
    ->addTextarea('message', '', 'Your message: ', 'cols=30, rows=4, required')
    ->addPlugin('word-character-count', '#message', 'default', array('%maxAuthorized%' => 100))
    ->addCheckbox('newsletter', 'Suscribe to Newsletter', 1, 'checked=checked')
    ->printCheckboxGroup('newsletter', '')
    ->addRecaptcha('recaptcha-code-here')
    ->addBtn('submit', 'submit-btn', 1, 'Submit', 'class=btn btn-success')
    ->endFieldset()
    ->addPlugin('icheck', 'input', 'default', array('%theme%' => 'square-custom', '%color%' => 'green'))

    // jQuery validation
    ->addPlugin('formvalidation', '#contact-form-2');

Sources & Credits

Thanks so much to: