Welcome Guest, Not a member yet? Register   Sign In
[solved] validation class - callback functions
#1

[eluser]obiron2[/eluser]
Hi guys,

I am trying to extend my knowlege of some of the more advanced functions in CI.

I have a form which requires a start and end date, populated as 3 fields per date Sday,Smth,Syr and Eday,Emth,Eyr

I would like to use the validation class to do the following:

Validate that each field is populated and is numeric and no more than 2 digits long - easy - 'required|trim|numeric|max_length[2]'.

Validate that when Sday,Smth,Syr are combined together they form a valid date

Validate that the start date is before the end date

Validate that the start date is after a date pulled from the database

I don't really understand what is happening with $rules[] and $fields[] and what the validation class then does with them

Can anyone point me in the right direction on how to combine fields together in validation rules.



Thanks

obiron
#2

[eluser]ELRafael[/eluser]
http://ellislab.com/codeigniter/user-gui...ation.html

Read the Callbacks: Your own Validation Functions section.

:-P
#3

[eluser]obiron2[/eluser]
I did.

The examples given allow you to validate a single field in the callback. I need to validate a combination of three / six fields in a single callback.

I am not clear how to define the $rules and $fields. If someome can show me how to do that and format the function call, I can write the function.

The function I am looking to write is a basic date validator - do the three fields represent a valid date, is one date before another. I will post the functions back to the community.

Obiron
#4

[eluser]Michael Ekoka[/eluser]
Lets say we want to validate a date. It's typically made using 3 selectbox fields in a form (day, month, year). We don't want to validate the fields separately so we assign one callback validation method to one of the fields, as well as the name of the compound field (Date of Birth). Now, the validation doesn't care what your callback method does inside. It's only concerned with the value that it returns. So, if it returns false, the validator knows to display the error message. If it returns nothing or true the validator assumes the field is valid.

Code:
function my_action(){
    // assign the callback to one of the fields
    $rules['year'] = 'callback__valid_date';
    // assign the compound to one of the fields
    $fields['year'] = 'Date of Birth';
    // the next 2 fields need to be set just to redisplay their value in the
    // form in case of validation failure
    $fields['month'] = '';
    $fields['day'] = '';

    $this->validation->set_rules($rules);
    $this->validation->set_fields($fields);
    $valid = $this->validation->run();
    if($valid){
        // do your thing
    }else{
        // do your other thing
    }
}

function _valid_date(){
    $day = $this->input->post('day');
    $month = $this->input->post('month');
    $year = $this->input->post('year');
    // this message will be displayed if this method returns false
    $this->validation->set_message('_valid_date', 'The %1$s is not valid.');

    if (!checkdate($month, $day, $year)){
        return false;
    }

    $hollow_months = array(4,6,9,11);
    if(in_array($month,$hollow_months) AND $day>30){
        return false;    
    }

    $leap_year = ($year%4==0?true:false);
    if($month == 2){
        if( $leap_year){
            if($day > 29 ){
                return false;
            }
        }else{
            if($day > 28){
                return false;
            }
        }    
    }    
}
#5

[eluser]obiron2[/eluser]
Superstar!

and I don't even need to write the function. Thankyou so much.

If I need to check two dates, I suppose I either need two callback functions with different $this->input-post('XXX') values which then get passed on to the valid_date function or pass a variable through to the function and put a case statemement into the function to set the $this->input->post('xxx')

If I need to do multiple validations, would I do this by getting the callback function to run multiple functions or can I do multiple callbacks.

Obiron
#6

[eluser]Michael Ekoka[/eluser]
For multiple dates, you will need a couple of steps, but this works very well if you understand what's going on.

In your form declare your date values like this:

Code:
<html>
Date of Birth:
<select name="birth[day]" >....</select>
<select name="birth[month]">....</select>
<select name="birth[year]">....</select>

Died on:
<select name="rip[day]" >....</select>
<select name="rip[month]">....</select>
<select name="rip[year]">....</select>

now you would change the code above like:

Code:
function my_action(){
    // assign the callback to one of the fields
    $rules['birth'] = 'callback__valid_date';
    $rules['rip'] = 'callback__valid_date';
    // give a display name to the compound (this is mostly for error messages
    $fields['birth'] = 'Date of Birth';
    $fields['rip'] = 'Died on';
    // I bumped into some problems with the validation while using it
    // like this. For some unknown reasons, it won't automatically reassign the $birth[] or $rip[] arrays
    // (or POST arrays for that matter) to $this->validation->birth and $this->validation->rip.
    // You will have to do this manually after you've ran the validation.

    $this->validation->set_rules($rules);
    $this->validation->set_fields($fields);
    $valid = $this->validation->run();

    // Now, don't forget to manually reassign the arrays here if you want
    // to redisplay the values in the form.    
    $this->validation->birth = $this->input->post('birth');
    $this->validation->rip = $this->input->post('rip');
    // Upon validation failure, you can now redisplay the dates
    // like $this->validation->birth['year'], etc.

    if($valid){
        // do your thing
    }else{
        // do your other thing
    }
}

// a more generic date validator
function _valid_date($date){
    $day = $date['day'];
    $month = $date['month'];
    $year = $date['year'];
    // this message will be displayed if this method returns false
    $this->validation->set_message('_valid_date', 'The %1$s is not valid.');

    if (!checkdate($month, $day, $year)){
        return false;
    }

    $hollow_months = array(4,6,9,11);
    if(in_array($month,$hollow_months) AND $day>30){
        return false;    
    }

    $leap_year = ($year%4==0?true:false);
    if($month == 2){
        if( $leap_year){
            if($day > 29 ){
                return false;
            }
        }else{
            if($day > 28){
                return false;
            }
        }    
    }    
}
#7

[eluser]iive[/eluser]
CodeIgniter, you are so helpful. I just came across to this problem and it is solved after I read this thread. Thanks.
#8

[eluser]souto[/eluser]
The same goes to me.
This is an important feature, since validation often requires interaction between fields, and not fields per se.

Thanks a lot.




Theme © iAndrew 2016 - Forum software by © MyBB