Welcome Guest, Not a member yet? Register   Sign In
Easier SetFields method? (proposed change?)
#1

[eluser]litzinger[/eluser]
Although the Validation class and all that saves me a ton of time with forms, I still find it kind of tedious to work with, mainly having to declare $rules[] and $fields[] for every form field I want to validate. So while working on a form a few minutes ago, it stuck me that I was being very repetitive.

Instead of setting $fields['my_field'] = 'My Field'; why can't I just take that key value 'my_field' from the $rules array that I already declared, and strip the underscore and capitalize the first character of the words?

Here is what my validation looks like now...

Code:
$rules['name'] = 'required';  
$rules['ssn'] = 'required';
$rules['address'] = 'required';
$rules['city'] = 'required';
$rules['state'] = 'required';
$rules['zip'] = 'required|min_length[5]';
$rules['email'] = 'required|valid_email';
$rules['home_phone'] = 'required|min_length[7]';  
$rules['work_phone'] = 'min_length[7]';
$rules['fax'] = 'min_length[7]';
$rules['emergency_name'] = 'required';
$rules['emergency_phone'] = 'required';
$rules['emergency_relationship'] = 'required';  

$rules['occupation'] = 'required';
$rules['employer'] = 'required';  
$rules['employer_address'] = 'required';  
$rules['supervisor_name'] = 'required';  
$rules['supervisor_phone'] = 'required';  
$rules['education'] = 'required';  
$rules['major_degree'] = 'required';  

$Validation->SetRules($rules);

$fields['ssn'] = 'Social Security Number';

$Validation->SetFields($fields);

And the SetFields method change:

Code:
function SetFields($data = '', $field = '', $separator = '_')
    {    
        if ($data == '')
        {
            if (count($this->_fields) == 0 && count($this->_rules) == 0)
            {
                return FALSE;
            }
        }
        else
        {
            if ( ! is_array($data))
            {
                $data = array($data => $field);
            }
            
            if (count($data) > 0)
            {
                $this->_fields = $data;
            }
        }    
        
        foreach($this->_rules as $key => $val)
        {                  
            $text = ucwords(str_replace($separator, ' ', $key));            
            $auto_fields[$key] = $text;    
        }  
        
        $this->_fields = array_merge($auto_fields, $this->_fields);    
            
        foreach($this->_fields as $key => $val)
        {        
            $this->$key = ( ! isset($_POST[$key]) OR is_array($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);
            
            $error = $key.'_error';
            if ( ! isset($this->$error))
            {
                $this->$error = '';
            }
        }        
    }

I'm just searching the _rules for the text, reformatting it, and if I still want to pass specific error text to that field I still can, and just merge the arrays to produce the final array.

Outputs:

Code:
1. The Name field is required.
   2. The Social Security Number field is required.
   3. The Address field is required.
   4. The City field is required.
   5. The State field is required.
   6. The Zip field is required.
   7. The Email field is required.
   8. The Home Phone field is required.
   9. The Emergency Name field is required.
  10. The Emergency Phone field is required.
  11. The Emergency Relationship field is required.
  12. The Occupation field is required.
  13. The Employer field is required.
  14. The Employer Address field is required.
  15. The Supervisor Name field is required.
  16. The Supervisor Phone field is required.
  17. The Education field is required.
  18. The Major Degree field is required.

Opinions?
#2

[eluser]Michael Wales[/eluser]
Sounds like a great addition myself... I too, often find these steps repetitive and make a lot of my controllers larger than they need to be. I've started dumping all of my validation stuff into private methods within the controller - but that only cleans up the appearance of the public methods - it doesn't eliminate the repetitiveness.

I intend to add this to MY_validation as soon as I get home - thanks!
#3

[eluser]sikkle[/eluser]
Walesnd :

do you mind to copy paste some code here, like what you put in your public function and what you put in your private one ?

thanks.
#4

[eluser]Michael Wales[/eluser]
/application/libraries/MY_Validation.php
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed.');

class MY_Validation extends CI_Validation {

function MY_Validation() {
  parent::CI_Validation();
}

function SetFields($data = '', $field = '', $separator = '_')
    {    
        if ($data == '')
        {
            if (count($this->_fields) == 0 && count($this->_rules) == 0)
            {
                return FALSE;
            }
        }
        else
        {
            if ( ! is_array($data))
            {
                $data = array($data => $field);
            }
            
            if (count($data) > 0)
            {
                $this->_fields = $data;
            }
        }    
        
        foreach($this->_rules as $key => $val)
        {                  
            $text = ucwords(str_replace($separator, ' ', $key));            
            $auto_fields[$key] = $text;    
        }  
        
        $this->_fields = array_merge($auto_fields, $this->_fields);    
            
        foreach($this->_fields as $key => $val)
        {        
            $this->$key = ( ! isset($_POST[$key]) OR is_array($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);
            
            $error = $key.'_error';
            if ( ! isset($this->$error))
            {
                $this->$error = '';
            }
        }        
    }
}


Work like a charm - a great addition tilzinger - it's saving me a lot of typing.
#5

[eluser]litzinger[/eluser]
Thanks. I'm glad I thought of it. I'm working on a large application form and groaned at knowing I had to retype all those fields. I knew there had to be a better way Smile

Hopefully others will find it useful too.
#6

[eluser]tonanbarbarian[/eluser]
why not simply do something like the following

Code:
/**
* Method to set rules and build the fields from the rule keys
* Must accept an array of rules
*
* @param array $rules Array of Validation Rules
*/
function SetRules($rules=array()) {
  // set the rules
  $this->set_rules($rules);

  // load the inflector so we can convert the field names
  $this->CI->load->helper('inflector');

  // process the field names
  $fields = array();
  foreach (array_keys($rules) as $field)
    $fields[$field] = humanize($field);

  // set the fields
  $this->set_fields($fields);
  
} // setRules()

Since you are only really going to use the method with an array of rules in most cases then the method only takes an array
And there is no real need to replicate code that is already there so it just sets the rules first,
and then goes and builds the list of fields

This is my take on it anyway




Theme © iAndrew 2016 - Forum software by © MyBB