5 min read

Ajax based Yii login form

Ajax based Yii login form

Last modified

Ajax helps us creating fancy forms, Ajax based forms boost user experience. Yii framework provides ajax validation but at the end form is submitted without ajax and our page goes refreshed.

Yii form validation includes an hook afterValidate that runs after form validation completes. This is the point where we can check validation result and then submit form via ajax call if validation don’t have any errors.

Lets create an ajax based Yii login form.

/protected/views/site/login.php


<?php
/* @var $this SiteController */
/* @var $model LoginForm */
/* @var $form CActiveForm  */

$this->pageTitle = Yii::app()->name . ' - Login';
$this->breadcrumbs = array(
    'Login',
);
?>

<h1>Login</h1>

<p>Please fill out the following form with your login credentials:</p>

<div class="form">
    <?php
    $form = $this->beginWidget('CActiveForm', array(
        'id' => 'login-form',
        'enableClientValidation' => true,
        'clientOptions' => array(
            'validateOnSubmit' => true,
            'afterValidate' => 'js:function(form, data, hasError) {
                if (!hasError){
                    str = $("#login-form").serialize() + "&ajax=login-form";

                    $.ajax({
                        type: "POST",
                        url: "' . Yii::app()->createUrl('site/login') . '",
                        data: str,
                        dataType: "json",
                        beforeSend : function() {
                            $("#login").attr("disabled",true);
                        },
                        success: function(data, status) {
                            if(data.authenticated)
                            {
                                window.location = data.redirectUrl;
                            }
                            else
                            {
                                $.each(data, function(key, value) {
                                    var div = "#"+key+"_em_";
                                    $(div).text(value);
                                    $(div).show();
                                });
                                $("#login").attr("disabled",false);
                            }
                        },
                    });
                    return false;
                }
            }',
        ),
    ));
    ?>

    <p class="note">Fields with <span class="required">*</span> are required.</p>

    <div class="row">
        <?php echo $form->labelEx($model, 'username'); ?>
        <?php echo $form->textField($model, 'username'); ?>
        <?php echo $form->error($model, 'username'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model, 'password'); ?>
        <?php echo $form->passwordField($model, 'password'); ?>
        <?php echo $form->error($model, 'password'); ?>
    </div>

    <div class="row rememberMe">
        <?php echo $form->checkBox($model, 'rememberMe'); ?>
        <?php echo $form->label($model, 'rememberMe'); ?>
        <?php echo $form->error($model, 'rememberMe'); ?>
    </div>

    <div class="row buttons">
        <?php echo CHtml::submitButton('Login', array('id' => 'login')); ?>
    </div>

    <?php $this->endWidget(); ?>
</div><!-- form -->

actionlogin in protected/controllers/SiteController.php


     /**
     * Displays the login page
     */
    public function actionLogin()
    {
        $model = new LoginForm;

        // if it is ajax validation request
        if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form')
        {
            $errors = CActiveForm::validate($model);
            if ($errors != '[]')
            {
                echo $errors;
                Yii::app()->end();
            }
        }

        // collect user input data
        if (isset($_POST['LoginForm']))
        {
            $model->attributes = $_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if ($model->validate() && $model->login())
            {
                if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form')
                {
                    echo CJSON::encode(array(
                        'authenticated' => true,
                        'redirectUrl' => Yii::app()->user->returnUrl,
                        "param" => "Any additional param"
                    ));
                    Yii::app()->end();
                }
                $this->redirect(Yii::app()->user->returnUrl);
            }
        }
        // display the login form
        $this->render('login', array('model' => $model));
    }

Above code is easy and self explanatory, write below in comments if you find any difficulty.