Welcome Guest, Not a member yet? Register   Sign In
Validating 2 or more fields against each other, using callbacks.
#1

[eluser]jonhurlock[/eluser]
Hi,

Ive got a form which uses takes a two inputs, in this case two dates for an event; firstly the start date (when the event starts), and secondly an end date(when the event ends).

I want to be able to do a validation callback to make sure the first date is before the second (starting date is before the end date). I want to do this on the server, not via javascript on the client.

Below is some of the code in my controller.

Code:
function new_event()
{
....
        $this->form_validation->set_rules('datestart', 'Date the Event Starts',  'trim|required|exact_length[10]|xss_clean|callback_date_check');
        $this->form_validation->set_rules('dateend',  'Date the Event Ends',  'trim|required|exact_length[10]|xss_clean|callback_date_check');
...
}

function date_check($str)
{
    list($month, $day, $year) = split('[/.-]', $str);
    $unixtime = mktime(0,0,0,$month,$day,$year);
        
    if ($unixtime <= time())
    {
        $this->form_validation->set_message('date_check', 'The %s can not be before today\'s date.');
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

As you can see i already have a simple callback function to check if the dates entered are after today's date. But now i need to check if the end date, if actually after the start date.

If I can, how do i pass two variables to a call back function, and implement it using the form_validation library? Any help would be greatly appreciated.

If you want to think of this as a simpler, problem amagine a form with two fields. 'password', and 'password confirmation'. You need to check that password is equal to 'password confirmation'.

Kind Regards,

Jon
#2

[eluser]xwero[/eluser]
passing variables to a rule is done by adding square brackets. the variables will be the second argument of the rule.
Code:
function date_check($str,$earliest = time())
{
    if( ! preg_match('/\d{4}-\d{2}-\d{2}/') // you can use more accurate date from string checks    
    {
       return FALSE;
    }

    $input_time = strtotime($str);

    if($input_time < $earliest)
    {
       return FALSE;
    }

    return TRUE;
}
This is the general date checking function you need to use for both dates.

To check if the end date is higher than the start date you only need to add a rule to the end date.
Code:
function date_higher_than($str,$lower_date)
{
   if( ! isset($this->_error_data[$lower_date]) // check to see the lower date has no errors
   { // alternative check $this->_field_data[$lower_date]['error']
       return FALSE;
   }

   if(strtotime($str) < strtotime($this->_field_data[$lower_date]['postdata']))
   {
      return FALSE;
   }
}

I assumed these functions are in the MY_Validation.php file because they are not one trick ponies.
So your rules are going to look like this
Code:
$this->form_validation->set_rules('datestart', 'Date the Event Starts',  'trim|required|exact_length[10]|xss_clean|date_check');
        $this->form_validation->set_rules('dateend',  'Date the Event Ends',  'trim|required|exact_length[10]|xss_clean|date_check|date_higher_than[datestart]');

It's possible the code isn't working but i think you get the idea.
#3

[eluser]Phil Sturgeon[/eluser]
You don't need to convert it to unix time, you can just do the following:

Code:
echo '2008-01-01' > '2007-12-30' ? 'higher' : 'lower';

Check out Less Than, Greater Than, Equal to in Validation for some more general examples of higher/lower which can easily be used to check the dates against each other. You would however need the above callback to check the date is after today.
#4

[eluser]xwero[/eluser]
pyromaniac if you use a more general comparison function you need to add the raw input of the other field where the date_higher_than can benefit from the already manipulated input of the other field.
#5

[eluser]jonhurlock[/eluser]
Thanks xwero, thats exactly what i needed to know! Thanks pyro, but i was looking for the more general solution, so i could apply it to other things, for example the passwords example i gave. But thanks for that tip anyway. Big Grin




Theme © iAndrew 2016 - Forum software by © MyBB