Cform And Ajax Validation, Errors Not Showing

Hello everyone.

I am building a Form, using CActiveForm Builder. The form renders fine and when I click the ajax-submit button I get a response, but I can’t make the errors show.

This is the CForm Builder:




<?php

	return array(

		'activeForm'=>array(

			'class'=>'CActiveForm',

			'id'=>'datos',

			'stateful'=>true,

			'enableClientValidation'=>true,

			'enableAjaxValidation'=>false,

			'clientOptions'=>array(

				'validateOnSubmit'=>true,

				'validateOnChange'=>true,

				'validateOnType'=>false,

			),

		),

		'showErrorSummary'=>false,

		'action'=>'index.php?r=pagar/buscarColegio',

		'elements'=>array(

			'key'=>array(

				'type'=>'hidden',

			),

			'email'=>array(

				'type'=>'text',

				'class'=>'required email',

				'title'=>Traductor::t('Introduzca una cuenta de correo electrónico válida'),

				'rel'=>'tooltip',

			),

			'telefono'=>array(

				'type'=>'text',

				'class'=>'required digits',

				'title'=>Traductor::t('Introduzca el número de su teléfono móvil (10 dígitos sin espacios ni guiones)'),

				'maxlength'=>10,

				'minlength'=>10,

				'rel'=>'tooltip',

			),

			'estado_id'=>array(

				'type'=>'dropdownlist',

				'items'=>Estado::model()->lista_estados(Estado::model()->obtener_lista_estados(Yii::app()->params['pais_id']), 'estado_id', 'estado'),

				'prompt'=>Traductor::t('Seleccione'),

				'class'=>'required',

				'title'=>Traductor::t('Seleccione el estado del colegio que está buscando'),

				'rel'=>'tooltip',

			),

			'ciudad'=>array(

				'type'=>'dropdownlist',

				'prompt'=>Traductor::t('Primero elija un estado'),

				'disabled'=>true,

				'class'=>'required',

				'title'=>Traductor::t('Selecciona la ciudad donde se encuentra el colegio'),

				'rel'=>'tooltip',

			),

			'nombre_colegio'=>array(

				'type'=>'text',

				'class'=>'required lettersandspacesonly',

				'title'=>Traductor::t('Escriba el nombre del colegio. Puede usar mayúsculas o minúsculas. No use acentos ni caracteres especiales'),

				'disabled'=>true,

				'minlength'=>2,

				'rel'=>'tooltip',

			),

			'privacidad'=>array(

				'type'=>'checkbox',

				'class'=>'required',

				'title'=>Traductor::t('Para continuar es necesario aceptar los términos y condiciones'),

				'value'=>'1',

				'rel'=>'tooltip',

			)

		),

		'buttons'=>array(

			'buscar'=>array(

				'type'=>'submit',

				'attributes'=>array(

					'value'=>Traductor::t('Buscar'),

					'class'=>'submitRojo',

					'ajax'=>array(

						'type'=>'POST',

						'url'=>Yii::app()->createUrl('pagar/buscarColegio')

					),

				),

			),

		),

	);



This is the view:




