Welcome Guest, Not a member yet? Register   Sign In
Custom callback function in form validation not working
#1

[eluser]alucard[/eluser]
Hi guys,

My 'check_against_plan_type' custom callback function is not working.

The other callback functions are working correctly.

The error message that I am getting is:
'Call to a member function set_message() on a non-object in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\codeigniter\application\libraries\my_form_validation.php on line 38'

My callback functions which are in a separate class:

Code:
function compare_cat(){//compare categories - callback function for form validation
            if( !$_POST['category1']=="" &&($_POST['category1'] == $_POST['category2'])){
               $this->CI->form_validation->set_message('compare_cat','Category 1 and category 2 cannot be the same');
                return false;
            }
            else{
                return true;
            }
        }
        function valid_url(){//check if url supplied is valid - callback function for form validation
            if(!preg_match('/^((http:\/\/www\.)|(www\.)|(http:\/\/))[a-zA-Z0-9._-]+\.[a-zA-Z.]{2,5}$/', $_POST['link'])){
                $this->CI->form_validation->set_message('valid_url',"Enter a valid url, make sure to enter 'http://' first.");
                return false;
            }
            else{
                return true;
            }
        }
        function valid_email(){
            if(!preg_match( '/^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/', $_POST['email'])){
                $this->CI->form_validation->set_message('valid_email',"Enter a valid email");
                return false;
            }
            else{
                return true;
            }
        }
        function check_against_plan_type(){
            if((isset($_POST['listing_plan_id']) && $_POST['listing_plan_id'] == 3) && str_word_count($_POST['description']) > 100){
                $this->CI->form_validaton->set_message('check_against_plan_type', "For the plan you have chosen, description word count cannot be more than 100");
                //echo 'more than 50';
                //exit;
                return false;
            }
            else{
                return true;
            }
        }
}

