Haste Form has been designed to ease working with Contao forms in the front end.
A lot of the following examples can be combined. For more internal details please read the source ;-)
<?php
// First param is the form id
// Second is either GET or POST
// Third is a callable that decides when your form is submitted
// You can pass an optional fourth parameter (true by default) to turn the form into a table based one
$objForm = new \Haste\Form\Form('someid', 'POST', function($objHaste) {
return \Input::post('FORM_SUBMIT') === $objHaste->getFormId();
});
// Haste will never decide for you when the form has been submitted.
// You have to tell it! Let's have a look at an example using GET
// Haste will turn into the submitted state as soon as the GET param
// "foo" contains the value "bar"
$objForm = new \Haste\Form\Form('someid', 'GET', function() {
return \Input::get('foo') === 'bar';
});
// You can optionally preserve the current GET parameters.
// They will be added as hidden fields to the current form.
// This is especially useful when using multiple GET forms (like search and filter).
$objForm->preserveGetParameters();
$objForm->preserveGetParameters(array('page_n')); // Exclude 'page_n' parameter
// A form needs an action. By default it's the current request URI you
// place your Haste form on, but you can either set your own URI:
$objForm->setFormActionFromUri('https://foo.bar/somewhere.html');
// Or you can pass a page ID that Haste will turn into an URI for your
// convenience:
$objForm->setFormActionFromPageId(42);
// Now let's add form fields:
$objForm->addFormField('year', array(
'label' => 'Year',
'inputType' => 'text',
'eval' => array('mandatory'=>true, 'rgxp'=>'digit')
));
// Need a checkbox?
$objForm->addFormField('termsOfUse', array(
'label' => array('This is the <legend>', 'This is the <label>'),
'inputType' => 'checkbox',
'eval' => array('mandatory'=>true)
));
// Let's add a submit button
$objForm->addFormField('submit', array(
'label' => 'Submit form',
'inputType' => 'submit'
));
// Automatically add the FORM_SUBMIT and REQUEST_TOKEN hidden fields.
// DO NOT use this method with generate() as the "form" template provides those fields by default.
$objForm->addContaoHiddenFields();
// For the ease of use we do provide two helpers for the submit button and captcha field
$objForm->addSubmitFormField('submit', 'Submit form');
$objForm->addCaptchaFormField('captcha');
Now that you have your form instance ready, you can generate the markup for it and validate the user inputs etc.
<?php
// validate() also checks whether the form has been submitted
if ($objForm->validate()) {
// Get the submitted and parsed data of a field (only works with POST):
$arrData = $objForm->fetch('year');
// Get all the submitted and parsed data (only works with POST):
$arrData = $objForm->fetchAll();
// For your convenience you can also use a callable to walk over all widgets
$arrData = $objForm->fetchAll(function($strName, $objWidget) {
return \Input::postRaw($strName);
});
// Read from POST: \Input::post('year');
// Read from GET: \Input::get('year');
}
// Get the form as string
echo $objForm->generate();
// or just
echo $objForm;
// You can also pass your own Template instance
$objMyTemplate = new \FrontendTemplate('mytemplate');
$objForm->addToTemplate($objMyTemplate);
echo $objMyTemplate->parse();
// Alternatively, you can pass it to any other object
$objFilter = new \stdClass();
$objForm->addToObject($objFilter);
$this->Template->filter = $objFilter;
<?php
// you can exclude or modify certain fields by passing a callable as second
// parameter
$objForm->addFieldsFromDca('tl_content', function(&$strField, &$arrDca) {
// make sure to skip elements without inputType or you will get an exception
if (!isset($arrDca['inputType'])) {
return false;
}
// add anything you like
if ($strField == 'myField') {
$arrDca['eval']['mandatory'] = true;
}
// you must return true otherwise the field will be skipped
return true;
});
// By default you can use the built-in callback that will skip fields without specified inputType
// which normally would lead to the exception
$objForm->addFieldsFromDca('tl_content', array($objForm, 'skipFieldsWithoutInputType'));
<?php
// you can exclude or modify certain fields by passing a callable as second
// parameter
$objForm->addFieldsFromFormGenerator(42, function(&$strField, &$arrDca) {
// add anything you like
if ($strField == 'myField') {
$arrDca['eval']['mandatory'] = true;
}
// you must return true otherwise the field will be skipped
return true;
});
By passing an \Haste\Util\ArrayPosition
instance as the third parameter you can
insert the field at a certain position. Available positions are:
ArrayPosition::FIRST
ArrayPosition::LAST
ArrayPosition::BEFORE
ArrayPosition::AFTER
FIRST
and LAST
do not require the second parameter of the constructor.
<?php
// this example adds an explanation form field before the existing submit
// form field
$objForm->addFormField('mandatory', array(
'inputType' => 'explanation',
'eval' => array('text' => '<p>Mandatory</p>', 'class' => 'mandatory-label')
), new \Haste\Util\ArrayPosition(\Haste\Util\ArrayPosition::BEFORE, 'submit'));
<?php
$objForm->removeFormField('firstname');
You can easily bind a Contao Model instance to the form to ease working with them.
Haste form will try to load and preset the data from the model if there is already
some and will also store the values to the model.
However, it will not call ->save()
on the model so you can still do with it
whatever you like.
<?php
// Presets values from page ID 42
$objModel = \PageModel::findByPk(42);
$objForm->bindModel($objModel);
$objForm->addFieldsFromDca('tl_page');
if ($objForm->validate()) {
// The model will now contain the changes so you can save it
$objModel->save();
}
You can add your own field validation per addValidator
or directly in your field using save_callback
.
<?php
// use addValidator
$objForm->addValidator('email', function($varValue, \Widget $objWidget, Form $objForm){
if ($varValue !== '[email protected]') {
throw new \Exception('Wrong email address!');
}
return $varValue;
});
// or directly in your field
$objForm->addFormField('email', [
'save_callback' => [
function($value) {
if ($value !== '[email protected]') {
throw new \Exception('Wrong email address!');
}
return $value;
}
]
]);