<?php echo $colegio_form->renderBegin() ?>

		<?php echo $colegio_form['key']->renderInput() ?>

		<div class="paso1">

			<h3><?php echo Traductor::t("Datos personales"); ?></h3>

			<div>

				<?php echo $colegio_form['email']->renderLabel() ?>

				<?php echo $colegio_form['email']->renderInput() ?>

				<?php echo $colegio_form['email']->renderError() ?>

			</div>

			<div>

				<?php echo $colegio_form['telefono']->renderLabel() ?>

				<?php echo $colegio_form['telefono']->renderInput() ?>

				<?php echo $colegio_form['telefono']->renderError() ?>

			</div>

	

			<h3><?php echo Traductor::t("Datos de la escuela"); ?></h3>

			<div>

				<?php echo $colegio_form['estado_id']->renderLabel() ?>

				<?php echo $colegio_form['estado_id']->renderInput() ?>

				<?php echo $colegio_form['estado_id']->renderError() ?>

			</div>

			<div>

				<div>

					<?php echo $colegio_form['ciudad']->renderLabel() ?>

					<div id="estado_loading" class="loading" style="display:none"></div>

				</div>

				<?php echo $colegio_form['ciudad']->renderInput() ?>

				<?php echo $colegio_form['ciudad']->renderError() ?>

			</div>

			<div>

				<?php echo $colegio_form['nombre_colegio']->renderLabel() ?>

				<?php echo $colegio_form['nombre_colegio']->renderInput() ?>

				<?php echo $colegio_form['nombre_colegio']->renderError() ?>

			</div>

			

			<div class="aceptarCondicionesPrivacidad">	

				<?php echo $colegio_form['privacidad']->renderInput() ?>

				<?php echo $colegio_form['privacidad']->renderLabel() ?><br/>

				<?php echo $colegio_form['privacidad']->renderError() ?>

				<!--div id="mensajeCondiciones" class="msgError" style="display:none"></div-->

			</div>

			

		</div><!-- .paso1 -->

	

	<div class="botonesForm">

		<!--input type="submit" name="datos[buscar]" value="<?php echo Traductor::t("Buscar"); ?>" id="submit" class="submitRojo" /-->

		<?php echo $colegio_form->buttons['buscar'] ?>

		<div class="clear"></div>

	</div>

	

	<?php echo $colegio_form->renderEnd() ?>



This is ColegioForm model:




<?php


/**

 * Clase ColegioForm.

 * ColegioForm es la estructura de los datos para buscar un colegio

 * Usadon en pagar/index

 */

class ColegioForm extends CFormModel

{

	public $key;

	public $email;

	public $telefono;

	public $nombre_colegio;

	public $estado_id;

	public $ciudad;

	public $privacidad;

	public $buscar;


	/**

	 * Reglas de validación

	 */

	public function rules()

	{

		return array(

			// todos son obligatorias

			array('key, email, telefono, nombre_colegio, estado_id, ciudad, privacidad', 'required'),

			// variable email que sea una cuenta de correo electronico valida

			array('email','email'),

			// telefono debe ser de 10 digitos

			array('telefono','length','min'=>10, 'max'=>10),

			// telefono debe ser numerico

			array('telefono','numerical'),

			// nombre_colegio debe ser minimo 2 caracteres

			array('nombre_colegio', 'length', 'min'=>2),

			// privacidad deber ser 1 = acepta

			//array('privacidad', 'match', '1'),

		);

	}


	/**

	 * Nombres de los campos/variables

	 */

	public function attributeLabels()

	{

		return array(

			'email'=>Traductor::t('Correo electrónico'),

			'telefono'=>Traductor::t('Número de teléfono móvil'),

			'estado_id'=>Traductor::t('Estado'),

			'ciudad'=>Traductor::t('Ciudad'),

			'nombre_colegio'=>Traductor::t('Nombre del colegio'),

			'privacidad'=>Traductor::t("He leído y estoy de acuerdo con los {link1a}términos y condiciones{link1b}, y otorgo mi consentimiento para que mis datos personales sean tratados conforme a lo previsto en el presente {link2a}aviso de privacidad{link2b}.", array('link1a'=>'<a href="terminos_condiciones.php" target="_blank">', 'link1b'=>'</a>', 'link2a'=>'<a href="privacidad.php" target="_blank">', 'link2b'=>'</a>')),

			'buscar'=>Traductor::t('Buscar'),

		);

	}

}



This is the action that renders the form:





		public function actionIndex()

		{

			$colegio_form_model = new ColegioForm;

			$colegio_form = new CForm('application.views.pagar.forma_colegio', $colegio_form_model);

			//$estados = Estado::model()->obtener_lista_estados(Yii::app()->params['pais_id']);

			//$lista_estados = CHtml::listData($estados, 'estado_id', 'estado');

			Yii::app()->clientScript->registerScriptFile('js/index.js', CClientScript::POS_END);

			$this->render('index', array(

				'colegio_form'=>$colegio_form, 

				'estados'=>$estados,

				'lista_estados'=>$lista_estados

			));

		}



