Getting started
Within any template which supports form validation, there will be a fv object. You define additional validation rules for the fields in your form which get added to this central object. Validation rules are defined in a chain-like style; if you've used the jQuery javascript library before you might be familiar with this format already. It's also important you declare the validation rules at the top of the template file you are using otherwise the rules may not be processed properly.
Adding a validation rule
The rules are applied to the field which has the current context. You can set which field has the current context by using the field() method. In the following example we add a rule to the first_name field which ensures it must be between 0 and 40 characters in length. The field name (in this case first_name) is derived from the name attribute of the <input> field within the HTML:
{{ fv.field('first_name').rule('length[0,40]') }}
Rules are defined using the rule() method. You pass in a special keyword (from a set of pre-defined rules) which defines the rule to apply to a field as well as any parameters needed to configure it. Not all rules require parameters.
If a visitor tries to submit the form without meeting the rule's requirements they will be shown an automatically generated error message explaining the problem. If the default error message doesn't meet your needs you can override it by passing in a second parameter to rule() like so:
{{ fv.field('first_name').rule('length[0,40]','Your first name must not be longer than 40 characters') }}
The following example shows how you can chain multiple rules together for a field.
{{ fv.field('email_address').rule('length[0,100]').rule('email') }}
In this case, the email_address field must be between 0 and 100 characters and must be in a valid email format. e.g bob@example.org.
Adding a rule to a field automatically makes that field mandatory (i.e. a valid value must be submitted for that form to pass validation and be processed). If you want to make a field mandatory without specifying any rules you can use the mandatory() method:
{{ fv.field('last_name').mandatory() }}
In this case, if the visitor enters anything into the field it will pass validation. Alternatively you can make fields optional by using the optional() method. In this case the validation rules will only be applied if the field contains a value.
{{ fv.field('fav_number').optional().rule('number').rule('range[0,99]') }}
This section has only covered the basics of the form validation system used within OmCore. There are many additional methods you can call which will let you customise both the functionality of the validation and any error messages displayed.
A list of all available rules can be found at the end of this document. If you have suggestions for new rules which you think may be useful please email them to support@omcore.net. Is this the right email address to use?
Displaying errors and handling invalid submissions
When a visitor enters data into your form which doesn't meet validation rules and tries to submit it they will get brought back to the same page. You can then display the errors they made and give them a chance to submit the form again with the fields corrected. There's a few ways to do this. Firstly, we include a method called error_html() which will automatically generate the error message HTML for you. If there are no errors (i.e. when a form first loads), then nothing is output. It's placed at the top of a form and used like so:
{{ fv.error_html() }}
It prints the validation errors in a <ul> list contained within a <div>. This should be adequate for many people, however if you require more control over the output you can access the errors array directly using the has_errors() method and the errors() method:
{% if form_validation.has_errors %}
<div class="form_errors">
<p>There was a problem with the details you submitted:</p>
<ul>
{% for field in form_validation.errors() %}
{% for error in field %}
<li>{{ error }}</li>
{% endfor %}
{% endfor %}
</ul>
</div>
{% endif %}
Notice that the errors are stored in a two dimension array, split up by field name and error name.
For usability reasons it's important that you also present the data which was originally submitted back to the visitor so that they don't have to re-enter it again. The submitted form data can be accessed through the data() method:
<input type="text" name="first_name" value="{{ fv.data.first_name }}">
<input type="text" name="last_name" value="{{ fv.data.last_name }}">
<textarea name="message">{{ fv.data.message }}</textarea>
Filters
Filters are a way of automatically formatting the value of a field submitted through a form. This formatted data can then be used later on within the forms processing e.g when it gets inserted into a database or populates an email.
Filters are defined in a similar manner to rules and can can take parameters if needed. In the following example, any text which the user enters into the product_code field will be converted to uppercase:
{{ fv.field('product_code').filter('upper') }}
Filters can be used in conjunction with rules and can be chained as well, the following is a perfectly valid example:
{{ fv.field('name').optional().rule('length[5,*]').filter('trim').filter('lower') }}
A list of all available filters can be found at the end of this document.
Spam prevention
Spam is a common problem with forms on the web. Malicious spiders operated by spammers trawl through sites looking for forms where they can submit false or made up data, often with a website URL, hoping it ends up getting noticed or inadvertently clicked. One way of preventing this is to require the visitor to answer a question or identify a word which can only be answered by a human before the form can be successfully submitted. This technique is known as a captcha.
You can easily set up captchas using OmCore's form validation system using the require_captcha() method. Calling this method ensures that the form will only be submitted if a valid captcha answer has been supplied with the rest of the form data. It's used like so:
{{ fv.require_captcha() }}
You must also display the captcha code which the visitor has to enter and a text field for submitting the code, this is done by placing {{ fv.captcha }} at the point in your template where you want the captcha code and text field to appear.
The captcha code consists of 5 digits which have been specially obscured to make it harder for screen readers and spiders to detect. If a form is set up to use a captcha field but the code isn't submitted, or is incorrect, the visitor will see an error message and the form wont be submitted.
Reference
Rules
- alnum
Parameters: none
Field must be alphanumeric, e.g. it only contain letters and digits. - alpha
Parameters: none
Field may only contain letters. - checked
Parameters: [n] or [n,n]
Tests to ensure a certain number of checkboxes are selected for this field. e.g.
checked[10] - Exactly 10 items must be selected
checked[3,5] - Between 3 and 5 items must be selected. - date
Parameters: [start_date, end_date] or [past] or [future]
Validate a date field. Can take a start and end date or the keywords 'past' or 'future'. Internally start_date and end_date are parsed by PHP's strtotime() function, therefore any applicable value for that function can be used. e.g.
date[31/12/2006,1/1/2009] - Date must be between 31st Dec 2006 and 1st Jan 2009
date[now,+8 hours] - Date must be between now and 8 hours in the future.
date[past] - Date must be in the past
date[future] - Date must be in the future - digit
Parameters: none
Field may only contain digits (0-9) - email
Parameters: none
Field must be a valid email address. - length
Parameters: [n] or [n,n] or [n,*]
Ensures a text field is a certain length. If only a single parameter is passed then the text must match that exact length. If two parameters are passed they are treated as upper and lower limits for the length of the text. If the second parameter is a * character there will be no upper limit. e.g.
length[10] - Value must be exactly 10 characters long
length[0,40] - Value must be between 0 and 40 characters
length[5,*] - Value must be at least 5 characters, no upper limit - numeric
Parameters: none
Field must be a valid numeric value. 6, 78.34, -100 are all examples of numeric values. - query
Parameters: [sql_query]
Takes a SELECT SQL query, runs it and passes validation if one or more rows are returned. - range
Parameters: [n,n]
Used for fields holding numeric data. Checks if a number is within a certain range. e.g range[1,31] would ensure that the number in a field would be between 1 and 31 - regex
Parameters: [regular_expression]
Passes validation if one or more regular expression matches are made on the field's data. regular_expression must be a valid PCRE regular expression. e.g.
regex[/^[a-z0-9_-]{3,16}$/] - slug
Parameters: none
Field must be a valid URL slug. e.g it can only contain lowercase alphanumeric characters and the dash - symbol. - url
Parameters: none
Field must be a valid URL. - ! modifier
Parameters: n/a
The ! modifier isn't technically a rule in itself. By prefixing any other rules with ! you can invert the expected output, passing a field when it would normally fail (and vice versa). e.g !range[4,55] would only pass validation if the value of the field was below 4 and above 55.
Filters
- capitalize
Parameters: none
The first character will be uppercase, all others lowercase. - date
Parameters: [date_format]
Formats a date using PHP's date function. - join
Parameters: [join_text]
Joins elements of an array together, separated by join_text. - lower
Parameters: none
Converts all the characters in a text field to their lowercase equivalent. - striptags
Parameters: none
Removes all HTML tags from a text field. - sum
Parameters: none
Sums the elements of an array. - title
Parameters: none
Words will start with uppercase letters, all remaining characters are lowercase. - trim
Parameters: none
Removes whitespace from the beginning and end of a text field. - upper
Parameters: none
Converts all the characters in a text field to their uppercase equivalent. - url
Parameters: none
Formats a lazy URL such as google.com or www.omcore.net into a proper URL including http:// e.g. www.bbc.co.uk => http://www.bbc.co.uk
Methods
- antispam()
Parameters: None
Prevent spam without using a captcha or requiring the user to fill out any additional fields. Outputs some hidden HTML fields which get automatically filled out by spam bots. If these hidden fields are submitted with data then its likely to be a spam bot and the form fails validation. Also implements a timeout rule which stops forms being filled out and submitted in less than 3 seconds (most automated bots will fill a form and submit it in under a second). Embed within the <form> tag, at the top or just before the submit button. - clear()
Parameters: None
Removes all rules and filters on the current field context. Useful for overriding default validation rules. - data()
Parameters: None
Returns an array of the data submitted to the validation class. - error_html()
Parameters: None
Provides a simple way of displaying validation error messages to visitors. - errors()
Parameters: None
Returns the validation errors array. - field()
Parameters: string field_name [, string field_title ]
Sets the current field context which other rules and filters operate on. The system will try to generate a human readable title for the field based on it's field_name. e.g first_name becomes First name. If you want to override this and provide your own title this can be done by passing a second parameter to field() e.g.
{{ fv.field('last_name', 'Customers first name').mandatory() }} - filter()
Parameters: string filter_name [, bool apply_after_validation ]
Adds a filter to the current field context. If the second parameter is set to true then the filter is applied *after* validation has taken place (by default it is applied before validation). e.g.
{{ fv.field('product_code').filter('upper') }} - has_errors()
Parameters: None
Returns true if the form has any validation errors, otherwise returns false. - mandatory()
Parameters: [string error_message]
Sets a field as mandatory. By passing in a string as the first parameter the error message can be customised. e.g.
{{ fv.field('last_name', 'Customers first name').mandatory() }} - optional()
Parameters: None
Sets a field as optional. - rule()
Parameters: string rule_name [, string error_message ]
Adds a rule to the current field context. By default the system will automatically generate the error message based on the rule_name. To override this, provide a second parameter with the error message you require. e.g.
{{ fv.field('post_code').rule('length[0, 8]', 'Please enter your postcode') }} - title()
Parameters: string rule_name
Sets the human readable title of a field if you want to override the auto generated value. e.g.
{{ fv.field('post_code').title('Postcode') }} - require_captcha()
Parameters: [string error_message]
If this is called then a form must submit a captcha code otherwise it will never pass validation. See the captcha() method. By passing in an optional string as the first parameter the error message for forms submitted without a valid captcha code can be customised.