Trying to make login+restore password+signup in one view Yii2

I am learning Yii2 and now i am trying to do a page that provides login, restore password and signup. View renders, but after executing requests page reloads and nothing happens. Controller has a few actions:

public function actionLoad(){

    if(!Yii::$app->user->isGuest){
        return Yii::$app->response->redirect('/day');
    }

    $login_model = new LoginForm();
    $signup_model = new SignUpForm();
    $restore_model = new RestoreForm();

    return $this->render('login', compact(['login_model', 'signup_model', 'restore_model']));
}

public function actionLogin(){
    if ($login_model->load(Yii::$app->request->post())) {
        if($login_model->validateLogin()){
            Yii::$app->user->login($login_model->validateLogin(), 3600*24*30);
            return $this->refresh();
        }
    }
}

public function actionSignUp(){
    if ($signup_model->load(Yii::$app->request->post())) {
        if ($user = $signup_model->validateSignUp()) {
            if (Yii::$app->getUser()->login($user, 3600*24*30)) {
                return $this->refresh();
            }
        }
    }
}

public function actionRestore(){
    if ($restore_model->load(Yii::$app->request->post())) {
        $restore_model->validateRestore();
        return $this->refresh();
    }
}

view forms looks like this:

        <?php $form_signup = ActiveForm::begin([
                'options' => ['class'=>'form_signup'],
                'fieldConfig' => [
                        'inputOptions'=>['class'=>'form_input'],
                        'template'=>'{input}'
                ]
        ]); ?>
        <input id="form-token" type="hidden" name="<?=Yii::$app->request->csrfParam?>"
               value="<?=Yii::$app->request->csrfToken?>"/>
            <?= $form_signup->field($signup_model, 'username')->input('text', ['placeholder' => 'Username']) ?>
            <?= $form_signup->field($signup_model, 'email')->input('email', ['placeholder' => 'Email']) ?>
            <?= $form_signup->field($signup_model, 'password')->input('password', ['placeholder' => 'Password']) ?>
            <?= Html::submitButton('Sign Up', ['class' => 'btn']) ?>
        <?php ActiveForm::end(); ?>

If i move all from actions to the actionLoad, it all works, but i want an action for each operation. What should i do? P.S. if you have some advices for "best practices" - i would get it with thanks.

1 answer

  • answered 2018-05-16 06:14 Chux

    You are using ActiveForm widget. If you don't specify the action attribute, it will be the same action you that is rendering the current view (action load, I would assume from your code).

    So, actionLoad will execute again, and nothing will happen as that action doesn't do anything apart from rendering a view.

    Your problem is that you are using one single form for three different actions. You can:

    • Have as many forms as actions.
    • Have only one form and change the action attribute via javascript depending on what the user selects.