2019-11-18 05:58:33 +01:00
---
2014-10-19 10:32:34 +02:00
title: Introduction to Forms
summary: An introduction to creating a Form instance and handling submissions.
2019-11-18 05:58:33 +01:00
iconBrand: wpforms
---
2014-10-19 10:32:34 +02:00
# Forms
2021-06-30 11:48:52 +02:00
The HTML `Form` is the most used way to interact with a user. Silverstripe CMS provides classes to generate forms through
2017-07-03 03:22:12 +02:00
the [Form ](api:SilverStripe\Forms\Form ) class, [FormField ](api:SilverStripe\Forms\FormField ) instances to capture data and submissions through [FormAction ](api:SilverStripe\Forms\FormAction ).
2014-10-19 10:32:34 +02:00
2019-11-18 05:58:33 +01:00
[notice]
2018-06-29 16:03:32 +02:00
See the [Introduction to frontend forms ](https://www.silverstripe.org/learn/lessons/v4/introduction-to-frontend-forms-1 ) lesson for a step by step process of creating a `Form`
2019-11-18 05:58:33 +01:00
[/notice]
2014-10-19 10:32:34 +02:00
## Creating a Form
2017-07-03 03:22:12 +02:00
Creating a [Form ](api:SilverStripe\Forms\Form ) has the following signature.
2014-10-19 10:32:34 +02:00
2017-08-03 02:51:32 +02:00
```php
2017-10-27 04:38:27 +02:00
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FieldList;
$form = new Form(
$controller, // the Controller to render this form on
$name, // name of the method that returns this form on the controller
FieldList $fields, // list of FormField instances
FieldList $actions, // list of FormAction instances
$required // optional use of RequiredFields object
);
2017-08-03 02:51:32 +02:00
```
2014-10-19 10:32:34 +02:00
In practice, this looks like:
2021-06-30 11:48:52 +02:00
**app/src/PageController.php**
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
```php
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\Forms\TextField;
class PageController extends ContentController
{
2017-08-03 05:35:09 +02:00
private static $allowed_actions = [
2016-12-30 00:17:15 +01:00
'HelloForm'
2017-08-03 05:35:09 +02:00
];
2016-12-30 00:17:15 +01:00
public function HelloForm()
{
$fields = new FieldList(
TextField::create('Name', 'Your Name')
);
$actions = new FieldList(
FormAction::create('doSayHello')->setTitle('Say hello')
);
$required = new RequiredFields('Name');
$form = new Form($this, 'HelloForm', $fields, $actions, $required);
return $form;
}
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
public function doSayHello($data, Form $form)
{
$form->sessionMessage('Hello ' . $data['Name'], 'success');
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
return $this->redirectBack();
}
}
2017-08-03 05:35:09 +02:00
2016-12-30 00:17:15 +01:00
```
2018-06-25 00:39:53 +02:00
**app/templates/Page.ss**
2016-12-30 00:17:15 +01:00
```ss
$HelloForm
```
2014-10-19 10:32:34 +02:00
2019-11-18 05:58:33 +01:00
[info]
2014-10-19 10:32:34 +02:00
The examples above use `FormField::create()` instead of the `new` operator (`new FormField()`). These are functionally
equivalent, but allows PHP to chain operations like `setTitle()` without assigning the field instance to a temporary
variable.
2019-11-18 05:58:33 +01:00
[/info]
2014-10-19 10:32:34 +02:00
When constructing the `Form` instance (`new Form($controller, $name)`) both controller and name are required. The
2021-06-30 11:48:52 +02:00
`$controller` and `$name` are used to allow Silverstripe CMS to calculate the origin of the `Form object` . When a user
2014-10-19 10:32:34 +02:00
submits the `HelloForm` from your `contact-us` page the form submission will go to `contact-us/HelloForm` before any of
2017-07-03 03:22:12 +02:00
the [FormAction ](api:SilverStripe\Forms\FormAction ). The URL is known as the `$controller` instance will know the 'contact-us' link and we provide
2014-10-19 10:32:34 +02:00
`HelloForm` as the `$name` of the form. `$name` **needs** to match the method name.
Because the `HelloForm()` method will be the location the user is taken to, it needs to be handled like any other
controller action. To grant it access through URLs, we add it to the `$allowed_actions` array.
2016-12-30 00:17:15 +01:00
```php
2017-08-03 05:35:09 +02:00
private static $allowed_actions = [
2016-12-30 00:17:15 +01:00
'HelloForm'
2017-08-03 05:35:09 +02:00
];
2016-12-30 00:17:15 +01:00
```
2014-10-19 10:32:34 +02:00
2019-11-18 05:58:33 +01:00
[notice]
2014-10-19 10:32:34 +02:00
Form actions (`doSayHello`), on the other hand, should _not_ be included in `$allowed_actions` ; these are handled
2017-07-03 03:22:12 +02:00
separately through [Form::httpSubmission() ](api:SilverStripe\Forms\Form::httpSubmission( )).
2019-11-18 05:58:33 +01:00
[/notice]
2014-10-19 10:32:34 +02:00
## Adding FormFields
2017-07-03 03:22:12 +02:00
Fields in a [Form ](api:SilverStripe\Forms\Form ) are represented as a single [FieldList ](api:SilverStripe\Forms\FieldList ) instance containing subclasses of [FormField ](api:SilverStripe\Forms\FormField ).
Some common examples are [TextField ](api:SilverStripe\Forms\TextField ) or [DropdownField ](api:SilverStripe\Forms\DropdownField ).
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
```php
2017-07-03 03:22:12 +02:00
SilverStripe\Forms\TextField::create($name, $title, $value);
2016-12-30 00:17:15 +01:00
```
2014-10-19 10:32:34 +02:00
2019-11-18 05:58:33 +01:00
[info]
2015-05-23 07:30:09 +02:00
A list of the common FormField subclasses is available on the [Common Subclasses ](field_types/common_subclasses/ ) page.
2019-11-18 05:58:33 +01:00
[/info]
2014-10-19 10:32:34 +02:00
2017-07-03 03:22:12 +02:00
The fields are added to the [FieldList ](api:SilverStripe\Forms\FieldList ) `fields` property on the `Form` and can be modified at up to the point the
2014-10-19 10:32:34 +02:00
`Form` is rendered.
2016-12-30 00:17:15 +01:00
```php
$fields = new FieldList(
TextField::create('Name'),
EmailField::create('Email')
);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$form = new Form($controller, 'MethodName', $fields, ...);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// or use `setFields`
$form->setFields($fields);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// to fetch the current fields..
$fields = $form->getFields();
```
2014-10-19 10:32:34 +02:00
2017-07-03 03:22:12 +02:00
A field can be appended to the [FieldList ](api:SilverStripe\Forms\FieldList ).
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
```php
$fields = $form->Fields();
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// add a field
$fields->push(TextField::create(/* ... */));
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// insert a field before another one
$fields->insertBefore(TextField::create(/* ... */), 'Email');
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// insert a field after another one
$fields->insertAfter(TextField::create(/* ... */), 'Name');
// insert a tab before the main content tab (used to position tabs in the CMS)
$fields->insertBefore(Tab::create(/* ... */), 'Main');
// Note: you need to create and position the new tab prior to adding fields via addFieldToTab()
```
2014-10-19 10:32:34 +02:00
Fields can be fetched after they have been added in.
2016-12-30 00:17:15 +01:00
```php
$email = $form->Fields()->dataFieldByName('Email');
$email->setTitle('Your Email Address');
```
2014-10-19 10:32:34 +02:00
Fields can be removed from the form.
2016-12-30 00:17:15 +01:00
```php
$form->getFields()->removeByName('Email');
```
2014-10-19 10:32:34 +02:00
2019-11-18 05:58:33 +01:00
[alert]
2014-10-19 10:32:34 +02:00
Forms can be tabbed (such as the CMS interface). In these cases, there are additional functions such as `addFieldToTab`
and `removeFieldByTab` to ensure the fields are on the correct interface. See [Tabbed Forms ](tabbed_forms ) for more
information on the CMS interface.
2019-11-18 05:58:33 +01:00
[/alert]
2014-10-19 10:32:34 +02:00
## Modifying FormFields
2017-07-03 03:22:12 +02:00
Each [FormField ](api:SilverStripe\Forms\FormField ) subclass has a number of methods you can call on it to customise its' behavior or HTML markup. The
2014-10-19 10:32:34 +02:00
default `FormField` object has several methods for doing common operations.
2019-11-18 05:58:33 +01:00
[notice]
2014-10-19 10:32:34 +02:00
Most of the `set` operations will return the object back so methods can be chained.
2019-11-18 05:58:33 +01:00
[/notice]
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
```php
$field = new TextField(..);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$field
->setMaxLength(100)
->setAttribute('placeholder', 'Enter a value..')
->setTitle('');
```
2014-10-19 10:32:34 +02:00
### Custom Templates
2017-07-03 03:22:12 +02:00
The [Form ](api:SilverStripe\Forms\Form ) HTML markup and each of the [FormField ](api:SilverStripe\Forms\FormField ) instances are rendered into templates. You can provide custom
2014-10-19 10:32:34 +02:00
templates by using the `setTemplate` method on either the `Form` or `FormField` . For more details on providing custom
templates see [Form Templates ](form_templates )
2016-12-30 00:17:15 +01:00
```php
$form = new Form(..);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$form->setTemplate('CustomForm');
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// or, for a FormField
$field = new TextField(..);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$field->setTemplate('CustomTextField');
$field->setFieldHolderTemplate('CustomTextField_Holder');
```
2014-10-19 10:32:34 +02:00
## Adding FormActions
2017-07-03 03:22:12 +02:00
[FormAction ](api:SilverStripe\Forms\FormAction ) objects are displayed at the bottom of the `Form` in the form of a `button` or `input` tag. When a
2014-10-19 10:32:34 +02:00
user presses the button, the form is submitted to the corresponding method.
2016-12-30 00:17:15 +01:00
```php
FormAction::create($action, $title);
```
2014-10-19 10:32:34 +02:00
2017-07-03 03:22:12 +02:00
As with [FormField ](api:SilverStripe\Forms\FormField ), the actions for a `Form` are stored within a [FieldList ](api:SilverStripe\Forms\FieldList ) instance in the `actions` property
2014-10-19 10:32:34 +02:00
on the form.
2016-12-30 00:17:15 +01:00
```php
public function MyForm()
{
$fields = new FieldList(/* .. */);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$actions = new FieldList(
FormAction::create('doSubmitForm', 'Submit')
);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$form = new Form($controller, 'MyForm', $fields, $actions);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// Get the actions
$actions = $form->Actions();
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// As actions is a FieldList, push, insertBefore, removeByName and other
// methods described for `Fields` also work for actions.
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$actions->push(
FormAction::create('doSecondaryFormAction', 'Another Button')
);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$actions->removeByName('doSubmitForm');
$form->setActions($actions);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
return $form
}
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
public function doSubmitForm($data, $form)
{
//
}
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
public function doSecondaryFormAction($data, $form)
{
//
}
```
2014-10-19 10:32:34 +02:00
The first `$action` argument for creating a `FormAction` is the name of the method to invoke when submitting the form
with the particular button. In the previous example, clicking the 'Another Button' would invoke the
`doSecondaryFormAction` method. This action can be defined (in order) on either:
* One of the `FormField` instances.
* The `Form` instance.
* The `Controller` instance.
2019-11-18 05:58:33 +01:00
[notice]
2014-10-19 10:32:34 +02:00
If the `$action` method cannot be found on any of those or is marked as `private` or `protected` , an error will be
thrown.
2019-11-18 05:58:33 +01:00
[/notice]
2014-10-19 10:32:34 +02:00
The `$action` method takes two arguments:
2015-02-03 10:55:59 +01:00
* `$data` an array containing the values of the form mapped from `$name => $value`
2017-07-03 03:22:12 +02:00
* `$form` the submitted [Form ](api:SilverStripe\Forms\Form ) instance.
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
```php
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\Forms\EmailField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\TextField;
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
class PageController extends ContentController
{
2017-08-03 05:35:09 +02:00
private static $allowed_actions = [
2016-12-30 00:17:15 +01:00
'MyForm'
2017-08-03 05:35:09 +02:00
];
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
public function MyForm()
{
$fields = new FieldList(
TextField::create('Name'),
EmailField::create('Email')
);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$actions = new FieldList(
FormAction::create('doSubmitForm', 'Submit')
);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$form = new Form($controller, 'MyForm', $fields, $actions);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
return $form
}
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
public function doSubmitForm($data, $form)
{
// Submitted data is available as a map.
echo $data['Name'];
echo $data['Email'];
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// You can also fetch the value from the field.
echo $form->Fields()->dataFieldByName('Email')->Value();
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// Using the Form instance you can get / set status such as error messages.
$form->sessionMessage('Successful!', 'good');
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
// After dealing with the data you can redirect the user back.
return $this->redirectBack();
}
}
2017-08-03 05:35:09 +02:00
2016-12-30 00:17:15 +01:00
```
2014-10-19 10:32:34 +02:00
2021-05-20 10:07:44 +02:00
See [how_tos/handle_nested_data ](How to: Handle nested form data ) for more advanced use cases.
2014-10-19 10:32:34 +02:00
## Validation
2017-07-03 03:22:12 +02:00
Form validation is handled by the [Validator ](api:SilverStripe\Forms\Validator ) class and the `validator` property on the `Form` object. The validator
is provided with a name of each of the [FormField ](api:SilverStripe\Forms\FormField )s to validate and each `FormField` instance is responsible for
2014-10-19 10:32:34 +02:00
validating its' own data value.
For more information, see the [Form Validation ](validation ) documentation.
2016-12-30 00:17:15 +01:00
```php
2017-08-03 05:35:09 +02:00
$validator = new SilverStripe\Forms\RequiredFields([
2016-12-30 00:17:15 +01:00
'Name',
'Email'
2017-08-03 05:35:09 +02:00
]);
2014-10-19 10:32:34 +02:00
2016-12-30 00:17:15 +01:00
$form = new Form($this, 'MyForm', $fields, $actions, $validator);
```
2014-10-19 10:32:34 +02:00
2017-11-27 04:39:17 +01:00
## Related Lessons
2018-06-29 16:03:32 +02:00
* [Introduction to frontend forms ](https://www.silverstripe.org/learn/lessons/v4/introduction-to-frontend-forms-1 )
2017-11-27 04:39:17 +01:00
2014-10-19 10:32:34 +02:00
## API Documentation
2017-07-03 03:22:12 +02:00
* [Form ](api:SilverStripe\Forms\Form )
* [FormField ](api:SilverStripe\Forms\FormField )
* [FieldList ](api:SilverStripe\Forms\FieldList )
* [FormAction ](api:SilverStripe\Forms\FormAction )