diff --git a/docs/en/02_Developer_Guides/00_Model/09_Validation.md b/docs/en/02_Developer_Guides/00_Model/09_Validation.md new file mode 100644 index 000000000..4a80e2d28 --- /dev/null +++ b/docs/en/02_Developer_Guides/00_Model/09_Validation.md @@ -0,0 +1 @@ +* stub, talk validate() \ No newline at end of file diff --git a/docs/en/02_Developer_Guides/03_Forms/00_Forms.md b/docs/en/02_Developer_Guides/03_Forms/00_Forms.md deleted file mode 100644 index ec38465a8..000000000 --- a/docs/en/02_Developer_Guides/03_Forms/00_Forms.md +++ /dev/null @@ -1,586 +0,0 @@ -# Forms - -HTML forms are in practice the most used way to interact with a user. -SilverStripe provides classes to generate and handle the actions and data from a -form. - -## Overview - -A fully implemented form in SilverStripe includes a couple of classes that -individually have separate concerns. - -* Controller — Takes care of assembling the form and receiving data from it. -* Form — Holds sets of fields, actions and validators. -* FormField — Fields that receive data or displays them, e.g input fields. -* FormActions — Buttons that execute actions. -* Validators — Validate the whole form. - -Depending on your needs you can customize and override any of the above classes; -the defaults, however, are often sufficient. - -## The Controller - -Forms start at the controller. Here is a simple example on how to set up a form -in a controller. - -**Page.php** - - :::php - class Page_Controller extends ContentController { - - private static $allowed_actions = array( - 'HelloForm' - ); - - // Template method - public function HelloForm() { - $fields = new FieldList(); - $actions = new FieldList( - FormAction::create("doSayHello")->setTitle("Say hello") - ); - $form = new Form($this, 'HelloForm', $fields, $actions); - // Load the form with previously sent data - $form->loadDataFrom($this->request->postVars()); - return $form; - } - - public function doSayHello($data, Form $form) { - // Do something with $data - return $this->render(); - } - } - -The name of the form ("HelloForm") is passed into the `Form` constructor as a -second argument. It needs to match the method name. - -Because forms need a URL, the `HelloForm()` method needs to be handled like any -other controller action. To grant it access through URLs, we add it to the -`$allowed_actions` array. - -Form actions ("doSayHello"), on the other hand, should _not_ be included in -`$allowed_actions`; these are handled separately through -`Form->httpSubmission()`. - -You can control access on form actions either by conditionally removing a -`FormAction` from the form construction, or by defining `$allowed_actions` in -your own `Form` class (more information in the -["controllers" topic](/topics/controllers)). - -**Page.ss** - - :::ss - <%-- place where you would like the form to show up --%> -
$HelloForm
- -
-Be sure to add the Form name 'HelloForm' to your controller's $allowed_actions -array to enable form submissions. -
- -
-You'll notice that we've used a new notation for creating form fields, using -`create()` instead of the `new` operator. These are functionally equivalent, but -allows PHP to chain operations like `setTitle()` without assigning the field -instance to a temporary variable. For in-depth information on the create syntax, -see the [Injector](/reference/injector) documentation or the API documentation -for `[api:Object]`::create(). -
- -## The Form - -Form is the base class of all forms in a SilverStripe application. Forms in your -application can be created either by instantiating the Form class itself, or by -subclassing it. - -### Instantiating a form - -Creating a form is a matter of defining a method to represent that form. This -method should return a form object. The constructor takes the following -arguments: - -* `$controller`: This must be an instance of the controller that contains the - form, often `$this`. -* `$name`: This must be the name of the method on that controller that is - called to return the form. The first two arguments allow the form object - to be re-created after submission. **It's vital that they be properly - set—if you ever have problems with a form action handler not working, - check that these values are correct.** -* `$fields`: A `[api:FieldList]` containing `[api:FormField]` instances make - up fields in the form. -* `$actions`: A `[api:FieldList]` containing the `[api:FormAction]` objects - - the buttons at the bottom. -* `$validator`: An optional `[api:Validator]` for validation of the form. - -Example: - - :::php - // Controller action - public function MyCustomForm() { - $fields = new FieldList( - EmailField::create("Email"), - PasswordField::create("Password") - ); - $actions = new FieldList(FormAction::create("login")->setTitle("Log in")); - return new Form($this, "MyCustomForm", $fields, $actions); - } - - -## Subclassing a form - -It's the responsibility of your subclass's constructor to call - - :::php - parent::__construct() - -with the right parameters. You may choose to take $fields and $actions as -arguments if you wish, but $controller and $name must be passed—their values -depend on where the form is instantiated. - - :::php - class MyForm extends Form { - public function __construct($controller, $name) { - $fields = new FieldList( - EmailField::create("Email"), - PasswordField::create("Password") - ); - $actions = new FieldList(FormAction::create("login")->setTitle("Log in")); - - parent::__construct($controller, $name, $fields, $actions); - } - } - - -The real difference, however, is that you can then define your controller -methods within the form class itself. This means that the form takes -responsibilities from the controller and manage how to parse and use the form -data. - -**Page.php** - - :::php - class Page_Controller extends ContentController { - - private static $allowed_actions = array( - 'HelloForm', - ); - - // Template method - public function HelloForm() { - return new MyForm($this, 'HelloForm'); - } - } - -**MyForm.php** - - :::php - class MyForm extends Form { - - public function __construct($controller, $name) { - $fields = new FieldList( - EmailField::create("Email"), - PasswordField::create("Password") - ); - - $actions = new FieldList(FormAction::create("login")->setTitle("Log in")); - - parent::__construct($controller, $name, $fields, $actions); - } - - public function login(array $data, Form $form) { - // Authenticate the user and redirect the user somewhere - Controller::curr()->redirectBack(); - } - } - -## The FormField classes - -There are many classes extending `[api:FormField]`. There is a full overview at -[form field types](/reference/form-field-types). - - -### Using Form Fields - -To get these fields automatically rendered into a form element, all you need to -do is create a new instance of the class, and add it to the `FieldList` of the -form. - - :::php - $form = new Form( - $this, // controller - "SignupForm", // form name - new FieldList( // fields - TextField::create("FirstName")->setTitle('First name'), - TextField::create("Surname")->setTitle('Last name')->setMaxLength(50), - EmailField::create("Email")->setTitle("Email address")->setAttribute('type', 'email') - ), - new FieldList( // actions - FormAction::create("signup")->setTitle("Sign up") - ), - new RequiredFields( // validation - "Email", "FirstName" - ) - ); - -## Readonly - -You can turn a form or individual fields into a readonly version. This is handy -in the case of confirmation pages or when certain fields cannot be edited due to -permissions. - -Readonly on a Form - - :::php - $myForm->makeReadonly(); - - -Readonly on a FieldList - - :::php - $myFieldList->makeReadonly(); - - -Readonly on a FormField - - :::php - $myReadonlyField = $myField->transform(new ReadonlyTransformation()); - // shortcut - $myReadonlyField = $myField->performReadonlyTransformation(); - - -## Custom form templates - -You can use a custom form template to render with, instead of *Form.ss* - -It's recommended you do this only if you have a lot of presentation text or -graphics that surround the form fields. This is better than defining those as -*LiteralField* objects, as it doesn't clutter the data layer with presentation -junk. - -First you need to create your own form class extending Form; that way you can -define a custom template using a `forTemplate()` method on your Form class. - - :::php - class MyForm extends Form { - - public function __construct($controller, $name) { - $fields = new FieldList( - EmailField::create("Email"), - PasswordField::create("Password") - ); - - $actions = new FieldList(FormAction::create("login")->setTitle("Log in")); - parent::__construct($controller, $name, $fields, $actions); - } - - public function login(array $data, Form $form) { - // Do something with $data - Controller::curr()->redirectBack(); - } - - public function forTemplate() { - return $this->renderWith(array($this->class, 'Form')); - } - } - -`MyForm->forTemplate()` tells the `[api:Form]` class to render with a template -of return value of `$this->class`, which in this case is *MyForm*. If the -template doesn't exist, then it falls back to using Form.ss. - -*MyForm.ss* should then be placed into your *templates/Includes* directory for your project. Here is an example of -basic customisation, with two ways of presenting the field and its inline validation: - - :::ss -
- <% if $Message %> -

