Try the beta version of the new SilverStripe documentation

For the next 2 weeks you can use the new documentation website and give us your feedback.

close

This document contains information for an outdated version (3.0) and may not be maintained any more.

If some of your projects still use this version, consider upgrading as soon as possible.

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 Form constructor, and are subclasses of the abstract Validator base class. The only implementation which comes with SilverStripe is the RequiredFields class, which ensures fields are filled out when the form is submitted.

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 FormField->validate()&version=3.0&module=framework) method. There are many fields for different purposes (see "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).

class MyController extends Controller {
    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), which are evaluated by modern browsers without any need for JavaScript. SilverStripe supports this by allowing to set custom attributes on fields.

// 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.

// 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 DataObject->validate()&version=3.0&module=framework) method for this purpose. Refer to the "datamodel" topic for more information.

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.

Comments

Comment policy: Please use comments for tips and corrections about the described functionality.
Comments are moderated, we reserve the right to remove comments that are inappropriate or are no longer relevant. Use the Silverstripe Forum to ask questions.

blog comments powered by Disqus