Forms - Create, validate and save
Introduction
With version 5, the handling of forms has been improved. Forms can be created in PP with a separate form class from Admidio and a Smarty template. The form sends its entries to the server via an Ajax call and receives a response. This can be an error message if the data was not entered correctly or a success message if the form data could be saved. The data is validated automatically based on the information from the form order.
Creating an HTML form
The first step is to create a page with the PagePresenter class.
$page = PagePresenter::withHtmlIDAndHeadline('adm_example_page', $gL10n->get('SYS_EXAMPLES'));
Now the form can be initialized with the Forms class. A unique ID and the corresponding smarty template must be specified. The URL to which the form input is sent must also be specified.
$form = new FormPresenter( 'adm_example_edit_form', 'modules/example.edit.tpl', SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/example.php', array( 'uuid' => $getExampleUUID, 'mode' => 'edit' )), $page );
Once the form has been initialized, the individual fields can now be added. For each field, there are different transfers, which are documented in the Forms class. The definition of the fields also has an influence on the validation. If a field is defined as a mandatory field. The validation checks that a value is entered for this field. If this is not the case, the validation later returns an error message.
$form->addInput( 'adm_headline', $gL10n->get('SYS_TITLE'), $example->getValue('example_headline'), array('maxLength' => 100, 'property' => FormPresenter::FIELD_REQUIRED) ); $form->addSelectBox( 'adm_season', $gL10n->get('SYS_SEASON'), array( 'winter' => 'SYS_WINTER', 'spring' => 'SYS_SPRING', 'summer' => 'SYS_SUMMER', 'fall' => 'SYS_FALL' ), array( 'property' => FormPresenter::FIELD_REQUIRED, 'defaultValue' => (int)$example->getValue('example_season') ) ); $form->addEditor( 'adm_description', $gL10n->get('SYS_TEXT'), $example->getValue('example_description') );
If information about the creator or the last editor is to be displayed in the form, the following code block can be used for this. The prerequisite for this is that there is an object that is of the Entity class or is derived from the Entity class. The corresponding functions are stored there, which automatically read the data from the database table.
$page->assignSmartyVariable('nameUserCreated', $example->getNameOfCreatingUser()); $page->assignSmartyVariable('timestampUserCreated', $example->getValue('example_timestamp_create')); $page->assignSmartyVariable('nameLastUserEdited', $example->getNameOfLastEditingUser()); $page->assignSmartyVariable('timestampLastUserEdited', $example->getValue('example_timestamp_change'));
In the last step, the form is assigned to the Page Present class and saved in the current session so that the information can be used during validation.
$form->addToHtmlPage(); $gCurrentSession->addFormObject($form);
The corresponding Smarty template looks like this:
<form {foreach $attributes as $attribute} {$attribute@key}="{$attribute}" {/foreach}> <div class="admidio-form-required-notice"><span>{$l10n->get('SYS_REQUIRED_INPUT')}</span></div> {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} {include 'sys-template-parts/form.input.tpl' data=$elements['adm_headline']} {include 'sys-template-parts/form.select.tpl' data=$elements['adm_season']} {include 'sys-template-parts/form.editor.tpl' data=$elements['adm_description']} <div class="form-alert" style="display: none;"> </div> {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save']} {include file="sys-template-parts/system.info-create-edit.tpl"} </form>
The template starts with the form element. The DIV should then appear for each form with a reference to mandatory fields. This is followed by the adm_crsf_token field, which must be included in every form and protects the form against CSRF attacks. The individual fields from the template parts are then integrated. Here it is important that the array elements for data contains the ID of the field. The DIV for the alert must then be added and then the button for sending is added. If you want to display information about the creator or the last change, the info-create-edit template must be included in the last step. Other design elements such as Bootstrap cards or notes can be stored directly in the template and do not have to be defined via the Forms class as in earlier versions.
Validate and save form data
Once the form has been created, the script for processing the form must now be adapted. The first step is to validate the form content. You can use the following code for this.
$exampleEditForm = $gCurrentSession->getFormObject($_POST['adm_csrf_token']); $formValues = $exampleEditForm->validate($_POST);
In the first line, the form is loaded from the session. The form is identified using the CSRF token. Validation then takes place in the next step. This checks whether all mandatory fields have been filled in. It also checks whether the data types correspond to the fields and whether, for example, a valid email address has been entered in an email. In the case of an editor, the content is checked using HTMLPurifier. The exact checks can be looked up in FormPresenter::validate().
In the next step, the field contents can now be transferred to the database object and then saved in the database.
$example = new Entity($gDb); $example->readDataByUuid($getAnnUuid); foreach ($formValues as $key => $value) { if (str_starts_with($key, 'example_')) { $example->setValue($key, $value); } }
The last step is to return this script. This must be a JSON with the following structure for both a success message and an error. Success:
{ "status": "success" }
Error:
{ "status": "error", "message": "This is the error message that will be shown to the user!" }
Now your form is ready and you can try it out in the browser.