CodeIgniter: validating form array not working

codeigniter, codeigniter-2

Solution

Ok - I've just spent an hour on this - and I've worked out the problem + solution

The issue is that when the variable you are testing is part of an array, CI interprets the field as being set, and thus "contains" a value (even when it is empty). Because that "value" is NOT a number greater than 0 - it fails.

Therefore you'll need to unset the $_POST (NOT $user_group_profiles) variable when it is "empty" so that it passes validation. Note - validation is run on $_POST - that is why you are unsetting $_POST and not $user_group_profiles

So the workaround is this:

$user_group_profiles = $this->input->post('user_group_profiles', TRUE);
foreach ($user_group_profiles as $key => $user_group_profile)
{
     // Set the rules
     $this->form_validation->set_rules($key."[profile_name]", "Profile Name", "trim|required");
     $this->form_validation->set_rules($key."[birthdate]", "Birthdate", "trim|required");
     $this->form_validation->set_rules($key."[height]", "Height", "trim|greater_than[0]");
     $this->form_validation->set_rules($key."[weight]", "Weight", "trim|greater_than[0]");

     // Now check if the field is actually empty
     if (empty($user_group_profile['height']))
     {
         // If empty, remove from array so CI validation doesnt get tricked and fail
         unset($_POST[$key]['height']);
     }
     if (empty($user_group_profile['weight']))
     {
         unset($_POST[$key]['weight']);
     }
}

I've tested this - and it fixes your problem.

You could also program it this way if you dont want to touch the $_POST data:

foreach ($user_group_profiles as $key => $user_group_profile)
    {
         // Set the rules
         $this->form_validation->set_rules($key."[profile_name]", "Profile Name", "trim|required");
         $this->form_validation->set_rules($key."[birthdate]", "Birthdate", "trim|required");


         // Now check if the field is actually empty
         if ( ! empty($user_group_profile['height']))
         {
             $this->form_validation->set_rules($key."[height]", "Height", "trim|greater_than[0]");
         }
         if ( ! empty($user_group_profile['weight']))
         {
             $this->form_validation->set_rules($key."[weight]", "Weight", "trim|greater_than[0]");
         }
    }

Problem

I have an array of profile data I need to validate: ``` $user_group_profiles = $this->input->post('user_group_profiles', TRUE); foreach ($user_group_profiles as $key => $user_group_profile) { $this->form_validation->set_rules("user_group_profiles[$key][profile_name]", 'Profile Name', 'trim|required'); $this->form_validation->set_rules("user_group_profiles[$key][birthdate]", 'Birthdate', 'trim|required'); // TODO: heigth/weight not required, but the validation somehow makes it required $this->form_validation->set_rules("user_group_profiles[$key][height]", 'Height', 'trim|greater_than[0]'); $this->form_validation->set_rules("user_group_profiles[$key][weight]", 'Weight', 'trim|greater_than[0]'); } ``` Height and weight are option, but when no value is set for those fields, CI validation complains. A `var_dump($user_group_profiles);` shows this: ``` array 'ugp_b33333338' => array 'profile_name' => string '' (length=0) 'birthdate' => string '' (length=0) 'height' => string '' (length=0) 'weight' => string '' (length=0) ``` Any ideas what might be wrong? EDIT 1: I went into CI's Form_validation library and made `$_field_data` and public member. When I var_export it after, I got this: ``` 'user_group_profiles[ugp_833333338][height]' => array 'field' => string 'user_group_profiles[ugp_833333338][height]' (length=42) 'label' => string 'Height' (length=6) 'rules' => string 'greater_than[1]' (length=15) 'is_array' => boolean true 'keys' => array 0 => string 'user_group_profiles' (length=19) 1 => string 'ugp_833333338' (length=13) 2 => string 'height' (length=6) 'postdata' => string '' (length=0) 'error' => string 'The Height field must contain a number greater than 1.' (length=54) ```

Original source