Ajax Not Applying Scenario In Validation

Hello,

Currently I’m creating a “Forgot Password” scenario, where I just need an e-mail to check if its everything ok.

However, when trying to apply scenario conditions to model using except, the validator (being called in AJAX), just seem to ignore it and keeps calling for all the validation rules (first name required, last name required, email unique, email required, password required).

I just don’t understand why, as I’m explicitly saying that I’m using forgot_password scenario.

My code:

controller





class SiteController extends Controller {


    public function actionLogin() {


        if (!Yii::app()->user->isGuest) {

            $this->redirect($this->createAbsoluteUrl('/'));

        }


        # [...]


        $forgot_pw = new Player('forgot_password');


        // esqueceu a password

        if(isset($_POST['recoverPassword']) && isset($_POST['Player'])) {

        

	    $forgot_pw->attributes = $_POST['Player'];


            $this->performRegisterAjaxValidation($forgot_pw);


            if ($forgot_pw->validate()) {

                $forgot_pw->sendPasswordRecoveryEmail();

                Yii::app()->user->setFlash('success', "Foi-lhe enviado um e-mail contendo um link que terá de clicar para receber uma nova password no seu e-mail.");

                $this->redirect($this->createAbsoluteUrl('/'));

                // envia email com chave de renovaçao de pw

                // sucesso

            }

            

        }


        # [...]


        // displays the login form

        $this->render('login', array('model' => $model, 'user' => $user, 'forgot_pw'=>$forgot_pw));

    }


        

        protected function performRegisterAjaxValidation($model)

        {

                if(Yii::app()->getRequest()->getIsAjaxRequest()) {


                    echo CActiveForm::validate( array( $model )); 


                    Yii::app()->end(); 


                }


        }

    


}



model




class Player extends CActiveRecord

{

	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

                        array('firstname, lastname, password', 'required', 'message'=>'{attribute} é um campo de preenchimento obrigatório','except'=>'forgot_password'),

			array('email','required', 'message'=>'{attribute} é um campo de preenchimento obrigatório'),

                        array('country_id', 'length', 'max'=>10),

			array('firstname', 'length', 'max'=>20),

			array('lastname, nickname', 'length', 'max'=>30),

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

                        array('email', 'email', 'message'=>'Insira um endereço de e-mail correto.'),

                        array('email', 'unique','message'=>'Já existe um utilizador com esse endereço de e-mail','except'=>'forgot_password'),

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

			array('activation_key,recover_key', 'length', 'max'=>45),

			array('birthdate', 'safe'),

                        array('registered_at', 'type', 'type'=>'datetime', 'datetimeFormat'=>'dd-MM-yyyy hh:mm','on'=>'insert'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('id, country_id, birthdate, firstname, email, lastname, nickname', 'safe', 'on'=>'search'),

		);

	}


        # [...]


}



view


    <h1>Esqueceu a sua password?</h1>

    

    <?php $form_pw = $this->beginWidget('CActiveForm', array(

        'id'=>'forgot-password-form',

        'enableAjaxValidation'=>true,

        'enableClientValidation'=>true,

        'focus'=>array($forgot_pw,'email'),

        'clientOptions'=>array('validateOnSubmit'=>true),

    )); ?>


    <div class="full-width">

        

        <div class="center-form">

                <div class="row">

                    <p>Preencha abaixo o seguinte campo com o endereço de e-mail com que criou a sua conta.</p>

                    <?php echo $form_pw->labelEx($forgot_pw,'email'); ?>

                    <?php echo $form_pw->textField($forgot_pw,'email', array('tabindex'=>1)); ?>

                    <div class="errorMessageContainer"><?php echo $form_pw->error($forgot_pw,'email'); ?></div>

<p>Ao clicar no botão <em>Quero recuperar a minha password</em>, receberá um link no e-mail que deverá clicar para que lhe seja gerada uma nova password.</p>

                </div>

        </div>

        

        <div class="cboth"></div>

        

    </div><!-- .full-width -->

    

    <div class="fright">

        <input type="hidden" name="recoverPassword" />

        <?php echo CHtml::submitButton('Quero recuperar a minha password!'); ?>

        <a href="#cancel" class="cancel-button">Cancelar</a>

    </div>

    

    <div class="cboth"></div>

    

    <?php $this->endWidget(); ?>

Any ideas?

Is your Yii framework version 1.1.11 or higher?

Yes, I’m using the last one, v1.1.14.

Just to check, have you confirmed that it works if you disable client and ajax validation? I can’t see anywhere in the code where you’re assigning the data from the form to the model.

Yes, I’m totally sure. It sends through post, and does what is expected, send the recovery email with link.

When using AJAX and client-side validation it does return this JSON (with errors):


{"Player_firstname":["Primeiro Nome \u00e9 um campo de preenchimento obrigat\u00f3rio"],"Player_lastname":["\u00daltimo nome \u00e9 um campo de preenchimento obrigat\u00f3rio"],"Player_password":["Password \u00e9 um campo de preenchimento obrigat\u00f3rio"],"Player_email":["J\u00e1 existe um utilizador com esse endere\u00e7o de e-mail"]}

because in the rules( ) the first two rules are specified in general not for particular scenario so the validation takes these rules in all scenario so you have to change the scenario for that rules accordingly. this is what the problem not the version problem…

Probably you’ve not seen the entire rule, I’m making an exception at the end:


                        array(

'firstname, lastname, password',

'required',

'message'=>'{attribute} é um campo de preenchimento obrigatório',

'except'=>'forgot_password'),

oh sorry im on mobile so the opera browser shows the half code so that I think u forget to write some exceptions or scenario

No problem :)

Any ideas?

print the scenario and check whether it shows the right scenario and try without ajax mode validation and check it works as expected and then try in ajax mode.