mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Combine form validation topic with forms topic
- Proofread entire file (forms & form validation topics) - Re-wrap paragraphs to 80 columns - Correct/update links from other doc files
This commit is contained in:
parent
429fdfaa72
commit
46695d3b4b
@ -720,7 +720,7 @@ an object, not for displaying the objects contained in the relation.
|
||||
## Validation and Constraints
|
||||
|
||||
Traditionally, validation in SilverStripe has been mostly handled on the
|
||||
controller through [form validation](/topics/form-validation).
|
||||
controller through [form validation](/topics/forms#form-validation).
|
||||
|
||||
While this is a useful approach, it can lead to data inconsistencies if the
|
||||
record is modified outside of the controller and form context.
|
||||
|
@ -1,159 +0,0 @@
|
||||
# Form Validation
|
||||
|
||||
SilverStripe provides PHP form validation out of the box,
|
||||
but doesn't come with any built-in JavaScript validation
|
||||
(the previously used `Validator.js` approach has been deprecated).
|
||||
|
||||
## Required Fields
|
||||
|
||||
Validators are implemented as an argument to the `[api:Form]` constructor,
|
||||
and are subclasses of the abstract `[api:Validator]` base class.
|
||||
The only implementation which comes with SilverStripe is
|
||||
the `[api:RequiredFields]` class, which ensures fields are filled out
|
||||
when the form is submitted.
|
||||
|
||||
:::php
|
||||
public function Form() {
|
||||
$form = new Form($this, 'Form',
|
||||
new FieldList(
|
||||
new TextField('MyRequiredField'),
|
||||
new TextField('MyOptionalField')
|
||||
),
|
||||
new FieldList(
|
||||
new FormAction('submit', 'Submit form')
|
||||
),
|
||||
new RequiredFields(array('MyRequiredField'))
|
||||
);
|
||||
// Optional: Add a CSS class for custom styling
|
||||
$form->dataFieldByName('MyRequiredField')->addExtraClass('required');
|
||||
return $form;
|
||||
}
|
||||
|
||||
## Form Field Validation
|
||||
|
||||
Form fields are responsible for validating the data they process,
|
||||
through the `[api:FormField->validate()] method. There are many fields
|
||||
for different purposes (see ["form field types"](/reference/form-field-types) for a full list).
|
||||
|
||||
## Adding your own validation messages
|
||||
|
||||
In many cases, you want to add PHP validation which is more complex than
|
||||
validating the format or existence of a single form field input.
|
||||
For example, you might want to have dependent validation on
|
||||
a postcode which depends on the country you've selected in a different field.
|
||||
|
||||
There's two ways to go about this: Either you can attach a custom error message
|
||||
to a specific field, or a generic message for the whole form.
|
||||
|
||||
Example: Validate postcodes based on the selected country (on the controller).
|
||||
|
||||
:::php
|
||||
class MyController extends Controller {
|
||||
private static $allowed_actions = array('Form');
|
||||
public function Form() {
|
||||
return Form::create($this, 'Form',
|
||||
new FieldList(
|
||||
new NumericField('Postcode'),
|
||||
new CountryDropdownField('Country')
|
||||
),
|
||||
new FieldList(
|
||||
new FormAction('submit', 'Submit form')
|
||||
),
|
||||
new RequiredFields(array('Country'))
|
||||
);
|
||||
}
|
||||
public function submit($data, $form) {
|
||||
// At this point, RequiredFields->validate() will have been called already,
|
||||
// so we can assume that the values exist.
|
||||
|
||||
// German postcodes need to be five digits
|
||||
if($data['Country'] == 'de' && isset($data['Postcode']) && strlen($data['Postcode']) != 5) {
|
||||
$form->addErrorMessage('Postcode', 'Need five digits for German postcodes', 'bad');
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
// Global validation error (not specific to form field)
|
||||
if($data['Country'] == 'IR' && isset($data['Postcode']) && $data['Postcode']) {
|
||||
$form->sessionMessage("Ireland doesn't have postcodes!", 'bad');
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
// continue normal processing...
|
||||
}
|
||||
}
|
||||
|
||||
## JavaScript Validation
|
||||
|
||||
While there are no built-in JavaScript validation handlers in SilverStripe,
|
||||
the `FormField` API is flexible enough to provide the information required
|
||||
in order to plug in custom libraries.
|
||||
|
||||
### HTML5 attributes
|
||||
|
||||
HTML5 specifies some built-in form validations ([source](http://www.w3.org/wiki/HTML5_form_additions)),
|
||||
which are evaluated by modern browsers without any need for JavaScript.
|
||||
SilverStripe supports this by allowing to set custom attributes on fields.
|
||||
|
||||
:::php
|
||||
// Markup contains <input type="text" required />
|
||||
TextField::create('MyText')->setAttribute('required', true);
|
||||
|
||||
// Markup contains <input type="url" pattern="https?://.+" />
|
||||
TextField::create('MyText')
|
||||
->setAttribute('type', 'url')
|
||||
->setAttribute('pattern', 'https?://.+')
|
||||
|
||||
### HTML5 metadata
|
||||
|
||||
In addition, HTML5 elements can contain custom data attributes with the `data-` prefix.
|
||||
These are general purpose attributes, but can be used to hook in your own validation.
|
||||
|
||||
:::php
|
||||
// Validate a specific date format (in PHP)
|
||||
// Markup contains <input type="text" data-dateformat="dd.MM.yyyy" />
|
||||
DateField::create('MyDate')->setConfig('dateformat', 'dd.MM.yyyy');
|
||||
|
||||
// Limit extensions on upload (in PHP)
|
||||
// Markup contains <input type="file" data-allowed-extensions="jpg,jpeg,gif" />
|
||||
$exts = array('jpg', 'jpeg', 'gif');
|
||||
$validator = new Upload_Validator();
|
||||
$validator->setAllowedExtensions($exts);
|
||||
$upload = Upload::create()->setValidator($validator);
|
||||
$fileField = FileField::create('MyFile')->setUpload(new);
|
||||
$fileField->setAttribute('data-allowed-extensions', implode(',', $exts));
|
||||
|
||||
Note that these examples don't have any effect on the client as such,
|
||||
but are just a starting point for custom validation with JavaScript.
|
||||
|
||||
## Model Validation
|
||||
|
||||
An alternative (or additional) approach to validation is to place it directly
|
||||
on the model. SilverStripe provides a `[api:DataObject->validate()]` method for this purpose.
|
||||
Refer to the ["datamodel" topic](/topics/datamodel#validation-and-constraints) for more information.
|
||||
|
||||
## Validation in the CMS
|
||||
|
||||
Since you're not creating the forms for editing CMS records,
|
||||
SilverStripe provides you with a `getCMSValidator()` method on your models
|
||||
to return a `[api:Validator]` instance.
|
||||
|
||||
:::php
|
||||
class Page extends SiteTree {
|
||||
private static $db = array('MyRequiredField' => 'Text');
|
||||
|
||||
public function getCMSValidator() {
|
||||
return new RequiredFields(array('MyRequiredField'));
|
||||
}
|
||||
}
|
||||
|
||||
## Subclassing Validator
|
||||
|
||||
To create your own validator, you need to subclass validator and define two methods:
|
||||
|
||||
* **javascript()** Should output a snippet of JavaScript that will get called to perform javascript validation.
|
||||
* **php($data)** Should return true if the given data is valid, and call $this->validationError() if there were any
|
||||
errors.
|
||||
|
||||
## Related
|
||||
|
||||
* Model Validation with [api:DataObject->validate()]
|
@ -1,6 +1,6 @@
|
||||
# Forms
|
||||
|
||||
HTML forms are in practice the most used way to communicate with a browser.
|
||||
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.
|
||||
|
||||
@ -9,14 +9,14 @@ form.
|
||||
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 - Often submit buttons that executes actions.
|
||||
* Validators - Validate the whole form, see [Form validation](form-validation.md) topic for more information.
|
||||
* 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—Often submit buttons that executes actions.
|
||||
* Validators—Validate the whole form.
|
||||
|
||||
Depending on your needs you can customize and override any of the above classes,
|
||||
however the defaults are often sufficient.
|
||||
Depending on your needs you can customize and override any of the above classes;
|
||||
the defaults, however, are often sufficient.
|
||||
|
||||
## The Controller
|
||||
|
||||
@ -53,12 +53,13 @@ in a controller.
|
||||
The name of the form ("HelloForm") is passed into the `Form` constructor as a
|
||||
second argument. It needs to match the method name.
|
||||
|
||||
Since forms need a URL, the `HelloForm()` method needs to be handled like any
|
||||
other controller action. In order to whitelist its access through URLs, we add
|
||||
it to the `$allowed_actions` array.
|
||||
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 here, these
|
||||
are handled separately through `Form->httpSubmission()`.
|
||||
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
|
||||
@ -68,19 +69,21 @@ your own `Form` class (more information in the
|
||||
**Page.ss**
|
||||
|
||||
:::ss
|
||||
<!-- place where you would like the form to show up -->
|
||||
<%-- place where you would like the form to show up --%>
|
||||
<div>$HelloForm</div>
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
Be sure to add the Form name 'HelloForm' to the Controller::$allowed_actions()
|
||||
to be sure that form submissions get through to the correct action.
|
||||
Be sure to add the Form name 'HelloForm' to your controller's $allowed_actions
|
||||
array to enable form submissions.
|
||||
</div>
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
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().
|
||||
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().
|
||||
</div>
|
||||
|
||||
## The Form
|
||||
@ -95,12 +98,17 @@ 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
|
||||
fields allow the form object to be re-created after submission. **It's vital that they are properly set - if you ever
|
||||
have problems with 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.
|
||||
* `$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:
|
||||
@ -119,13 +127,14 @@ Example:
|
||||
|
||||
## Subclassing a form
|
||||
|
||||
It's the responsibility of your subclass' constructor to call
|
||||
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.
|
||||
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 {
|
||||
@ -141,8 +150,9 @@ $name must be passed - their values depend on where the form is instantiated.
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
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**
|
||||
@ -214,7 +224,7 @@ form.
|
||||
## 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 can be edited due to
|
||||
in the case of confirmation pages or when certain fields cannot be edited due to
|
||||
permissions.
|
||||
|
||||
Readonly on a Form
|
||||
@ -241,10 +251,13 @@ Readonly on a FormField
|
||||
|
||||
You can use a custom form template to render with, instead of *Form.ss*
|
||||
|
||||
It's recommended you only do this if you've got a lot of presentation text, 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.
|
||||
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 of all, you need to create your form on it's own class, that way you can define a custom template using a `forTemplate()` method on your Form class.
|
||||
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 {
|
||||
@ -305,14 +318,16 @@ your project. Here is an example of basic customization:
|
||||
<% end_if %>
|
||||
</form>
|
||||
|
||||
`$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 `<input>` 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.
|
||||
`$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 `<input>` 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.
|
||||
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
|
||||
|
||||
@ -333,19 +348,20 @@ Each form field is rendered into a form via the
|
||||
`<div>` as well as a `<label>` element (if applicable).
|
||||
|
||||
You can also render each field without these structural elements through the
|
||||
`[FormField->Field()](api:FormField)` method. In order to influence the form
|
||||
rendering, overloading these two methods is a good start.
|
||||
`[FormField->Field()](api:FormField)` method. To influence form rendering,
|
||||
overriding these two methods is a good start.
|
||||
|
||||
In addition, most form fields are rendered through SilverStripe templates, e.g.
|
||||
`TextareaField` is rendered via `framework/templates/forms/TextareaField.ss`.
|
||||
In addition, most form fields are rendered through SilverStripe templates; for
|
||||
example, `TextareaField` is rendered via
|
||||
`framework/templates/forms/TextareaField.ss`.
|
||||
|
||||
These templates can be overwritten globally by placing a template with the same
|
||||
name in your `mysite` directory, or set on a form field instance via anyone of
|
||||
These templates can be overridden globally by placing a template with the same
|
||||
name in your `mysite` directory, or set on a form field instance via any of
|
||||
these methods:
|
||||
|
||||
- FormField->setTemplate()
|
||||
- FormField->setFieldHolderTemplate()
|
||||
- FormField->getSmallFieldHolderTemplate()
|
||||
- FormField->setTemplate()
|
||||
- FormField->setFieldHolderTemplate()
|
||||
- FormField->getSmallFieldHolderTemplate()
|
||||
|
||||
<div class="hint" markdown='1'>
|
||||
Caution: Not all FormFields consistently uses templates set by the above methods.
|
||||
@ -358,7 +374,7 @@ by adding a hidden *SecurityID* parameter to each form. See
|
||||
[secure-development](/topics/security) for details.
|
||||
|
||||
In addition, you should limit forms to the intended HTTP verb (mostly `GET` or `POST`)
|
||||
to further reduce attack surface, by using `[api:Form->setStrictFormMethodCheck()]`.
|
||||
to further reduce attack exposure, by using `[api:Form->setStrictFormMethodCheck()]`.
|
||||
|
||||
:::php
|
||||
$myForm->setFormMethod('POST');
|
||||
@ -391,10 +407,170 @@ Adds a new text field called FavouriteColour next to the Content field in the CM
|
||||
:::php
|
||||
$this->Fields()->addFieldToTab('Root.Content', new TextField('FavouriteColour'), 'Content');
|
||||
|
||||
## Form Validation
|
||||
|
||||
SilverStripe provides PHP form validation out of the box, but doesn't come with
|
||||
any built-in JavaScript validation (the previously used `Validator.js` approach
|
||||
has been deprecated).
|
||||
|
||||
### Required Fields
|
||||
|
||||
Validators are implemented as an argument to the `[api:Form]` constructor, and
|
||||
are subclasses of the abstract `[api:Validator]` base class. The only
|
||||
implementation that comes with SilverStripe is the `[api:RequiredFields]` class,
|
||||
which ensures that fields are filled out when the form is submitted.
|
||||
|
||||
:::php
|
||||
public function Form() {
|
||||
$form = new Form($this, 'Form',
|
||||
new FieldList(
|
||||
new TextField('MyRequiredField'),
|
||||
new TextField('MyOptionalField')
|
||||
),
|
||||
new FieldList(
|
||||
new FormAction('submit', 'Submit form')
|
||||
),
|
||||
new RequiredFields(array('MyRequiredField'))
|
||||
);
|
||||
// Optional: Add a CSS class for custom styling
|
||||
$form->dataFieldByName('MyRequiredField')->addExtraClass('required');
|
||||
return $form;
|
||||
}
|
||||
|
||||
### Form Field Validation
|
||||
|
||||
Form fields are responsible for validating the data they process, through the
|
||||
`[api:FormField->validate()]` method. There are many fields for different
|
||||
purposes (see ["form field types"](/reference/form-field-types) for a full list).
|
||||
|
||||
### Adding your own validation messages
|
||||
|
||||
In many cases, you want to add PHP validation that is more complex than
|
||||
validating the format or existence of a single form field input. For example,
|
||||
you might want to have dependent validation on a postcode which depends on the
|
||||
country you've selected in a different field.
|
||||
|
||||
There are two ways to go about this: attach a custom error message to a specific
|
||||
field, or a generic message to the whole form.
|
||||
|
||||
Example: Validate postcodes based on the selected country (on the controller).
|
||||
|
||||
:::php
|
||||
class MyController extends Controller {
|
||||
private static $allowed_actions = array('Form');
|
||||
public function Form() {
|
||||
return Form::create($this, 'Form',
|
||||
new FieldList(
|
||||
new NumericField('Postcode'),
|
||||
new CountryDropdownField('Country')
|
||||
),
|
||||
new FieldList(
|
||||
new FormAction('submit', 'Submit form')
|
||||
),
|
||||
new RequiredFields(array('Country'))
|
||||
);
|
||||
}
|
||||
public function submit($data, $form) {
|
||||
// At this point, RequiredFields->validate() will have been called already,
|
||||
// so we can assume that the values exist.
|
||||
|
||||
// German postcodes need to be five digits
|
||||
if($data['Country'] == 'de' && isset($data['Postcode']) && strlen($data['Postcode']) != 5) {
|
||||
$form->addErrorMessage('Postcode', 'Need five digits for German postcodes', 'bad');
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
// Global validation error (not specific to form field)
|
||||
if($data['Country'] == 'IR' && isset($data['Postcode']) && $data['Postcode']) {
|
||||
$form->sessionMessage("Ireland doesn't have postcodes!", 'bad');
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
// continue normal processing...
|
||||
}
|
||||
}
|
||||
|
||||
### JavaScript Validation
|
||||
|
||||
Although there are no built-in JavaScript validation handlers in SilverStripe,
|
||||
the `FormField` API is flexible enough to provide the information required in
|
||||
order to plug in custom libraries.
|
||||
|
||||
#### HTML5 attributes
|
||||
|
||||
HTML5 specifies some built-in form validations
|
||||
([source](http://www.w3.org/wiki/HTML5_form_additions)), which are evaluated by
|
||||
modern browsers without any need for JavaScript. SilverStripe supports this by
|
||||
allowing to set custom attributes on fields.
|
||||
|
||||
:::php
|
||||
// Markup contains <input type="text" required />
|
||||
TextField::create('MyText')->setAttribute('required', true);
|
||||
|
||||
// Markup contains <input type="url" pattern="https?://.+" />
|
||||
TextField::create('MyText')
|
||||
->setAttribute('type', 'url')
|
||||
->setAttribute('pattern', 'https?://.+')
|
||||
|
||||
#### HTML5 metadata
|
||||
|
||||
In addition, HTML5 elements can contain custom data attributes with the `data-`
|
||||
prefix. These are general-purpose attributes, but can be used to hook in your
|
||||
own validation.
|
||||
|
||||
:::php
|
||||
// Validate a specific date format (in PHP)
|
||||
// Markup contains <input type="text" data-dateformat="dd.MM.yyyy" />
|
||||
DateField::create('MyDate')->setConfig('dateformat', 'dd.MM.yyyy');
|
||||
|
||||
// Limit extensions on upload (in PHP)
|
||||
// Markup contains <input type="file" data-allowed-extensions="jpg,jpeg,gif" />
|
||||
$exts = array('jpg', 'jpeg', 'gif');
|
||||
$validator = new Upload_Validator();
|
||||
$validator->setAllowedExtensions($exts);
|
||||
$upload = Upload::create()->setValidator($validator);
|
||||
$fileField = FileField::create('MyFile')->setUpload(new);
|
||||
$fileField->setAttribute('data-allowed-extensions', implode(',', $exts));
|
||||
|
||||
Note that these examples don't have any effect on the client as such, but are
|
||||
just a starting point for custom validation with JavaScript.
|
||||
|
||||
### Model Validation
|
||||
|
||||
An alternative (or additional) approach to validation is to place it directly on
|
||||
the model. SilverStripe provides a `[api:DataObject->validate()]` method for
|
||||
this purpose. Refer to the
|
||||
["datamodel" topic](/topics/datamodel#validation-and-constraints) for more information.
|
||||
|
||||
### Validation in the CMS
|
||||
|
||||
Since you're not creating the forms for editing CMS records, SilverStripe
|
||||
provides you with a `getCMSValidator()` method on your models to return a
|
||||
`[api:Validator]` instance.
|
||||
|
||||
:::php
|
||||
class Page extends SiteTree {
|
||||
private static $db = array('MyRequiredField' => 'Text');
|
||||
|
||||
public function getCMSValidator() {
|
||||
return new RequiredFields(array('MyRequiredField'));
|
||||
}
|
||||
}
|
||||
|
||||
### Subclassing Validator
|
||||
|
||||
To create your own validator, you need to subclass validator and define two methods:
|
||||
|
||||
* **javascript()** Should output a snippet of JavaScript that will get called
|
||||
to perform javascript validation.
|
||||
* **php($data)** Should return true if the given data is valid, and call
|
||||
$this->validationError() if there were any errors.
|
||||
|
||||
## Related
|
||||
|
||||
* [Form Field Types](/reference/form-field-types)
|
||||
* [MultiForm Module](http://silverstripe.org/multi-form-module)
|
||||
* Model Validation with [api:DataObject->validate()]
|
||||
|
||||
## API Documentation
|
||||
|
||||
|
@ -16,8 +16,7 @@ It is where most documentation should live, and is the natural "second step" aft
|
||||
* [Environment management](environment-management): Sharing configuration details (e.g. database login, passwords) with multiple websites via a `_ss_environment.php` file
|
||||
* [Error Handling](error-handling): Error messages and filesystem logs
|
||||
* [Files and Images](files): File and Image management in the database and how to manipulate images
|
||||
* [Form Validation](form-validation): Built-in validation on form fields, and how to extend it
|
||||
* [Forms](forms): Create your own form, add fields and create your own form template using the existing `Form` class
|
||||
* [Forms & form validation](forms): Create your own form, add fields and create your own form template using the existing `Form` class
|
||||
* [Internationalization (i18n)](i18n): Displaying templates and PHP code in different languages using i18n
|
||||
* [Javascript](javascript): Best practices for developing with JavaScript in SilverStripe
|
||||
* [Module Development](module-development): Creating a module (also known as "extension" or "plugin") to contain reusable functionality
|
||||
|
Loading…
Reference in New Issue
Block a user