This bugtracker is archived (announcement). New tickets are created on github.com. See all framework issues, cms issues, and search the module listings for more specific bugtrackers.
wiki:development/validation
Last modified 4 years ago Last modified on 15/02/11 14:03:18

Validation Development Plan

Contact

  • Ingo Schommer (ingo at silverstripe dot com)
  • Sean Harvey (sean at silverstripe dot com)

Status

Brainstorming, early development of jquery integration in project branch (merging into trunk once stabilized a bit)

Research

Symfony validation:

Symfony's form system is very similar to the SilverStripe? one, and you set validators up on a per-Form basis. However, a validation scheme for each field is set manually in Symfony. This seems very useful, as you can define custom parameters on a per-field basis. This would fit with the jQuery validation plugin, for example, you set a message on the EmailField? validation scheme, with say, a min_length of 50 which applies to the server side as well as passes through to the jQuery plugin.

The current scheme of just setting an array of field names isn't sufficient, as it's too weak a configuration setting. Considering we already allow very specific configuration of each fields in a FieldSet? object, we should also allow configuration for each field configured in the Validator object. You also shouldn't have to override the entire FormField? type just to change a validation message.

Takeaways:

  • Custom configuration of each FormField? object on the Validator object, min length, messages etc
  • Optional trim() of the final data value of the submitted data, to check before validating

Current Shortcomings

  • Type checking is poor on data checked against validator (e.g. "0" is considered null)
  • Hardcoded server-generated javascript
  • Hardcoded form onsubmit handlers (no customization)
  • No support for multiple validators (e.g. RequiredFields? shouldn't extend Validator)
  • Validator has to be explicitly defined (breaks assumptions of fields automatically validating?)
  • No support for Form validation within CMS
  • No support for Form validation loaded by ajax
  • No way to change the validation message on a per-field basis
  • Can't define cross-field validation (e.g. user doesn't fill out BankID, which subsequently means another field isn't required)

Requirements

(ordered by priority)

  • Customization of serverside validation by setting validation rules per-field
  • Deprecating RequiredFields?, leaving it as a deprecated class throwing a notice
  • Formfields should be validated "out of the box", not rely on devs explictily adding a validator
  • Localization support (currencies, dates)
  • jQuery Unit Tests for every custom javascript validation method in sapphire
  • Default to validation onchange (rather than onsubmit) - optionally onkeyup?
  • Error CSS classes on <div class="field"> container (rather than input-element)
  • Configuration by FormField? instance (e.g. two CurrencyField? instances on the same form, one only allowing positive values)
  • Validation in CMS as well as Frontend forms by evaluated JSON returns (rather than raw HTML) which inject javascript rules (and script-resources?) into DOM
  • Ajax submission
  • Customization of Serverside and Clientside validation error messages (i18n-enabled? sprintf-support?)
  • Encapsulated behaviour for ajax callbacks (see AjaxUniqueTextField? for bad example)
  • Cleanly separate validation for required (=not empty) from value parsing (currently they're mostly the same javascript method). Example: an empty required date should be caught by the jQuery "require()" method, and the jQuery "validateDate" method should not trigger unless the field is filled out in the first place
  • Summary of errormessages on top of form (clientside only, serverside can continue showing form-specific messages only)
  • Documentation!

Problems

  • Allowing clientside customization of validation plugin with still passing defaults and settings generated on the server?

Clientside Customization

Rendered by Validator.php

var formValidationOptions = {
  'Form_EditForm': {
   rules: {
     name: {
       required: true,
       minlength: 2
     }
   },
   messages: {
     name: {
       required: "We need your email address to contact you",
       minlength: jQuery.format("At least {0} characters required!")
     }
   }
});

// only called if Validator.php->includeJavascriptValidation = true;
$('#Form_EditForm').validate(formValidationOptions.Form_EditForm);

Optionally added by custom javascript:

// or customize yourself by merging objects:
var myValidationOptions = $.merge(formValidationOptions.Form_EditForm, {
  rules: {
   email: { required: true}
  }
});

// remove some stuff we don't need

myValidationOptions.rules.name = null;

// manually instanciating the plugin
$('#Form_EditForm').validate(myValidationOptions);

Serverside Validation

  • Refactor RequiredFields?.php to be fully included in Validator.php (but leave empty class shell for backwards compatibility)
  • Include default validator unless anything else is specified
  • Include sprint_f of server side validation labels, e.g. "%s <small>*</small>" where %s is the label
  • Allow for some way to define cross field validation? e.g. "If BankID isn't filled out, then BankName? isn't required"
$form = new Form(
  $this,
  'Form',
  new FieldSet(
    $emailField = new EmailField('Email')
  ),
  ...
}
$emailField->setValidator(array('required' => true));
$form = new Form(
  $this,
  'Form',
  new FieldSet(
    new EmailField('Email')
  ),
  ...
}
$form->setValidator(array(
  'Email' => array('required' => true))
);

Use Cases for Customization on FormField? instance

Custom Validation Methods

Advanced

  • Javascript validation for dynamically generated fields in the DOM (e.g. new rows on TableField?) - should work with livequery and validation-triggers on html classes

TODO

  • TODO Clarify usage of DataObject::validate() and ValidationResult? class
  • TODO Clarify execution chain from Form::saveInto() to model validation to getting validation feedback returned to the user

References