Custom Validation Errors per Field

Derek Jones edited this page Jul 5, 2012 · 6 revisions
Clone this wiki locally

This extension to the core Validation class provides a method for setting custom error messages per field. CodeIgniter's default behaviour is to set errors based on the validation rule that failed to be satisfied. These can be customized, but not per field.

Note that errors configured with this new method will be displayed regardless of what rule was unsatisfied, so it is good practice to make your custom errors very clear as to what is required.

Here's the code which you can save in application/libraries/MY_Validation.php, or, if you're already extending Validation, add this method to your extension.

<?php

class MY_Validation extends CI_Validation {

   function MY_Validation()
   {
      parent::CI_Validation();
   }
   
   function set_errors($fields)
   {
      if (is_array($fields) and count($fields))
      {
         foreach($fields as $key => $val)
         {
            $error = $key.'_error';
            if (isset($this->$error) and isset($this->$key) and $this->$error != '')
            {
               $old_error = $this->$error;
               $new_error = $this->_error_prefix.sprintf($val, $this->$key).$this->_error_suffix;
               $this->error_string = str_replace($old_error, $new_error, $this->error_string);
               $this->$error = $new_error;
            }
         }
      }     
   }
   
}

[size=4]How to use set_errors()[/size]

This extension creates a $this->validation->set_errors() method. Because the run() method generates the error string based on your rules, this method MUST be called AFTER $this->validation->run() and BEFORE your store or print $this->validation->error_string.

Consider this in a controller:


[...]
      // Run Validation
      if (!$this->validation->run())
      {
         // Set custom errors
         $this->validation->set_errors(array('name' => 'Common now!'));
         
         if (!empty($this->validation->error_string))
         // Validation ran and there was an error
         {
            $form['error'] = $this->validation->error_string;
[...]

Just like the set_fields and set_rules methods, set_errors accepts an array where the keys correspond to your input field names, and values are the errors you want to display. (Tip: Always use the language library to allow your custom errors be translated. My example above omits this behavior for sake of brevity.)

Also note that your supplied messages get sprintf'd, so you can include the submitted value in your error!

$this->validation->set_errors(array('email' => "'%s' is not a valid email address."));

// "'colin@website' is not a valid email address."

Remember to use %1$s if the field value appears more than once in your message.

--- Notes: ---------------------------------------------------------------------

The set_errors() method honors your configured error prefix and suffix set with $this->validation->set_error_delimiters().

I admit, it's a bit awkward using str_replace() on the error_message property, where Validation stores errors, but I'd never want to override the run() method, which generates errors based on rules and not fields.