This is how I am setting the rules:
Code:
function set_rules(){
            //set validation rules
            $this->my_form->form_validation->set_rules('category1', $this->field_labels['category1'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('category2', $this->field_labels['category2'], "trim|compare_cat|xss_clean");
            $this->my_form->form_validation->set_rules('title', $this->field_labels['title'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('description', $this->field_labels['description'], "trim|check_against_plan_type|xss_clean");
            $this->my_form->form_validation->set_rules('phone', $this->field_labels['phone'], "trim|required|numeric|min_length[10]|max_length[11]");
            $this->my_form->form_validation->set_rules('link', $this->field_labels['link'], "trim|required|valid_url|xss_clean");
            if(!(isset($_POST['online_only_business'])) && isset($_POST['address_line1'])){
                $this->my_form->form_validation->set_rules('address_line1', $this->field_labels['address_line1'], "trim|required|xss_clean");
            }
            $this->my_form->form_validation->set_rules('address_line2', $this->field_labels['address_line2'], "trim|xss_clean");
            
            if(!(isset($_POST['online_only_business'])) && isset($_POST['city'])){
                $this->my_form->form_validation->set_rules('city', $this->field_labels['city'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['state'])){
                $this->my_form->form_validation->set_rules('state', $this->field_labels['state'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['post_code'])){
                $this->my_form->form_validation->set_rules('post_code', $this->field_labels['post_code'], "trim|required|numeric|max_length[4]|min_length[4]|xss_clean");
            }

            $this->my_form->form_validation->set_rules('listing_plan_id', '', "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('email', $this->field_labels['email'], "trim|required|valid_email|xss_clean");
    }
}

If anyone can help me out, I'd appreciate it.

Thanks
Alucard
#2

[eluser]toopay[/eluser]
Did you load the form validation class before call/use its function? Seems that class wasn't declared yet.
Code:
$this->load->library('form_validation');
And it should be simply like
Code:
$this->form_validation->set_rules();
instead
Code:
$this->my_form->form_validation->set_rules();
except, you did already declare 'my_form' variable as CI instance.
#3

[eluser]LuckyFella73[/eluser]
Hi alucard,

the Userguide says:
Quote:To invoke a callback just put the function name in a rule, with "callback_" as the rule prefix.

It seems that part is missing where you set the rule.

Code:
// should look like:
$this->my_form->form_validation->set_rules('description', $this->field_labels['description'], "trim|callback_check_against_plan_type|xss_clean");

It may be a good idea to make the callback function private!

Code:
function _check_against_plan_type { ... }

// then set the rule like this:
$this->my_form->form_validation->set_rules('description', $this->field_labels['description'], "trim|callback__check_against_plan_type|xss_clean");

Hope that helps
#4

[eluser]alucard[/eluser]
Thanks for replying guys,

I am trying to have form validation code separate from the controller.

This is how I have done it. It may be wrong. Please tell me if it is.

I had to take out the callback keyword when setting the rules for it to work.

The form validation and all callback functions are working correctly except for the 'check_against_plan_type' function.

If I have done it incorrectly please tell me, I tried to do it various other ways but it wouldn't work.

The setting of the rules is done in this class which is in applications/libraries:
Code:
class myform_validation{

    public $my_form;
    public $field_labels = array();
    
    public function  __construct($field_labels = array()) {
        $this->my_form = & get_instance();
        $this->my_form->load->library('form_validation');
        $this->field_labels = $field_labels;
    }
    public function do_validation(){
        if (isset($_POST["submit"])) {
            $this->my_form->form_validation->set_error_delimiters('<div class="error">', '</div>');

            $this->set_rules();
                /*
                    If validation passed return true else return false
                */

            return $this->my_form->form_validation->run()? true: false;
        }
    }

    function set_rules(){
            //set validation rules
            $this->my_form->form_validation->set_rules('category1', $this->field_labels['category1'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('category2', $this->field_labels['category2'], "trim|compare_cat|xss_clean");
            $this->my_form->form_validation->set_rules('title', $this->field_labels['title'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('description', $this->field_labels['description'], "trim|check_against_plan_type|xss_clean");
            $this->my_form->form_validation->set_rules('phone', $this->field_labels['phone'], "trim|required|numeric|min_length[10]|max_length[11]");
            $this->my_form->form_validation->set_rules('link', $this->field_labels['link'], "trim|required|valid_url|xss_clean");
            if(!(isset($_POST['online_only_business'])) && isset($_POST['address_line1'])){
                $this->my_form->form_validation->set_rules('address_line1', $this->field_labels['address_line1'], "trim|required|xss_clean");
            }
            $this->my_form->form_validation->set_rules('address_line2', $this->field_labels['address_line2'], "trim|xss_clean");
            
            if(!(isset($_POST['online_only_business'])) && isset($_POST['city'])){
                $this->my_form->form_validation->set_rules('city', $this->field_labels['city'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['state'])){
                $this->my_form->form_validation->set_rules('state', $this->field_labels['state'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['post_code'])){
                $this->my_form->form_validation->set_rules('post_code', $this->field_labels['post_code'], "trim|required|numeric|max_length[4]|min_length[4]|xss_clean");
            }

            $this->my_form->form_validation->set_rules('listing_plan_id', '', "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('email', $this->field_labels['email'], "trim|required|valid_email|xss_clean");
    }
}

The call back functions are in another class in applications/libraries:
Code:
class my_form_validation extends CI_Form_validation{
    
    public $CI;
    public function _construct(){
        $this->CI = & get_instance();
        $this->CI->load->library('form_validation');
    }
        function compare_cat(){//compare categories - callback function for form validation
            if( !$_POST['category1']=="" &&($_POST['category1'] == $_POST['category2'])){
               $this->CI->form_validation->set_message('compare_cat','Category 1 and category 2 cannot be the same');
                return false;
            }
            else{
                return true;
            }
        }
        function valid_url(){//check if url supplied is valid - callback function for form validation
            if(!preg_match('/^((http:\/\/www\.)|(www\.)|(http:\/\/))[a-zA-Z0-9._-]+\.[a-zA-Z.]{2,5}$/', $_POST['link'])){
                $this->CI->form_validation->set_message('valid_url',"Enter a valid url, make sure to enter 'http://' first.");
                return false;
            }
            else{
                return true;
            }
        }
        function valid_email(){
            if(!preg_match( '/^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/', $_POST['email'])){
                $this->CI->form_validation->set_message('valid_email',"Enter a valid email");
                return false;
            }
            else{
                return true;
            }
        }
        function check_against_plan_type(){
            if((isset($_POST['listing_plan_id']) && $_POST['listing_plan_id'] == 3) && str_word_count($_POST['description']) > 100){
                $this->CI->form_validaton->set_message('check_against_plan_type', "For the plan you have chosen, description word count cannot be more than 100");
                //echo 'more than 100';
                //exit;
                return false;
            }
            else{
                return true;
            }
        }
}
In my controller I have a function which loads:
Code:
$this->load->library('myform_validation', $this->get_field_labels());
  //do somestuff
if($this->myform_validation->do_validation()){
//validation passed
//do somestuff
}
#5

[eluser]toopay[/eluser]
If you are extending form validation class and put MY both on your custom class and config, then you dont need to call/load your custom class since it would automaticly loaded when you already load form validation class. Also, if i can give you suggestion, that would be to modify for better naming convention on check_against_plan_type function.
#6

[eluser]LuckyFella73[/eluser]
I don't know yet why exactly your rule doesn't work but
the word "callback" lead me into a wrong direction.
You extended the form_validation class and just did set
up new rules - they are no callback functions then Wink

I would prefer to extend the form_validation class the CI way:
Code:
// save that file into application/libraries:
class MY_Form_validation extends CI_Form_validation {
// here your rules
}

Btw. there is allready a rule to check for valid email.

@toopay - you are replying too fast, I better give up posting for today Wink
#7

[eluser]alucard[/eluser]
I have tried to make the changes you guys have suggested but I am getting this error message:
'Non-existent class: Form_validation'

I changed name of 'check_against_plan_type ' to 'valid_description'

All the rules including custom rules (thanks Luckyfella for the tip :-) ) are in this class:
Code:
class MY_Form_validation extends CI_Form_validation{

    public $my_form;
    public $field_labels = array();
    
    public function  __construct($field_labels = array()) {
        parent::_construct();
        $this->my_form = & get_instance();
        $this->my_form->load->library('form_validation');
        $this->field_labels = $field_labels;
    }
    public function do_validation(){
        if (isset($_POST["submit"])) {
            $this->my_form->form_validation->set_error_delimiters('<div class="error">', '</div>');

            $this->set_rules();
                /*
                    If validation passed return true else return false
                */

            return $this->my_form->form_validation->run()? true: false;
        }
    }

    function set_rules(){
            //set validation rules
            $this->my_form->form_validation->set_rules('category1', $this->field_labels['category1'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('category2', $this->field_labels['category2'], "trim|compare_cat|xss_clean");
            $this->my_form->form_validation->set_rules('title', $this->field_labels['title'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('description', $this->field_labels['description'], "trim|valid_description|xss_clean");
            $this->my_form->form_validation->set_rules('phone', $this->field_labels['phone'], "trim|required|numeric|min_length[10]|max_length[11]");
            $this->my_form->form_validation->set_rules('link', $this->field_labels['link'], "trim|required|valid_url|xss_clean");
            if(!(isset($_POST['online_only_business'])) && isset($_POST['address_line1'])){
                $this->my_form->form_validation->set_rules('address_line1', $this->field_labels['address_line1'], "trim|required|xss_clean");
            }
            $this->my_form->form_validation->set_rules('address_line2', $this->field_labels['address_line2'], "trim|xss_clean");
            
            if(!(isset($_POST['online_only_business'])) && isset($_POST['my_formty'])){
                $this->my_form->form_validation->set_rules('my_formty', $this->field_labels['my_formty'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['state'])){
                $this->my_form->form_validation->set_rules('state', $this->field_labels['state'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['post_code'])){
                $this->my_form->form_validation->set_rules('post_code', $this->field_labels['post_code'], "trim|required|numeric|max_length[4]|min_length[4]|xss_clean");
            }

            $this->my_form->form_validation->set_rules('listing_plan_id', '', "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('email', $this->field_labels['email'], "trim|required|valid_email|xss_clean");
    }
        function compare_cat(){//compare categories - callback function for form validation
            if( !$_POST['category1']=="" &&($_POST['category1'] == $_POST['category2'])){
               $this->my_form->form_validation->set_message('compare_cat','Category 1 and category 2 cannot be the same');
                return false;
            }
            else{
                return true;
            }
        }
        function valid_url(){//check if url supplied is valid - callback function for form validation
            if(!preg_match('/^((http:\/\/www\.)|(www\.)|(http:\/\/))[a-zA-Z0-9._-]+\.[a-zA-Z.]{2,5}$/', $_POST['link'])){
                $this->my_form->form_validation->set_message('valid_url',"Enter a valid url, make sure to enter 'http://' first.");
                return false;
            }
            else{
                return true;
            }
        }
        function valid_email(){
            if(!preg_match( '/^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/', $_POST['email'])){
                $this->my_form->form_validation->set_message('valid_email',"Enter a valid email");
                return false;
            }
            else{
                return true;
            }
        }
        function valid_description(){
            if((isset($_POST['listing_plan_id']) && $_POST['listing_plan_id'] == 3) && str_word_count($_POST['description']) > 100){
                $this->my_form->form_validaton->set_message('valid_description', "For the plan you have chosen, description word count cannot be more than 100");
                //echo 'more than 50';
                //exit;
                return false;
            }
            else{
                return true;
            }
        }
}
?&gt;
I changed the file name to Form_validation.php

In my controller function I changed it to:
Code:
$this->load->library('form_validation', $this->get_field_labels());
           //do somesuff
            if($this->form_validation->do_validation()){
//validation passed
//do somestuff
}
#8

[eluser]LuckyFella73[/eluser]
Your class extending the form_validation class must be
saved in application/libraries and have the filename: "MY_Form_validation.php"
unless you did set up an other prefix in your config file.

In your class "MY_Form_validation" there is no need to load the form_validation
class! your class will be merged automatically when loading the form_validation class
#9

[eluser]toopay[/eluser]
You may want to look at User Guide closely, at extending/Creating Libraries section.
#10

[eluser]alucard[/eluser]
Woohoo I got it working including the custom rule that wasn't working before.

Thanks guys for all the help, everything is working now.

This is how it looks now:
Code:
class MY_form_validation extends CI_Form_validation{

    public $my_form;
    public $field_labels = array();
    
    public function  __construct($field_labels = array()) {
        
        $this->my_form =& get_instance();
        //$this->my_form->load->library('form_validation');
        $this->field_labels = $field_labels;
        parent::__construct();
    }
    public function do_validation(){
        if (isset($_POST["submit"])) {
            $this->my_form->form_validation->set_error_delimiters('<div class="error">', '</div>');

            $this->set_rules_();
                /*
                    If validation passed return true else return false
                */

            return $this->my_form->form_validation->run()? true: false;
        }
    }

    public function set_rules_(){
            //set validation rules
            $this->my_form->form_validation->set_rules('category1', $this->field_labels['category1'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('category2', $this->field_labels['category2'], "trim|compare_cat|xss_clean");
            $this->my_form->form_validation->set_rules('title', $this->field_labels['title'], "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('description', $this->field_labels['description'], "trim|valid_description|xss_clean");
            $this->my_form->form_validation->set_rules('phone', $this->field_labels['phone'], "trim|required|numeric|min_length[10]|max_length[11]");
            $this->my_form->form_validation->set_rules('link', $this->field_labels['link'], "trim|required|valid_url|xss_clean");
            if(!(isset($_POST['online_only_business'])) && isset($_POST['address_line1'])){
                $this->my_form->form_validation->set_rules('address_line1', $this->field_labels['address_line1'], "trim|required|xss_clean");
            }
            $this->my_form->form_validation->set_rules('address_line2', $this->field_labels['address_line2'], "trim|xss_clean");
            
            if(!(isset($_POST['online_only_business'])) && isset($_POST['my_formty'])){
                $this->my_form->form_validation->set_rules('my_formty', $this->field_labels['my_formty'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['state'])){
                $this->my_form->form_validation->set_rules('state', $this->field_labels['state'], "trim|required|xss_clean");
            }
            if(!(isset($_POST['online_only_business'])) && isset($_POST['post_code'])){
                $this->my_form->form_validation->set_rules('post_code', $this->field_labels['post_code'], "trim|required|numeric|max_length[4]|min_length[4]|xss_clean");
            }

            $this->my_form->form_validation->set_rules('listing_plan_id', '', "trim|required|xss_clean");
            $this->my_form->form_validation->set_rules('email', $this->field_labels['email'], "trim|required|valid_email|xss_clean");
    }
        function compare_cat(){//compare categories - callback function for form validation
            if( !$_POST['category1']=="" &&($_POST['category1'] == $_POST['category2'])){
               $this->my_form->form_validation->set_message('compare_cat','Category 1 and category 2 cannot be the same');
                return false;
            }
            else{
                return true;
            }
        }
        function valid_url(){//check if url supplied is valid - callback function for form validation
            if(!preg_match('/^((http:\/\/www\.)|(www\.)|(http:\/\/))[a-zA-Z0-9._-]+\.[a-zA-Z.]{2,5}$/', $_POST['link'])){
                $this->my_form->form_validation->set_message('valid_url',"Enter a valid url, make sure to enter 'http://' first.");
                return false;
            }
            else{
                return true;
            }
        }
        function valid_email(){
            if(!preg_match( '/^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/', $_POST['email'])){
                $this->my_form->form_validation->set_message('valid_email',"Enter a valid email");
                return false;
            }
            else{
                return true;
            }
        }
        function valid_description(){
            if((isset($_POST['listing_plan_id']) && $_POST['listing_plan_id'] == 3) && str_word_count($_POST['description']) > 100){
                $this->my_form->form_validation->set_message('valid_description', "For the plan you have chosen, description word count cannot be more than 100");
                //echo 'more than 50';
                //exit;
                return false;
            }
            else{
                return true;
            }
        }
}




Theme © iAndrew 2016 - Forum software by © MyBB