Ajax Login form with validation errors inside jQuery modal dialog

10 followers

This wiki article has not been tagged with a corresponding Yii version yet.
Help us improve the wiki by updating the version information.

I would like to share my little experience with Yii to the community in the form of the below small wiki:

I will demonstrate the user login and logout functionality along with validation errors using aweswome Yiiframework. The blog demo supplied with the standard framework download, provides a simple user login/logout functionality to demonstrate the core framework features. We will add some Ajax functions to this to display login form inside a jQuery modal dialog box with login errors if any. I do make use of ajaxSubmitButton( inside CActiveForm) to add ajax code to the submit button, CJuiDialog for modal dialog box. I will also show you how to separate login action(actionLogin in SiteController) into a separate class file(getLogin) that extends CAction, and later use this class as an action dynamically inside any controller. I use a widget class(loginProvider) and its action(GetLogin) for this purpose. I will now show you what modifications need to be done to the demo application:

  • Create a file named loginProvider.php and place it inside the components directory.
<?php
 
class loginProvider  extends CWidget{
 
    public static function actions(){
        return array(
                   'GetLogin'=>'application.components.actions.getLogin',
        );
    }
 
    public function run(){
 
        $this->renderContent();
 
    }
 
    protected function renderContent(){
 
 echo '<span style="float:right;">';
 if(Yii::app()->user->isGuest){
            echo CHtml::link('Login', array('/site/login.GetLogin'), array('onclick'=>'$("#login-dialog").dialog("open"); return false;'));
     echo '</span>';
     $this->getController()->renderPartial('application.components.views.login',array('model'=>new LoginForm)); 
 }
 else      
     echo CHtml::link('Logout ('.Yii::app()->user->name.')', array('site/logout'), array('visible'=>!Yii::app()->user->isGuest));
 echo '</span>';
   }
 
}
  • Create a directory named actions inside components directory.

  • Create the action class with name getLogin.php and place it inside components/actions directory.

<?php
 
class getLogIn extends CAction{
 
      public function run() {
            if (!defined('CRYPT_BLOWFISH')||!CRYPT_BLOWFISH)
    throw new CHttpException(500,"This application requires that PHP was compiled with Blowfish support for crypt().");
 
     $model=new LoginForm;
 
     if (Yii::app()->request->isAjaxRequest){ 
           if (isset($_POST['LoginForm'])) {  
          $model->attributes=$_POST['LoginForm'];
 
          if ($model->validate() && $model->login()){
                $array = array("login" => "success");
                              Yii::app()->user->setFlash("success", "Successfully logged in.");
                              $json = json_encode($array);
                              echo $json;
         Yii::app()->end();
   }
   else{
         echo CActiveForm::validate($model);
                              Yii::app()->end();
          }
           } //POST
 
            }
      } 
 
}
  • Create a file named login.php and place it inside components/views with the following contents:
<?php $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
    'id'=>'login-dialog',
    'options'=>array(
        'title'=>'Login',
        'autoOpen'=>false,
    ),
));?>
 
 
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
 'id'=>'user_login_form',
 'enableAjaxValidation'=>false,
  'enableClientValidation'=>true,
                'method' => 'POST',
                'clientOptions'=>array(
                     'validateOnSubmit'=>true,
                     'validateOnChange'=>true,
                     'validateOnType'=>false,
  ),
)); ?>
<h1>
Login</h1>
<p>
Please fill out the following form with your login credentials:</p>
<p class="note">
Fields with <span class="required">*</span> are required.</p>
<div id="login-error-div" class="errorMessage" style="display: none;">
</div>
<div class="row">
  <?php echo $form->labelEx($model,'username'); ?>
  <?php echo $form->textField($model,'username',array("onfocus"=>"$('#login-error-div').hide();")); ?>
  <?php //echo $form->error($model,'username'); ?>
 </div>
<div class="row">
  <?php echo $form->labelEx($model,'password'); ?>
  <?php echo $form->passwordField($model,'password',array("onfocus"=>"$('#login-error-div').hide();")); ?>
  <?php //echo $form->error($model,'password'); ?>
  <p class="hint">
   Hint: You may login with <tt>demo/demo</tt>.
  </p>
