How to validate a form field that is not a model attribute

Hello… I have started to play with YII in order to program a web application, but i have a problem with validating a form.

The form is simple and is about creating a new user (used by an administrator).

I have a password field that belong to a database table, but I need to have a password2 field that doesn’t belong to the users table. I need to perform 2 validations: password2 must be required and password2 must be equal to password.

If I add password2 field using CHtml::activePasswordField, an exception is thrown telling that password2 is not an attribute of the model. When I use CHtml::passwordField, no exception is thrown but the field becomes not required.

How can I do that?

Thanks

Jaime

in model u add:


public $password_repeat;

in order to make your password_repeat field be a member of User model. So, you can now do whatever you want with this variable in context of the model class (for example, to add it as a safeAttribute)

in view


CHtml::activePasswordField($model, 'password_repeat')

in validation rules:


array('password', 'compare')

Thus, your password will be compared to password_repeat.

For further information avout Compare Validator, please see the CCompareValidator

Hello! thanks for answering, but I have the problem that the password_repeat field keeps validating for required field, even when it is not empty.

This is the code for the model:




class Usuario extends CActiveRecord

{

	/**

	 * The followings are the available columns in table 'Usuario':

	 * @var integer $usr_id

	 * @var string $username

	 * @var string $password

	 * @var string $nombres

	 * @var string $apellidos

	 * @var integer $administrator

	 * @var string $email

	 * @var string $ultima_conexion

	 * @var string $fecha_creacion

	 * @var string $fecha_modificacion

	 */


    public $password_repeat;    

    

	/**

	 * Returns the static model of the specified AR class.

	 * @return CActiveRecord the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'Usuario';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		return array(

		    array('username, password, password_repeat, nombres, apellidos, email', 'required'),

			array('username','length','max'=>50),

			array('password','length','max'=>50),

			array('email','length','max'=>80),

			array('email','email'),

			array('password_repeat', 'compare', 'compareAttribute'=>'password', 'on'=>'register'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'usr_id'=>'ID',

			'username'=>'Usuario',

			'password'=>'Contraseña',

		    'password_repeat'=>'Repita Contraseña',

		    'nombres'=>'Nombres',

		    'apellidos'=>'Apellidos',

			'email'=>'Email',

		    'administrador'=>'Administrador',

		);

	}

	

    public function safeAttributes()

    {

        return array(

            parent::safeAttributes(),

            'login' => 'username, password',

        );

    }

}



and this is the code for the _form.php file:




<div class="yiiForm">


<p>

Los campos con <span class="required">*</span> son obligatorios.

</p>


<?php echo EHtml::form(); ?>


<?php echo EHtml::errorSummary($model); ?>


<div class="simple">

<?php echo EHtml::activeLabelEx($model,'username'); ?>

<?php echo EHtml::activeTextField($model,'username',array('size'=>50,'maxlength'=>50)); ?>

</div>

<div class="simple">

<?php echo EHtml::activeLabelEx($model,'password'); ?>

<?php echo EHtml::activePasswordField($model,'password',array('size'=>50,'maxlength'=>50)); ?>

</div>

<div class="simple">

<?php echo EHtml::activeLabelEx($model,'password_repeat'); ?>

<?php echo EHtml::activePasswordField($model,'password_repeat',array('size'=>50,'maxlength'=>50)); ?>

</div>

<div class="simple">

<?php echo EHtml::activeLabelEx($model,'nombres'); ?>

<?php echo EHtml::activeTextField($model,'nombres',array('size'=>80,'maxlength'=>80)); ?>

</div>

<div class="simple">

<?php echo EHtml::activeLabelEx($model,'apellidos'); ?>

<?php echo EHtml::activeTextField($model,'apellidos',array('size'=>80,'maxlength'=>80)); ?>

</div>

<div class="simple">

<?php echo EHtml::activeLabelEx($model,'administrador'); ?>

<?php echo EHtml::activeCheckBox($model, 'administrador', array('checked'=>'checked')); ?>

</div>

<div class="simple">

<?php echo EHtml::activeLabelEx($model,'email'); ?>

<?php echo EHtml::activeTextField($model,'email',array('size'=>60,'maxlength'=>80)); ?>

</div>


<div class="action">

<?php echo EHtml::submitButton($update ? 'Save' : 'Create'); ?>

</div>


<?php echo EHtml::endForm(); ?>

</div><!-- yiiForm -->



what may be happening?

Thanks

Jaime

I would recommend to have a read through this tutorial http://www.yiiframework.com/forum/index.php?/topic/3133-registration-forms-little-tips/

Hello…

I have followed the tutorial but I have the problem that the password_repeat field is not posted, or if it is posted, it is lost somewhere.

for example, if I write an echo to the actionCreate method, I got the exception that the password_repeat is not an index of attributes array (when I use echo $model->attributes[‘password_repeat’]). When I use $model->password_repeat I only get an empty string.

Notice that always validation returns true, meaning that the rule evaluates correctly, so the problem is after posting of the form.




public function actionCreate()

	{

		$model=new Usuario;

		if(isset($_POST['Usuario']))

		{

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

			echo '--->' . $model->password_repeat; // this shows an empty string even if the field was actually filled (and compared correctly with "password" field)

			//exit();

			if($model->save())

				$this->redirect(array('show','id'=>$model->usr_id));

		}

		$this->render('create',array('model'=>$model));

	}



Thanks

Jaime

in the actionCreate() function, I think you should add


$model->scenario = 'register';

to commit compare validation on register scenario.

What data do you receive in $_POST[‘Usuario’]? Could you supply a var_dump or var_export, please?

Try adding it to your safe attributes too.