And this is the action that recieves the form and validates the input:




		public function actionBuscarColegio()

		{

			$colegio = new ColegioForm;

			$colegio->attributes = $_POST['ColegioForm'];

			$this->performAjaxValidation($colegio);

			if (isset($_POST['ColegioForm'])) {

				// buscar el colegio

			}

			//$this->redirect('index', array('colegio_form'=>$colegio, 'lista_colegios'=>$lista_colegios));

			

		}

		

		/**

		 * Performs the AJAX validation.

		 * @param CModel the model to be validated

		 */

		protected function performAjaxValidation($model)

		{

			echo CActiveForm::validate($model);

		}



When I click the ajax-submit button, with all fields blank, I recieve (using Firebug):




{"ColegioForm_key":["Key cannot be blank."],"ColegioForm_email":["Correo electr\u00f3nico cannot be blank."],"ColegioForm_telefono":["N\u00famero de tel\u00e9fono m\u00f3vil cannot be blank."],"ColegioForm_nombre_colegio":["Nombre del colegio cannot be blank."],"ColegioForm_estado_id":["Estado cannot be blank."],"ColegioForm_ciudad":["Ciudad cannot be blank."]}



Also, and finally, I can see these JavaScript files loaded:




jquery.cookie.js

jquery.yiiactiveform.js

jquery-ui-custom.min.js

jquery-ui-i18n.js

jquery.validate.min.js

additional-methods.js

jquery.qtip.min.js

site.js

yii.debug.toolbar.js

index.js



What am I missing?

Thanks

Hi transitor,

An effective tool in a situation like this is to use an extension like Live HTTP Headers. When you submit the form, you can see if the validation request is being sent, and you can manually resend the request to ensure your validation method is functioning as it should (i.e. no errors, returning validation errors, etc.).

Although, you’ve set enableAjaxValidation to false, so I don’t know what you’re expecting :P

Hello,

Put like that in your controller…

actionIndex




                public function actionIndex()

                {

                        $colegio_form_model = new ColegioForm;

                        $colegio_form = new CForm('application.views.pagar.forma_colegio', $colegio_form_model);

                        //$estados = Estado::model()->obtener_lista_estados(Yii::app()->params['pais_id']);

                        //$lista_estados = CHtml::listData($estados, 'estado_id', 'estado');

                        Yii::app()->clientScript->registerScriptFile('js/index.js', CClientScript::POS_END);

                        $this->render('index', array(

                                'colegio_form'=>$colegio_form, 

                                'estados'=>$estados,

                                'lista_estados'=>$lista_estados

                        ),false,true);

                }



Oh man… hahaha! sorry, didn’t notice that, but, setting enableAjaxValidation to true (and enableClientValidation to false) doesn’t help, it works exactly the same.

Thanks, I see what you did there, but still no errors show up, I tried switching between enableAjaxValidation and enableClientValidation without success.

After you perform the validation you should really be calling Yii::app()->end(), if you’re not doing anything else.

Are you receiving any JS errors in console?

No errors in the console, weird, I know. Thanks.

I got it to work, but I had to to this:

Add a condition to the "success" function of the ajax call to show the errors if var estatus is not 1




		'buttons'=>array(

			'buscar'=>array(

				'type'=>'submit',

				'attributes'=>array(

					'value'=>Traductor::t('Buscar'),

					'class'=>'submitRojo',

					'ajax'=>array(

						'beforeSend'=>"function() {

							spinner('#alumnos_loading');

						}",

						'type'=>'POST',

						'dataType'=> 'json',

						'url'=>Yii::app()->createUrl('pagar/buscarAlumno'),

						'success'=>'function(data) {

							if (data.estatus==1) {

								esconderErrores();

								cargarListaAlumnos(data);

							} else {

								mostrarErrores(data);

							}

						}',

						'complete'=>"function(data) {

							spinner('#alumnos_loading');

						}"

					),

				),

			),

		),



This is the javascript function mostrarErrorres:




function mostrarErrores(data) {

	$.each(data, function (key, val) {

		$('#'+key+'_em_').html(val.toString()).show();

	});

}



This means that the response of the action buscarAlumno must be json and must have a variable "estatus" with value of 1, otherwise it will try to show errors.

I’m satisfied with this, it works and is reasonably reusable.