</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 submit">
 
  <?php echo CHtml::ajaxSubmitButton(
                                'Sign In',
    array('/site/login.GetLogin'),
                                array(  
                'beforeSend' => 'function(){ 
                                             $("#login").attr("disabled",true);
            }',
                                        'complete' => 'function(){ 
                                             $("#user_login_form").each(function(){ this.reset();});
                                             $("#login").attr("disabled",false);
                                        }',
                   'success'=>'function(data){  
                                             var obj = jQuery.parseJSON(data); 
                                            // View login errors!
         // alert(data);
                                             if(obj.login == "success"){
                                         $("#user_login_form").html("<h4>
Login Successful! Please Wait...</h4>
");
                                         parent.location.href = "/";
                                      }
          else{
                                                $("#login-error-div").show();
                                                $("#login-error-div").html("Login failed! Try again.");$("#login-error-div").append("
");
                                             }
 
                                        }' 
    ),
                         array("id"=>"login","class" => "btn btn-primary")      
                ); ?>
 
 </div>
<?php $this->endWidget(); ?>
</div>
<!-- form -->
 
<?php $this->endWidget('zii.widgets.jui.CJuiDialog'); ?>
  • Go to the main layout(blog/protected/views/layouts/main.php) and apply the following changes in the menu:
<div id="mainmenu">
  <?php $this->widget('zii.widgets.CMenu',array(
   'items'=>array(
    array('label'=>'Home', 'url'=>array('post/index')),
    array('label'=>'About', 'url'=>array('site/page', 'view'=>'about')),
    array('label'=>'Contact', 'url'=>array('site/contact')),
 
    //array('label'=>'Login', 'url'=>array('site/login'), 'visible'=>Yii::app()->user->isGuest),
    //array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('site/logout'), 'visible'=>!Yii::app()->user->isGuest)
   ),
  )); ?>
  <?php $this->widget('loginProvider'); ?>
 </div>
<!-- mainmenu -->
  • Finally, Go to SiteController(/blog/protected/controllers/SiteController) and append 'login.' action inside actions() method. Now, the login action is accessed as '/site/login.GetLogin'
<?php
 
class SiteController extends Controller
{
   ...
public function actions()
 {
  return array(
   // captcha action renders the CAPTCHA image displayed on the contact page
   'captcha'=>array(
    'class'=>'CCaptchaAction',
    'backColor'=>0xFFFFFF,
   ),
   // page action renders "static" pages stored under 'protected/views/site/pages'
   // They can be accessed via: index.php?r=site/page&view=FileName
   'page'=>array(
    'class'=>'CViewAction',
   ),
   'login.' =>  array('class'=>'application.components.loginProvider'),  
  );
 }
       ...
}
  • References: (http://www.yiiframework.com/demos/blog/ "Yii Blog") [How to get definite widget in controller] (http://www.yiiframework.com/forum/index.php/topic/18197-how-to-get-definite-widget-in-controller/page__p__89729__hl__widget+a+action+provider+#entry89729 "How to get definite widget in controller")

Total 4 comments

#16204 report it
swampone at 2014/01/27 11:04pm
login form showing in regular static form once page is loaded

Im still struggling to get this working properly. The login form is showing up on the page once its loaded not inside the dialog box. I have narrowed the issue down to the success callback in the ajaxSubmit button on the login form. Once I remove it, form opens properly in dialog box.

'success'=>'function(data){  
                                             var obj = jQuery.parseJSON(data); 
                                            // View login errors!
                                            // alert(data);
                                             if(obj.login == "success"){
                                                $("#user_login_form").html("<h4>
                                                Login Successful! Please Wait...</h4>
                                                ");
                                                parent.location.href = "/";
                                            }
                                            else{
                                                $("#login-error-div").show();
                                                $("#login-error-div").html("Login failed! Try again.");$("#login-error-div").append("
                                                ");
                                             }
 
                                        }

Once i remove the above, it opens in dialog box

#16088 report it
pravi at 2014/01/18 01:27pm
@swampone

Please debug using firebug and find errors if any

#15837 report it
swampone at 2013/12/20 07:26pm
dialog not opening

For some reason, when i click the login link, the dialog doesn't open

#14883 report it
Rajith R at 2013/09/18 06:34am
@pravi

Good Work

Leave a comment

Please to leave your comment.

Write new article
  • Written by: pravi
  • Category: Tutorials
  • Yii Version: Not set (update)
  • Votes: +6
  • Viewed: 17,228 times
  • Created on: Sep 14, 2013
  • Last updated: Sep 14, 2013
  • Tags: ajax login