ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

[SOLVED] Conditional Form Validation

October 20, 2011 2:47pm

Subscribe [4]
  • #1 / Oct 20, 2011 2:47pm

    Silviu

    77 posts

    Hello,

    I have (pretty large) form in which several sections depend on other settings to validate.

    For example I have a select box that determines the type of the information required: for a car or for a house. A car has ‘color’ and ‘horsepower’ and a house has ‘surface’ and ‘levels’ (you get the point).

    Now, there are other fields in the form that must be validated regardless - like ‘name’ and ‘email’.

    I was planning to define several sets of rules in config/form_validation.php:
    - one for the fields that must always be validated
    - one for each ‘subsection’ that must be conditionally validated - ‘car’, ‘house’, etc.

    The idea was to do secvential validation in a separate method that would return true or false:

    ...
    function main_form(){
     ...
     if($this->do_validation()){
      //code for success here
     }else{
      //code for failure here
     }
     ..
    }
    
    function do_validation(){
     if(!this->form_validation->run('general_rules') return FALSE;
    
     if($select == 'car')
      if(!this->form_validation->run('car_rules') return FALSE;
    
     if($select == 'house')
      if(!this->form_validation->run('house_rules') return FALSE;
     
     ...
    
     return TRUE;
    }
    
    ...

    Question: is is possible to run several validation rules in sequence?

     

  • #2 / Oct 20, 2011 3:25pm

    Kamarg

    241 posts

    Not really. However, you can have several sections where you call $this->form_validation->set_rules based on the value of posted variables. Alternately, you could do something like the below to run multiple sets of rules. However, it will clear out the error messages on each time you call it so there’s not an easy way to report all errors if an error exists in multiple sections.

    class MY_Form_validation extends CI_Form_validation {
     function clear_rules() {
      $this->_field_data  = array();
      $this->_error_array = array();
      $this->_error_messages = array();
     }
    }

     

  • #3 / Oct 21, 2011 2:48am

    Silviu

    77 posts

    Well, one of the solutions I stumbled upon is to add in the verification method rules according to the options selected. Something like:

    ...
    function main_form(){
     ...
     if($this->do_validation()){
      //code for success here
     }else{
      //code for failure here
     }
     ..
    }
    
    function do_validation(){
    //general rules
     $this->form_validation->set_rules('name rules');
     $this->form_validation->set_rules('email rules');
     ...
     //now for the contitional part
     if($this->input->post('type') == 'car'){
     $this->form_validation->set_rules('color rules');
     $this->form_validation->set_rules('horsepower rules');
     }elseif($this->input->post('type') == 'house'){
     $this->form_validation->set_rules('surface rules');
     $this->form_validation->set_rules('levels rules');
     } //and the list goes on
     
     return $this->form_validation_run();
    }
    
    ...

    This means that you cannot “store” validation rules in their proper place - form_validation.php, but if this is the only solution I’ll take it.

  • #4 / Oct 21, 2011 5:06am

    Silviu

    77 posts

    *UPDATE* (sorry for the double post but I wanted to point out one solution that worked for me and I think it would work for everyone).

    This is what it sparked my interes:

    class MY_Form_validation extends CI_Form_validation {
     function clear_rules() {
      $this->_field_data  = array();
      $this->_error_array = array();
      $this->_error_messages = array();
     }
    }

    Extending the form validation library to allow one to load multiple rule groups if needed.

    So I ended up with this:

    <?php
    
    /**
     * Form Validation Class extension for conditional form validation
     * Allows loading multiple rule groups before processing
     *
     * @package  CodeIgniter
     * @subpackage Libraries
     * @category Validation
     * @author  Silviu Ghita
     * @link  <a href="http://ellislab.com/forums/viewthread/202523/">http://ellislab.com/forums/viewthread/202523/</a>
     */
    
    class MY_Form_validation extends CI_Form_validation {
     /**
      * Method to add rule groups from form_validation.php
      * to the validation rules, intended to be used for
      * conditional form validation
      *
      * @param mixed $groups Group(s) to be added. Can be a single group name or an array
      */
     function add_group($groups = FALSE)
     {
    
      // Give nothing, receive nothing
      if($groups === FALSE)
      {
       return; // do nothing
      }
    
      // No reason to set rules if we have no POST data
      if (count($_POST) == 0)
      {
       return; // do nothing
      }
    
      // No validation rules?  We're done…
      if (count($this->_config_rules) == 0)
      {
       return; // do nothing
      }
    
      // If we have not received an array (the user entered just one group),
      // we'll turn it into one for easier processing
      if(!is_array($groups))
       $groups = array($groups);
    
      // Now we need to load all the rule groups requested
      foreach ($groups as $group)
      {
       if ($group != '' AND isset($this->_config_rules[$group])) // Do we have a group that matches this name?
       {
        $this->set_rules($this->_config_rules[$group]);
       }
      }
     }
    }
    
    /* End of file MY_Form_validation.php */
    /* Location: ./application/libraries/MY_Form_validation.php */

    To use it, place the file in the proper location (/application/libraries/MY_Form_validation.php) and in your controller do something like this:

    /**
      * Validate announcement submission
      * @return bool Returns TRUE or FLASE depending on the result
      */
     private function validateAnnouncement(){
    
      //basic validation
      $this->form_validation->add_group('announcement-basic');
    
      //for companies
      if($this->input->post('type')=='company')
       $this->form_validation->add_group('announcement-companies');
    
      //for various categories
      if($this->input->post('category')=='1') //real estate
       $this->form_validation->add_group('announcement-realestate');
      if($this->input->post('category')=='2') //auto
       $this->form_validation->add_group('announcement-auto');
      if($this->input->post('category')=='3') //pets
       $this->form_validation->add_group('announcement-pets');
      if($this->input->post('category')=='4') //electronics
       $this->form_validation->add_group('announcement-electronics');
      if($this->input->post('category')=='5') //clothes
       $this->form_validation->add_group('announcement-clothes');
      if($this->input->post('category')=='6') //pleasure
       $this->form_validation->add_group('announcement-pleasure');
      if($this->input->post('category')=='8') //events
       $this->form_validation->add_group('announcement-events');
    
      //run validation
      return $this->form_validation->run();
     }

    You can also add your groups into an array and pass that to the add_group method only once:

    /**
      * Validate announcement submission
      * @return bool Returns TRUE or FLASE depending on the result
      */
     private function validateAnnouncement(){
      //basic validation
      $rules = array('announcement-basic');
      //for companies
      if($this->input->post('type')=='company')
       $rules[] = 'announcement-companies';
    
      //for various categories
      if($this->input->post('category')=='1') //real estate
       $rules[] = 'announcement-realestate';
      if($this->input->post('category')=='2') //auto
       $rules[] = 'announcement-auto';
      if($this->input->post('category')=='3') //pets
       $rules[] = 'announcement-pets';
      if($this->input->post('category')=='4') //electronics
       $rules[] = 'announcement-electronics';
      if($this->input->post('category')=='5') //clothes
       $rules[] = 'announcement-clothes';
      if($this->input->post('category')=='6') //pleasure
       $rules[] = 'announcement-pleasure';
      if($this->input->post('category')=='8') //events
       $rules[] = 'announcement-events';
      
      //set rules
      $this->form_validation->add_group($rules);
      //run validation
      return $this->form_validation->run();
     }

    So there it is. Use it if you need it.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases