Form Builder
By using the form builder, you can minimize code duplication and accelerate the development of form modules and add-ons in the admin panel.
The form consists of:
- form header
- form fields
- tabs that divide the form fields into logical groups
- form control buttons
All of this can be controlled by the Form component. To initialize the form object, use the tplAdmin::form() method.
Let's consider a simple example of creating a form.
Simple form
As an example, let's take a simplified publication entity represented in the database as follows:
CREATE TABLE `bff_posts` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, -- publication ID
`title` varchar(200) NOT NULL DEFAULT '', -- publication title
`content` TEXT, -- publication content
`enabled` tinyint(1) unsigned NOT NULL DEFAULT '1', -- whether the publication is enabled
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- publication creation date
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
To create a form, you can follow several logical steps:
- Create a form component object
$formand pass it the controller object.
$list = \tplAdmin::form($this);
In practice, a form may have a larger number of fields, in which case its declaration (adding fields) can be separated into a separate template by specifying a second parameter and the template file name in it:
// controller template php file /tpl/admin.post.form.php
$list = \tplAdmin::form($this, 'admin.post.form');
The form object $form and the controller object $this will also be available in the template.
- Specify the form header:
$form->setTitle('Publications / Management');
- Create a tab
$form->tab(tab_key, tab_title)with the parameters key (unique name in Latin) and specify its name, and then add form fields to it.
There can be a large number of fields in the form, and they can be divided into multiple tabs. After declaring a tab, add the fields that will be included directly in this tab.
$form->tab('tab1', 'Tab #1');
// add fields...
$form->tab('tab2', 'Tab #2');
// add fields...
-
Add form fields of various types:
-
text field -
text(field_name, field_title, default_value, lang)-
field_name- the field'snameattribute, which must match the field name in the database -
field_title- the field name in the form -
default_value- the default value of the field -
lang- whether the field is multilingual (more on this below)
-
-
textarea field -
textarea(field_name, field_title, default_value, lang) -
checkbox field -
checkbox(field_name, field_title, default_value) -
datepicker field -
datepicker(field_name, field_title) -
You can learn more about working with different types of form fields from the article "Form Fields"
-
-
Add a form submit button
$form->buttonSubmit(title, callback), where the parameters are the button title and the callback event handler for form submission.
In the example, we use the default handler (onSave).
$form->buttonSubmit('Submit');
- Handle the form save event
$form->onSave(function($id, $data){
# call the controller model method to save the data of the entry by $id
# data is in the format ['field_name' => 'field_value']
return $this->model->postSave($id, $data);
});
In the form save event handler, pass the callback that is responsible for saving the data specified in the form fields.
- To display the form on the screen, render the block as follows:
return $form->view();
The controller method responsible for handling the form should end with this method.
As an example of usage, all logical steps are combined into a controller method responsible for generating a form:
/**
* Example of a module/add-on admin controller method
* generating a publication form
* @return string HTML
*/
public function postForm()
{
# create a form object
$form = \tplAdmin::form($this);
# specify the form title
$form->setTitle('Publications / Management');
# add the necessary fields
$form->tab('main', 'General') # declare the form tab
->text('title', 'Title', '', false)
->textarea('content', 'Content', '', false)
->checkbox('enabled', 'Publish', true)
->datepicker('created', 'Publication Date');
# add a save button and specify its name
$form->buttonSubmit('Submit');
# declare the data saving handler
$form->onSave(function($id, $data){
return $this->model->postSave($id, $data);
});
# render the form and return it to the application
return $form->view();
}
Form Integration in the List
Forms are an integral part of lists, for an example of integrating a form into a list, see here.
Field Visibility and Boundaries
It is possible to group fields into vertical blocks, placing one below the other (visually highlighting them with a border) and control their visibility depending on the value of a selected field.
$form->radio('choice', 'Make a choice', 1)
->option('1', 'Yes')
->option('2', 'No');
$form->text('block_1', 'Text field', '', false)
->boundaryInit(['title' => 'Block #1'])
->visibleIf('choice', 1);
$form->number('number1', 'Number field')
->boundaryIn('block1');
$form->text('block_2', 'Another text field')
->boundaryInit(['title' => 'Block #2'])
->visibleIf('choice', 2);
To visually group the fields 'block_1' and 'number1' with a border:
- declare a block in the first field to be grouped using the
boundaryInit(opts)method, passing the block name as a parameter; - add the following fields that belong to the block using the
boundaryIn('block1')method, where the parameter is the key of the first field that belongs to the block.
The visibility of a field can be controlled using the visibleIf(field_key, field_value) method, depending on the value of the field_key field.
You can also place fields next to each other in the same line (horizontal alignment), specifying their width.
$form->text('text_key_together', 'Title of fields combined in a row', '', false)
->width(70);
$form->text('text')
->together('text_key_together') # to the right of text_key_together field
->width(100);
$form->number('number')
->together('text_key_together') # to the right of text_key_together field
->width(70);
To achieve this layout, use the together(first_key_together) method, specifying the key of the first field to which the current field is added.
The width of the fields is controlled by the width(count_px) method.