enableAjaxValidation submit activeform before click submit

Hi! It’s famous problem.

I found many information in other sites, blogs and forums, but i don’t can fix this problem in my situation… =( Please help someone!

I use basic version. And i create functionality for registration new user (in base version of this is not).

My form in view:




<?php $form = ActiveForm::begin([

    'id' => 'registration-form',

    'options' => ['class' => 'form-horizontal'],

    'enableAjaxValidation' => true,

    'fieldConfig' => [

  	'template' => "{label}\n<div class=\"col-lg-4\">{input}</div>\n<div class=\"col-lg-6\">{error}</div>",

      'labelOptions' => ['class' => 'col-lg-2 control-label'],

    ],

	]); ?>


  <?= $form->field($model, 'name')->textInput(['autofocus' => true]) ?>

  <?= $form->field($model, 'email')->textInput() ?>

  <?= $form->field($model, 'password')->passwordInput() ?>

  <?= $form->field($model, 'verifypassword')->passwordInput() ?>


  <div class="form-group">

    <div class="col-lg-offset-2 col-lg-10">

      <?= Html::submitButton('Registration', ['class' => 'btn btn-primary', 'name' => 'reg-button']) ?>

    </div>

  </div>


<?php ActiveForm::end(); ?>

My action:


public function actionRegistration()

  {

    if (Yii::$app->request->post())

    {

      $modeluser = Yii::$app->request->post()['RegistrationForm'];


      $newUser = new User();

      $newUser->loadDefaultValues();

      $newUser->name = $modeluser['name'];

      $newUser->email = $modeluser['email'];

      $newUser->password = md5($modeluser['password']);

      $newUser->save();


      if (Yii::$app->user->login(UserIdentity::findByEmail($modeluser['email'])))

      {

        return $this->goHome();

      }


      return $this->goBack();

    }


    $model = new RegistrationForm();


    if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()))

    {

      Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

      return \yii\widgets\ActiveForm::validate($model);

    }


    return $this->render('registration', ['model' => $model]);

  }

And my model:


public function rules()

  {

    return [

      [['name', 'email', 'password', 'verifypassword'], 'required'],

      ['name', 'filter', 'filter' => 'trim'],

      ['password', 'filter', 'filter' => 'trim'],

      ['email', 'email'],

      ['email', 'unique'],

      ['email', 'validateEmail'],

      ['password', 'string', 'length'=>[6]],

      ['verifypassword', 'compare', 'compareAttribute'=>'password', 'operator'=>'==='],

    ];

  }


public function validateEmail($attribute, $params)

{

      $this->addError($attribute, 'Email most be unique!');

}

In function validateEmail i deliberately add error to my form. And? When i fill ONLY!!! e-mail field and this data already exist in DB and i remove focus from this field, happen login user. Other field does not matter, because for login i need email and password. If disable option ‘enableAjaxValidation’ => true in form then don’t submit but and i don’t have checking by my condition!

WTF???

Boy oh boy…

Few things here:

  1. The block with isAjax check should go first - the first "if" block is executed every time and this is why login is called on field blur.

  2. Why do you assign every attribute by hand? $newUser->load() is for that.

  3. Why oh why do you use md5 for password hashing? It’s not secure anymore. There is example here how to do it properly.

  4. If you are not calling validate() directly check if save() returned true - otherwise what is the point of login if save() returned false?

Oh, sorry all! I’m stupid(

Just action is not corrected. It is necessary to do so:


public function actionRegistration()

  {

    $model = new RegistrationForm();


    if (Yii::$app->request->post())

    {


      if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()))

      {

         Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

         return \yii\widgets\ActiveForm::validate($model);

      }


      $modeluser = Yii::$app->request->post()['RegistrationForm'];

      $newUser = new User();

      $newUser->loadDefaultValues();

      $newUser->name = $modeluser['name'];

      $newUser->email = $modeluser['email'];

      $newUser->password = md5($modeluser['password']);

      $newUser->save();


      if (Yii::$app->user->login(UserIdentity::findByEmail($modeluser['email'])))

      {

        return $this->goHome();

      }


      return $this->goBack();

    }


    return $this->render('registration', ['model' => $model]);

  }

It’s all. Problem is resolved. This topic can be closed. But maybe is someone come in handy…

There are still some problems left untouched … :(

Bizley Thanks so much! I take into consideration all your comments!

softark I agree with you, just my post (07:36 PM) was written when i have not read post from the 07:34 PM of Bizley… Or you something else have in mind? ???

The points 2) to 4) look still unsolved.

And also I’m wondering about “validateEmail” method. If you wanted to customize the error message, you could do it by setting “message” property of “unique” validator.