Solstice comes with a built in object oriented validation engine. In this guide we’ll explore how to use it for several common validation needs, and see how it ties in with LangService and the templating system.
Making a form field required
For our first example, we’re going to be validating the following form:

If the user enters text, they can move to the next screen, but if not, we want them to return to the form, and have it look like this:

To make this email input required, we need to define a validate method in the controller for this page. (See Defining Page Flows in your Application) Inside the validate method, you can specify that fields are required, or optional, and add custom validation routines for specific fields. We want this field to be required, so we will be using createRequiredParam, which takes as an argument the name of the input field. To have Solstice run the validation, your controller needs to make a call to processConstraints().
Here is the validate method that we would need to make the email field above be required:
Perl
sub validate {
my $self = shift;
$self->createRequiredParam('email_input');
return $self->processConstraints();
}Here is the template used:
HTML
<label for=
"email_input"
><!-- sol_var email_text --></label>
<input type=
"text"
id=
"email_input"
name=
"email_input"
value=
""
>
<!-- sol_var err_email_input --><br />
<div>
<!-- sol_var save_button -->
</div>
All we needed to do to make the error message to show up was this template variable:
HTML
<!-- sol_var err_email_input -->
The validation engine created that variable automatically. All inputs will have an extra err_<variable_name> variable created for them, which can be placed anywhere in the template.
Optional fields, and data validation
For the next step, we're going to add an optional input for an address. To make this example easy to deal with, we're not going to try to ensure that the address is valid, but we're going to make sure it's at least 10 characters long, and no more than 100. We're going to start with a form that looks like this:

and end up with a screen that looks like this if an invalid address is entered:

Extending our validation method
The first thing we're going to do is add the extra validation paramaters. To create an optional field, use the method createOptionalParam(). Like createRequiredParam(), it takes as it's argument the name of the field. Both of these methods return a Solstice::Validation object, which you can use to add specific constraints. Since we want to add a length constraint, we'll add this line to the validate method above:
Perl
my $address_constraint = $self->createOptionalParam('address');A length constraint is a built-in Solstice constraint. For a full listing of built in constraints, see Validation API. We're going to be using the addLengthConstraint() method, which can set a minimum and/or a maximum length constraint.
Perl
$address_constraint->addLengthConstraint('address_length_error', { min => 10, max => 100 });All constraints take for their first argument a name in the language file's error section.
Extending the Template
To add the address field to the page, we just need to add another section to the template, which will look very much like the email field.
HTML
<label for=
"address"
><!-- sol_var address_text --></label>
<input type=
"text"
id=
"address"
name=
"address"
value=
""
>
<!-- sol_var err_address --><br />
Just like before, we just need to add an err_address to show any error that is connected to the address field.
LangFile Entry
In the <errs> section, we had to add the following key:
<err name="address_length_error">Please enter between 10 and 100 characters.</err>
Custom Validation
Now we're going to add a phone number input to our form. It will again be optional, but we want to make sure that the phone number has the following format: (###) ###-####. This is a bit strict, and north america centric, but the goal here is to making a custom validation constraint, not the world's best phone number validator :)
Here is the new form, before validation:

Here it is after an invalid phone number is entered:

Extending validate
Just like with the address input, we're going to start by creating a new optional paramater:
Perl
my $phone_constraint = $self->createOptionalParam('phonenum');Next we need to add the custom constraints. In the Solstice validation engine, constraints work by way of callbacks, so we created an object method in our controller that returns a subroutine reference. This could be inlined, but this looks a bit cleaner, and it makes it so we can move the code around in our project, so more controllers can use it.
Here is how the custom constaint is added:
Perl
$phone_constraint->addConstraint('phone_format_error', $self->getPhoneNumberValidator());where getPhoneNumberValidator() is the method that returns the subroutine reference.
Here is the definition of that method:
Perl
sub getPhoneNumberValidator {
my $self = shift;
return sub {
my $param = shift;
return $param =~ /^\([\d]{3}\) [\d]{3}-[\d]{4}$/;
};
}Modifying the template
The template changes at this point should be looking pretty familiar...
HTML
<label for=
"phonenum"
><!-- sol_var phone_text --></label>
<input type=
"text"
id=
"phonenum"
name=
"phonenum"
value=
""
>
<!-- sol_var err_phonenum --><br />
LangFile entry
In the <errs> section, we had to add this entry:
<err name="phone_format_error">Please enter a number as follows: (###) ###-####</err>
Grouped Dependencies
In the process of making this nice little form, we've forgotten a very important bit of information: the person's name. We'll want to collect their first and last names, so we can do some smart sorting later on, and this should obviously be required... but we don't want Cher to have problems using our forms. Want we want is a grouped dependency, where there needs to be a response to one of our form inputs, but either one will be fine.
Here is the new form:

Again, after this grouped dependency fails:

Adding to Validate
Grouped dependencies have 3 things that need to be specified. There's the name of the dependency, the number of fields that are required, and then the names of the fields. Unlike required and optional constraints, no data validation restrictions can be added to a grouped dependency. To restrict the type of data, you will need to create optional constraints for every input field they apply to.
For this example, here is all we need to do to make one of the two fields required:
Perl
$self->createGroupDependency({ dependency_name => 'name_or_surname', require => 1, fields => ['name', 'surname'] });The name of the dependency is treated in the template just like it was the name of a form field, so if you want to show an error for the dependency, your template needs to reference err_<dependency_name>.
Adding to the template
The changes to the template are very similiar to the others, except there is only one error template variable that is added.
HTML
<label for=
"name"
><!-- sol_var name_text --></label>
<input type=
"text"
id=
"name"
name=
"name"
value=
""
>
<br />
<label for=
"surname"
><!-- sol_var surname_text --></label>
<input type=
"text"
id=
"surname"
name=
"surname"
value=
""
>
<!-- sol_var err_name_or_surname --><br />
File Listing
Template
Controller
View
LangFile