Welcome Guest, Not a member yet? Register   Sign In
Form Validation with Arrays
#1

[eluser]jamgood96[/eluser]
Let's say I've got a form for entering in a person's contact information. In this form, there are separate input boxes for the address, the city, the state, and the zip. I'd currently got it setup as follow...

street is address[street]
city is address[city]
state is address[state]
zipcode is address[zipcode]

Unfortunately, this doesn't seem to be working as expected. I want to be able to use

Code:
$this->form_validation->set_rules('address', 'Address', 'callback_validate_address');

To pass the value(s) to a custom callback function. The values seem to be getting passed to the function, but when it comes time to repopulate the form with set_values, it doesn't work to do set_value('address[street]') or set_value('address[city]').

Am I doing this completely wrong, or is this a limitation in CI or the Form_validation class?

Thanks in advance!

James
#2

[eluser]CroNiX[/eluser]
Well, its not repopulating the form because you aren't using the correct field names in your validation rules. There is no "address" field, so it can't repopulate it if the address rule fails. Only fields that have a validation rule defined will repopulate. You would be better off creating a separate validation rule for each one of those. Or, if you insisted on a single rule, you could use the optional 2nd parameter for validation rules to pass what type of field it is in the brackets.
Code:
$this->form_validation->set_rules('street', 'Street', 'callback_validate_address[street]');  

//whatever is in the brackets in the above rule will be passed as 2nd value to your callback
function validate_address($form_value, $field_type)
{
  switch($type)
  {
    case 'street':
        //val for street types
        break;
    case 'city':
        //val for city types
        break;
  }
}

Personally, I would stick with a different validation rule per field, as the rules for validating that field will be different and then you can reuse the rules for other fields.
#3

[eluser]jamgood96[/eluser]
There is an address field, it's just that it's an array. If I use

Code:
$this->form_validation->set_rules('address', 'Street', 'callback_validate_address');

the callback function receives the array, however calls the function four separate times (since address contains four values).
#4

[eluser]CroNiX[/eluser]
I don't think you can do it that way. The first parameter of form_validation:Confusedet_rules() needs to be the EXACT name of the field or it won't know where to repopulate. So, it would have to be address[street] in order to repopulate the street field, which would mean you would need 4 separate rule declarations instead of just one for 'address'. It is possible to use arrays, I use them all of the time for checkboxes. But I name the field "fieldname[]" (which means in the rules you use "fieldname[]"), not "fieldname[something]".

Personally I'd just change the field names to be unique and each have their own validation rule.


#5

[eluser]jamgood96[/eluser]
So if I go that route, how would I construct the validation callback to lookup an verify/lookup an entire address at Yahoo or Google?

I was hoping I could just pass an entire array through the validation callback and then use the data in the array to lookup and verify.

Does that make sense?
#6

[eluser]CroNiX[/eluser]
I'd have a rule for street, city, state and zip. Those would check the data types and formatting, etc. Id have an additional rule that checked the address with google.

$this->form_validation->set_rules('street', 'Street', 'callback_validate_street');
$this->form_validation->set_rules('city', 'City', 'callback_validate_city');
$this->form_validation->set_rules('state', 'State', 'callback_validate_state');
$this->form_validation->set_rules('zip', 'Zip', 'callback_validate_zip|callback_validate_address');

Then in validate_address, assemble the address from $this->input->post('street'), 'city', 'state' and zip, send it to google/yahoo for verification, and pass/fail based on outcome. This rule would only get triggered once and it will only get triggered if the other rules above fail. The only problem with this is that if the whole address fails at google, that it will report the error in the zip field and not all 4.
#7

[eluser]jamgood96[/eluser]
Ive decided to try a different route. since im using JavaScript throughout the site, I just created a hidden form field that is populated with the four address fields before submission.
#8

[eluser]TheFuzzy0ne[/eluser]
That will cause problems if someone doesn't have Javascript enabled. I would suggest going with the hidden form field (Address), and leaving it empty. You can validate the address as a whole after validating the parts (much like CroNiX's example above). If all of the parts pass validation, then you can verify it with Google. If it fails, you can use <?php echo form_error('address'); ?> to display the error message. You just need to make sure that the rules for 'address' are set after the sub-parts of the address, then you should be able to check to see if any of the sub-parts contain errors easily.
Code:
$this->form_validation->set_rules('street', 'Street', 'callback_validate_street');
$this->form_validation->set_rules('city', 'City', 'callback_validate_city');
$this->form_validation->set_rules('state', 'State', 'callback_validate_state');
$this->form_validation->set_rules('zip', 'Zip', 'callback_validate_zip|callback_validate_address');
$this->form_validation->set_rules('address', '', 'callback_validate_address');

Code:
function validate_address($str)
{
    foreach (array('street', 'city', 'state', 'zip') as $item)
    {
        if (form_error($item))
        {
            return TRUE; // There are other errors so just return TRUE.
        }
    }

    $input =& $this->input;
    if ( ! is_valid_address($input->post('street'), $input->post('city'), $input->post('state'), $input->post('zip'))
    {
        $this->form_validation->set_message('validate_address', 'This is not a valid address.');
        return FALSE;
    }

    return TRUE;
}

I don't know how your Google API works, but for this example let's imagine is_valid_address() calls the API to validate it.

I've not tested the example, but hopefully you can see the concept.




Theme © iAndrew 2016 - Forum software by © MyBB