Ajax Login form with validation errors inside jQuery modal dialog

You are viewing revision #6 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.

« previous (#5)next (#7) »

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'),  
  );
 }
       ...
}
3 0
9 followers
Viewed: 40 994 times
Version: Unknown (update)
Category: Tutorials
Written by: pravi
Last updated by: Maxxer
Created on: Sep 14, 2013
Last updated: 6 years ago
Update Article

Revisions

View all history