Welcome Guest, Not a member yet? Register   Sign In
Forms: Validating Multiple Inputs (As Array)
#1

[eluser]CISCK[/eluser]
I'm having some trouble validating a set of inputs, which make an array. (I have read the docs and searched the forms). Here's a simplified what I have:

Code:
<form action="<? site_url('welcome') ?>" method="post">
    <?= form_error('phone[]'); ?>
    <input name="phone[]" type="text" value="<?= set_value('phone[]'); ?>" maxlength="3">
    <input name="phone[]" type="text" value="<?= set_value('phone[]'); ?>" maxlength="3">
    <input name="phone[]" type="text" value="<?= set_value('phone[]'); ?>" maxlength="4">
    <input type="submit" value="Submit">
</form>

This works fine and submits an array that looks like the following (in the profiler):

Code:
$_POST['phone'] ... Array(
     [0] => 555
     [1] => 555
     [2] => 5555
)

Initially, I thought I could simply validate like so:

Code:
array(
     'field' => 'phone[]',
     'rules' => 'required|numeric|exact_length[10]'
);

Unless I'm mistaken, this is not the case when validating arrays. So, I changed the rules key for "phone[]" to a custom rule–"valid_phone":

Code:
// ./system/application/libraries/MY_Form_Validation.php
function valid_phone($arr = array())
{
    ...
}

Here is the problem.

For whatever reason, the $arr variable seems to be giving me an empty array, even if the fields are populated.

Help. Please?
#2

[eluser]toopay[/eluser]
Create a callback function, right in related controller, and validate the array inside that function. Callbacks: Your own Validation Functions
#3

[eluser]CISCK[/eluser]
It turns out that the valid_phone (callback) function actually runs 3 times, each with a different value from the array. So, the function is actually being passed a string. Check out the example code:

Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Welcome extends CI_Controller {
    
    public function index()
    {
        // load profiler and form_validation
        $this->output->enable_profiler(TRUE);
        $this->load->library('form_validation');        
        
        // create and set rules
        $this->form_validation->set_rules('phone[]', '', 'callback_valid_phone');
        
        // show the view
        $form_is_valid = $this->form_validation->run();
        $this->load->view(($form_is_valid) ? 'form_sent_view' : 'form_view');
    }
    
    public function valid_phone($str = '')
    {
        echo (is_array($str)) ? 'Array ' : 'Not an array ';
        return FALSE;
    }
}

/* End of file welcome.php */
/* Location: ./application/controllers/welcome.php */

This will output the following in the view: "Not an array Not an array Not an array." So, the function is run once for each item in the array and receives a string for the argument.

This is NOT ideal since I want to explode and validate the entire array in a single function. Any thoughts?

Also, I want to point out that using "MY_Form_Validation.php" will accomplish the same thing as using a callback in your controller.
#4

[eluser]toopay[/eluser]
[quote author="CISCK" date="1308894440"]Also, I want to point out that using "MY_Form_Validation.php" will accomplish the same thing as using a callback in your controller.[/quote]

Off course, but there is no neccesary to extend the form validation, for something which already provided, right?

Related with your problem, try this...
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Welcome extends CI_Controller {
    
    function __construct()
    {
       parent::__construct();
       $this->load->library('form_validation');
    }

    public function index()
    {
        // load profiler and form_validation
        $this->output->enable_profiler(TRUE);
                
        // create and set rules
        // $this->form_validation->set_rules('phone[]', '', 'callback_valid_phone');
        // Instead checking the 'phone[]', try inspect the 'phone'
        $this->form_validation->set_rules('phone', 'Phones', 'callback_valid_phone');
        
        /* lets disable this for a while
        // show the view
        $form_is_valid = $this->form_validation->run();
        $this->load->view(($form_is_valid) ? 'form_sent_view' : 'form_view');
        */
        if ($this->form_validation->run() == FALSE)
        {
           echo 'Failed';
           echo validation_errors();
           $this->load->helper('form');
           echo form_open('welcome/index');
           $data = array(
              'name'        => 'phone[]',
              'size'        => '50',
            );

            echo form_input($data);
            echo form_input($data);
            echo form_input($data);
            echo form_submit('submit', 'submit');
            echo form_close();
        }
        else
        {
           echo 'Success';
           var_dump($_POST);
        }
        
        
    }
    
    public function valid_phone($arr)
    {
        $error = 0;
        foreach($arr as $part => $val)
        {
           if (empty($val))
           {
              $this->form_validation->set_message('valid_phone', 'The %s field is required.');
              $error++;
           }
        }
        return $error > 0 ? FALSE : TRUE;
    }
}
#5

[eluser]CISCK[/eluser]
Thanks, toopay! This is helpful and has solved my problem... kinda.

The valid_phone callback still runs 3 times--once for each array key. I know this does not change the accuracy of the validation, but I still wonder if there's a better way. I have lots of phone numbers, licenses, socials, etc. broken up into multiple fields, and pretty soon, the callbacks are called 20-30+ extra times. That's no good.

Anyway, thanks again for your help, as passing 'phone' instead of 'phone[]' has allowed me to use this callback successfully:

Code:
public function valid_phone($arr = array())
{
    // turn the array into a string (e.g. 5555555555)
    $phone = trim(join('', $arr));    

    // is the phone string 10 digits long and numeric?
    $is_valid = (strlen($phone) == 10 AND is_numeric($phone)) ? TRUE : FALSE;
    $this->form_validation->set_message('valid_phone', 'Please enter a valid phone number.');

    return $is_valid;
}




Theme © iAndrew 2016 - Forum software by © MyBB