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:

  1. Create a form component object $form and 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.

  1. Specify the form header:
$form->setTitle('Publications / Management');
  1. 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...
  1. Add form fields of various types:

    • text field - text(field_name, field_title, default_value, lang)

      • field_name - the field's name attribute, 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"

  2. 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');
  1. 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.

  1. 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.