Welcome Guest, Not a member yet? Register   Sign In
Form validation with 2 rule sets
#1

[eluser]Unknown[/eluser]
Anyone know of a way to use form validation with two different rule sets on one form? I know with one you simply do run('ruleName') but I can't seem to figure out how to do it with two rule sets. I tried:
Code:
if ($this->form_validation->run('accidentForm') == FALSE || $this->form_validation->run('locationForm') == FALSE)
but the second run never gets called, even if the first one is equal to true.

Any help would be appreciated.
Thanks.
#2

[eluser]TheFuzzy0ne[/eluser]
As far as I know, it can't be done without a little hocus pocus. Just out of interest, why would you need to run two different sets of rules?
#3

[eluser]Unknown[/eluser]
Some of my forms will have sub-forms within. So rather than have the same rules in multiple locations, I'd rather be able to call more than one set of rules at a time. I came up with a basic solution that will work for now. I put a "rules" folder inside my "controllers" folder. Inside the rules folder I have multiple rule sets, such as rules1.php:
Code:
$this->form_validation->set_rules('gi_time', '');
$this->form_validation->set_rules('gi_officer', '');
$this->form_validation->set_rules('gi_agency', '');

and rules2.php:
Code:
$this->form_validation->set_rules('city', 'City');
$this->form_validation->set_rules('state', 'State');
$this->form_validation->set_rules('zip', 'Zip');

Then in my controller i just include the rules before I call run() to validate:
Code:
include('rules~/rules1.php');
include('rules~/rules2.php');

if ($this->form_validation->run() == FALSE)
{
    $data['loadSite'] = 'records/handlers/add_accident';    
    $this->loadMainView('accident/add',$data);
}
else
{
    //$this->load->view('formsuccess');
    $this->loadMainView('accident/add');
}
#4

[eluser]Chad Fulton[/eluser]
Hello!

The problem here lies in the way that the Form_validation class works. It only checks for group rules if there are no defined rules when the run() function is called.

So, the first time you're calling $this->form_validation->run('accidentForm'), the function sees that there are no defined rules, and the sets rules based on the rules group accidentForm.

Then, the second time you call $this->form_validation->run('locationForm'), the function sees that there are defined rules, and so validates using the already-defined rules (which happen to be the accidentForm rules).

There are a couple of ways I've found to deal with this problem, and you may like one better than another depending on how you want the validation to work. They all involve extending the Form_validation library.

The way I've settled on is to extend the Form_validation class by adding an additional function set_group_rules(). This function allows me to explicitly add groups of rules.

So, you could do:

Code:
// This will validate both sets of rules at the same time
$this->form_validation->set_group_rules('accidentForm');
$this->form_validation->set_group_rules('locationForm');
if($this->form_validation->run() == FALSE) {
...
}

Or, you could do this:
Code:
// This will validate the 'accidentForm' first
$this->form_validation->set_group_rules('accidentForm');
if($this->form_validation->run() == FALSE) {
...
}
// Now we add the 'locationForm' group of rules
$this->form_validation->set_group_rules('locationForm');
// And now we validate *both* sets of rules (remember that the accidentForm rules are still
// there), but it doesn't necessarily matter, since it will simply redo the 'accidentForm'
// validation while also doing the 'locationForm' validation
if($this->form_validation->run() == FALSE) {
...
}

Below is the code for the extended Form_validation class, saved in the application libraries folder as MY_Form_validation.php

Code:
class MY_Form_validation extends CI_Form_validation {

    /**
     * Set Rules from a Group
     *
     * The default CodeIgniter Form validation class doesn't allow you to
     * explicitely add rules based upon those stored in the config file. This
     * function allows you to do just that.
     *
     * @param string $group
     */
    public function set_group_rules($group = '') {
        // Is there a validation rule for the particular URI being accessed?
        $uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;

        if ($uri != '' AND isset($this->_config_rules[$uri])) {
            $this->set_rules($this->_config_rules[$uri]);
            return true;
        }
        return false;
    }

}
#5

[eluser]Unknown[/eluser]
Chad, I just signed up to thanks to you.

This was an elegant solution to the problem that I also have (had).

Thank you for your contribution here.
#6

[eluser]Chad Fulton[/eluser]
Thanks! I'm glad it helped someone out.




Theme © iAndrew 2016 - Forum software by © MyBB