Author: Stefan Kientzler
Viewers: 439
Last month viewers: 2
Package: Complex PHP Form Design and Generator
Read this to learn how to design and create a form with the Complex PHP Form Design and Generator. The article explains the individual steps gradually to create and process forms using simple examples with code samples and demonstration images.
Overview
1. Designing the Form: PHP versus XML
The basis of every form is an instance of the FormGenerator
class or the XMLForm
class (which is an extension of FormGenerator
) if the form is to be read from an XML definition file.
Coding the form direct in PHP or using an XML file?
In principle, almost all functions of the package are available when defining a form using an XML file.
Which of the two methods is used depends on the one hand on the particular preferences of the developer, or on whether the form to be created always has exactly the same structure or not.
If, for example, due to user rights or other externally changeable factors, different elements of the form are to be shown / hidden or provided with write protection, this can only be implemented by direct coding!
For a quick start, we first choose the direct coding in PHP. The complete source can be found in the example directory of the package as the file QuickStart.php. The XML version is also in this directory in the files QuickStartXML.php and xml/QuickStart.xml.
1.1. The First Steps
declare(strict_types=1);
require_once '../autoloader.php';
use SKien\Config\JSONConfig;
use SKien\Formgenerator\ArrayFormData;
use SKien\Formgenerator\FormGenerator;
use ...
// defining data array for test purposes
...
// creating the main form instance
$oFG = new FormGenerator($oData);
// load the configuration to use
$oConfig = new JSONConfig('./MSO-Theme/FormGenerator.json');
$oFG->setConfig($oConfig);
// the formaction.php script just displays the POSTED values
// for demonstration
$oFG->setAction('formaction.php');
$oFG->setTarget('_blank');
- Since the complete package works with
strict_types
, we also use them here ;-) - The package uses namespaces and follows the PSR-4 recomendation, so we only have to include the autoloader.php.
- Next follows the use statements for all classes we use in the example.
- Since in most cases a form is not only used to enter new data, it must be possible to pass the data to be processed. The structure of the data is described later in a separate section of this blog.
- Now we are creating the instance of our Form:
$oFG = new FormGenerator($oData);
. - In the next step we load our desired configuration file and pass it to the form.
A detailed desvription of the configuration can be found in FG-config.md$oConfig = new JSONConfig('./MSO-Theme/FormGenerator.json'); $oFG->setConfig($oConfig);
- Now we have to specify the script to be called when submitting the form. In our example we call a small script that simply echoes all data that is submitted. The output is opened in a new window.
$oFG->setAction('formaction.php'); $oFG->setTarget('_blank');
Now we are ready to define our form.
1.2. Basic Structure of the Form
Let's take a look at our example form and then break it down into its basic structure:
...and now let us build this structure with the appropriate objects:
$oFG->setColWidth([20, 80], '%');
...
$oFG->add(new FormHeader('Quick Start Example', 1));
$oFS = $oFG->addFieldSet('Name');
$oFL = $oFS->addLine('Lastname:');
...
$oFL = $oFS->addLine('Firstname:');
...
$oFL = $oFS->addLine('Nickname:');
...
$oFS = $oFG->addFieldSet('Personal Data');
$oFS->setColWidth([20, 25, 20, 35], '%');
$oFL = $oFS->addLine('Gender:');
...
$oFL = $oFS->addLine('Height:');
...
$oFG->add(new FormButtonBox(FormButtonBox::SAVE |
FormButtonBox::DISCARD,
FormFlags::ALIGN_RIGHT));
-
For the entire form we define two columns with a width of 20% and 80%. This column definition is inherited by all child elements by default, but can be overridden by any of these elements:
$oFG->setColWidth([20, 80], '%');
-
The Header is the first visible element:
$oFG->add(new FormHeader('Quick Start Example', 1));
-
Since this form does not contain multiple DIVs, we can leave these out and continue with the first field set:
$oFS = $oFG->addFieldSet('Name');
-
Now we can add the three labeled lines to this field set:
$oFL = $oFS->addLine('Lastname:'); ... $oFL = $oFS->addLine('Firstname:'); ... $oFL = $oFS->addLine('Nickname:'); ...
-
We continue with the second fieldset, for which we now define four columns with the widths 20%, 25%, 20% and 35%, so that the multi-column rows are also correctly rendered. The two lines with the appropriate (first) label are also added to this element :
$oFS = $oFG->addFieldSet('Personal Data'); $oFS->setColWidth([20, 25, 20, 35], '%'); $oFL = $oFS->addLine('Gender:'); ... $oFL = $oFS->addLine('Height:'); ...
-
Finally we define the standard buttons for saving or discarding the data:
$oFG->add(new FormButtonBox(FormButtonBox::SAVE | FormButtonBox::DISCARD, FormFlags::ALIGN_RIGHT));
1.3. Creating the input Elements
Now that we have created the basic structure of the form, the input elements follow next.
$oFG->setColWidth([20, 80], '%');
-> $oFG->add(new FormInput('ID', 0, FormFlags::HIDDEN));
$oFG->add(new FormHeader('Quick Start Example', 1));
$oFS = $oFG->addFieldSet('Name');
$oFL = $oFS->addLine('Lastname:');
-> $oFL->add(new FormInput('strLastname', '100%', FormFlags::MANDATORY, 50));
$oFL = $oFS->addLine('Firstname:');
-> $oFL->add(new FormInput('strFirstname', '100%', 0, 50));
$oFL = $oFS->addLine('Nickname:');
-> $oFL->add(new FormInput('strNickname', '100%', 0, 50));
$oFS = $oFG->addFieldSet('Personal Data');
$oFS->setColWidth([20, 25, 20, 35], '%');
$oFL = $oFS->addLine('Gender:');
-> $oCtrl = new FormSelect('strGender', 1, FormFlags::MANDATORY);
-> $oCtrl->setSelectOptions(['' => '', 'male' => 'm', 'female' => 'f', 'diverse' => 'd']);
-> $oFL->add($oCtrl);
-> $oFL->add(new FormStatic('Birthday:'));
-> $oFL->add(new FormDate('dateDoB', FormFlags::NO_ZERO | FormFlags::ADD_DATE_PICKER));
$oFL = $oFS->addLine('Height:');
-> $oCtrl = new FormInt('iHeight', 4);
-> $oCtrl->setSuffix('cm');
-> $oFL->add($oCtrl);
-> $oFL->add(new FormStatic('Weight:'));
-> $oCtrl = new FormFloat('fltWeight', 5, 1);
-> $oCtrl->setSuffix('kg');
-> $oFL->add($oCtrl);
$oFG->add(new FormButtonBox(FormButtonBox::SAVE |
FormButtonBox::DISCARD,
FormFlags::ALIGN_RIGHT));
-
To identify the data thas is edited, we create a hidden input field holding the internal ID.
$oFG->add(new FormInput('ID', 0, FormFlags::HIDDEN));
-
The first fieldset consists of three Lines, each containing a single Text input element. The length of text to be entered is limited to 50 chars. The
mandatory
flag for the 'lastname' element means that an entry is required in this field.$oFL = $oFS->addLine('Lastname:'); $oFL->add(new FormInput('strLastname', '100%', FormFlags::MANDATORY, 50)); $oFL = $oFS->addLine('Firstname:'); $oFL->add(new FormInput('strFirstname', '100%', 0, 50)); $oFL = $oFS->addLine('Nickname:'); $oFL->add(new FormInput('strNickname', '100%', 0, 50));
-
With the second fieldset, things get a little more complex. The two lines each contain two input elements with the associated labeling. The left-hand label is set directly when the line is created, the label for the second input element is created as an independent static element. In total we have four different types for input here:
- A selection list. The value 1 for the size defines the selection as a drop-down list. Here, too, the mandatory flag ensures that the user makes a selection. Available select options are , male, female and diverse.
$oCtrl = new FormSelect('strGender', 1, FormFlags::MANDATORY); $oCtrl->setSelectOptions(['' => '', 'male' => 'm', 'female' => 'f', 'diverse' => 'd']); $oFL->add($oCtrl);
- The second label and a date element. The 'No Zero' Flag specifies, that nothing will be outputed, if the value for this element is zero (otherwise, the element would show '00.00.0000')
$oFL->add(new FormStatic('Birthday:')); $oFL->add(new FormDate('dateDoB', FormFlags::NO_ZERO | FormFlags::ADD_DATE_PICKER));
- A field for entering an integer. We specify a input length of four char and the element is supplemented with the unit 'cm'.
$oCtrl = new FormInt('iHeight', 4); $oCtrl->setSuffix('cm'); $oFL->add($oCtrl);
- With the last label and an input field for a floating point number with one decimal place, we finish the definition of our form.
$oFL->add(new FormStatic('Weight:')); $oCtrl = new FormFloat('fltWeight', 5, 1); $oCtrl->setSuffix('kg'); $oFL->add($oCtrl);
- A selection list. The value 1 for the size defines the selection as a drop-down list. Here, too, the mandatory flag ensures that the user makes a selection. Available select options are , male, female and diverse.
1.4. Bring Up the Form to the Web
So far we have just defined our form structure. Now it is time to bring it up in a simple HTML page. First we need to retrieve three sections from our Formgenerator Instance:
- the HTML markup itself
- additional style definitions
- some dynamicaly generated javascript
$strFormHTML = $oFG->getForm(); $strStyleFromPHP = $oFG->getStyle(); $strConfigFromPHP = $oFG->getScript();
and embed this parts in a (very) simple HTML page:
<html>
<head>
<title>Quick Start Example</title>
<link type="text/css" rel="stylesheet" href="./MSO-Theme/FormGenerator.css">
<style>
<?php echo $strStyleFromPHP; ?>
</style>
<script type="text/javascript" src="../script/FormGenerator.js"></script>
<script>
<?php echo $strConfigFromPHP; ?>
</script>
</head>
<body style="background-color: #777; width: 100%; padding-top: 20px;">
<div style="width:400px; margin: 0px auto; background-color: transparent;">
<?php echo $strFormHTML; ?>
</div>
</body>
</html>
In the <head>
section of the HTML we have to link to a stylesheet that defines all CSS for the formgenerator. The package example directory contains two templates: FormGenerator.css and MSO-Theme/FormGenerator.css.
A more detailed description of the FormGenerator stylesheet will soon be part of another blog.
Behind the stylesheet we insert the dynamic generated styles from the Formgenerator in a <style>
block.
For all JS functionality (initialization, validation, ...) we only need to include the FormGenerator.js
scriptfile. If any further script file is needed, it will be loaded automaticaly.
As the last element required in the header, we insert the dynamic script, that was build by the Formgenerator.
In the example, the HTML body simply consists of a DIV so that the form is highlighted against a dark background. In real use, in the most cases, this is a DIV that is located somewhere within the layout of the website.
Using the MSO-Theme stylesheet the result of this quick start looks as follows:
by only changing the stylesheet (... and some values in the configuration) the result changes to:
2. Connecting the Form with Data
The form must (in most cases) be linked to a data provider. The data provider can not only be used to transfer the data to be processed to the form. He can also be used to specify select option lists (for select elements or radio groups) if these will not be included in the form definition.
The Dataprovider must implement the FormDataInterface
.
If no existing data have to be edited and there are no select options to specify, a null
value can be passed to the construcor. In this case an NullFormData
Instance is created internally.
The simplest - and in many cases applicable - data provider used in the example is the ArrayFormData
Provider. The data to be processed is passed as an associative array. Optionally, one or more select option lists can also be specified.
2.1. The Data to be Processed by the Form
// defining data array for test purposes
$aData = [
'ID' => 24,
'strLastname' => 'Johnson',
'strFirstname' => 'Dwayne ',
'strNickname' => 'the Rock',
'strGender' => 'm',
'dateDoB' => '1972-05-02',
'iHeight' => 196,
'fltWeight' => 116.0,
];
$oData = new ArrayFormData($aData);
A common use case is that the data to be processed results from a database query. This can easily be implemented e.g. with mysqli
as follows:
$oDB = new \mysqli('MyHost', 'MyName', 'MySecret', 'MyDB');
$oResult = $oDB->query('SELECT * FROM myTable WHERE ID = 24');
if ($oResult && $oResult->num_rows === 1) {
$aData = $oResult->fetch_array(MYSQLI_ASSOC);
$oData = new ArrayFormData($aData);
}
2.2. Specifying Select Options
Select options can either be set directly in the form definition for a contained Select element or RadioGroup or be transferred via the data provider.
In both cases a option list have to be an associative array with any count of text => value
pairs:
['text1' => value1, 'text2' => value2, ..., 'textN' => valueN];
Pass it directly to the element:
$oElement = $new FormSelect('ElementName', 1);
$oElement->setSelectOptions(['option1' => value1, ..., 'optionN' => valueN]);
Pass it to the dataprovider: The selection lists for any number of elements are passed in a nested array:
$aData = [...];
$aOptions = [
'ElementName1' => ['text11' => 'value11', ..., 'text1N' => 'value1N'],
'ElementName2' => ['text21' => 'value21', ..., 'text2N' => 'value2N'],
...
]
$oData = new ArrayFormData($aData, $aOptions);
The best practice to specify avalable select option depends on each special case:
- If the options are fixed values (which may be language dependent), it is better to specify them in the form definition (in PHP or XML).
- If the options are flexible values from any data source, the definition via the data provider is probably the better choice.
3. How to Download the Complex PHP Form Design and Generator or Install It with PHP Composer
The Complex PHP Form Design and Generator package can be downloaded from download page or be installed using the PHP Composer tool following instructions in the Composer install instructions page.
You need to be a registered user or login to post a comment
Login Immediately with your account on:
Comments:
No comments were submitted yet.