Custom date validation help

Hello

I’m trying to validate a date input and not quite sure how to go about it. My form has a Day dropdown (1-31 with empty default), Month dropdown (1-12 with empty default) and a Year text input.

The date is not required (all inputs can be empty). Other valid combinations are:

  • Year only (format YYYY)

  • Year and Month

  • Year and Month and Day

So Year and Day with no Month selected would be invalid.

The db table stores the value in a single column ("date_acquired") using the format (YYYYMMDD). So before being saved, the 3 inputs need to be combined (this part I can do).

I’m wondering how I validate the date inputs on submission and then remove them when I do the assignment for saving? How should I validate the date inputs as a group?

Any help would be greatly appreciated!

Use a validator method. Here is an example, modify the logic as you need:





class Model extends CActiveRecord

{

    public $year;

    

    public $month;

    

    public $day;

    

    public function rules()

    {

        return array(

            array('date_acquired', 'validateDate'),

        );

    }

    

    public function validateDate($attribute, $params)

    {

        if (isset($this->day)) {

            if ( ! isset($this->month) || ! isset($this->year)) {

                $this->addError('date_acquired', '...message...');

            }

        } else {

            $this->day = '...default value...';

        }

        if (isset($this->month)) {

            if ( ! isset($this->year)) {

                $this->addError('date_acquired', '...message...');

            } 

        } elseif ( ! $this->hasErrors('date_acquired')) {

            $this->month = '...default value...';

        }

        if ( ! $this->hasErrors('date_acquired')) {

         	if ( ! isset($this->year) ) {

                $this->year = '...default value...';

            }

            if (checkdate($this->month, $this->day, $this->year)) {

                $this->date_acquired = $this->year . $this->month . $this->day;

            } else {

                $this->addError('date_acquired', '...message...');

            } 

        }

    }

}



No need to remove them, they don’t cause any problems on save.

Hi phtamas,

Thanks for your suggestions. Some further questions regarding your solution, how do the values for $day, $month and $year get assigned?

Also, how does the validate method know what ‘date_acquired’ is? Because it wouldn’t be in $_POST (I was thinking I’d have the form elements name date_acquired_day, date_acquired_month and date_acquired_year.

Or would you suggest something different?

Thanks.

First, code needs to be modified, because I forgot to add the "safe" rule:




public function rules()

{

	return array(

		array('date_acquired', 'validateDate'),

		array('year,month,day', 'safe'),

	);

}



Then new values can be assigned as usual:


$model->attributes = $_POST['Model'];

$year, $month and $day are normal attributes of Model class, except that they won’t be saved in the database.

‘date_acquired’ is always available as an attribute of your model class.

Just as an FYI, there was a date validator added in Yii 1.1.7 per this page: http://www.yiiframework.com/wiki/56/reference-model-rules-validation/ Just found out about it.