$Message

- <% else %> - - <% end_if %> - -
- - -
- - <% with $Fields.dataFieldByName(Password) %> - $field - <% if $Message %> -

$Message

- <% end_if %> - <% end_with %> -
- - $Fields.dataFieldByName(SecurityID) -
- - <% if $Actions %> -
- <% loop $Actions %>$Field<% end_loop %> -
- <% end_if %> -
- -`$Fields.dataFieldByName(FirstName)` will return the form control contents of -`Field()` for the particular field object, in this case `EmailField->Field()` or -`PasswordField->Field()` which returns an `` element with specific markup -for the type of field. Pass in the name of the field as the first parameter, as -done above, to render it into the template. - -To find more methods, have a look at the `[api:Form]` class and -`[api:FieldList]` class as there is a lot of different methods of customising -the form templates. An example is that you could use `<% loop $Fields %>` -instead of specifying each field manually, as we've done above. - -### Custom form field templates - -The easiest way to customize form fields is adding CSS classes and additional attributes. - - :::php - $field = TextField::create('MyText') - ->addExtraClass('largeText'); - ->setAttribute('data-validation-regex', '[\d]*'); - -Will be rendered as: - - :::html - - -Each form field is rendered into a form via the -`[FormField->FieldHolder()](api:FormField)` method, which includes a container -`
` as well as a `