Creating a Modal Login widget using Yii-Bootstrap extension

Creating a Modal Login widget using Yii-Bootstrap extension

Last updated:

N.B.: This is a reminder for myself so I can look back and see how I did it, because it took a lot of time to get it going so I didn't want to lose it.

However, I must say that in the end I nearly always wind up using something simpler like a normal form instead of this modal login form thing.

It does look cool but sometimes I think simpler is better and as of this writing (Aug 2012) I don't think bootstrap is mature enough to provide a hassle free experience to all viewers, even with the responsive features. Making modals work responsively is, in my experience, a pita (for example see an example of fix for bootstrap on mobile devices) and I wouldn't try it unless the platform gets a little more mature.

/N.B.:

You could place this on your landing page:

(this is the login button that will trigger the modal)

<?php if (Yii::app()->user->isGuest): ?>
    <p><?php
    $this->widget('bootstrap.widgets.TbButton', array(
        'size' => 'large',
        'label' => 'login',
        'url' => '#login-modal',
        'htmlOptions' => array(
                        'data-toggle' => 'modal',
                        'onclick' => '$("#error-div").hide();$("#LoginForm_username").focus();'),
                         )
     );
?></p>

and this is the actual modal and form, along with alerts for error messages

<?php $this->beginWidget('bootstrap.widgets.TbModal', array(
                                            'id' => 'login-modal'
                                             )
          ); ?>
    <div class="modal-header">
        <a class="close" data-dismiss="modal">&times;</a>
        <h3>login</h3>
    </div>
    <div class="modal-body">
    <?php
        $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
            'id' => 'LoginForm',
            'htmlOptions' => array(
                'class' => 'well'),
            )
         );
?>
    <div id="error-div" class="alert alert-block alert-error" style="display:none;">
    </div>    
    <?php echo $form->textFieldRow($login_form_model, 'username', array(
                            'class' => 'span3'
                            )
                      ); ?>
    <?php echo $form->passwordFieldRow($login_form_model, 'password', array(
                             'class' => 'span3'
                             )
                      ); ?>
    <?php $this->widget('bootstrap.widgets.TbButton', array(
                                             'buttonType' => 'ajaxSubmit', 
                                             'icon' => 'ok', 
                                             'label' => 'Submit', 
                                             'ajaxOptions' => array(
                                                'success' => 
'function(data){
        var obj = $.parseJSON(data);
        if(obj.login=="success"){
            $("#login-modal").modal("hide");
            setTimeout(function(){location.reload(true);},400);
        }else{
            $("#error-div").show();
            $("#error-div").html("");
            if("LoginForm_password" in obj){
                $("#error-div").html(obj.LoginForm_password[0]+"<br />");
            }
            if("LoginForm_username" in obj){
                $("#error-div").append(obj.LoginForm_username[0]);
            }
        }
    }'),
));
    ?>
     <?php $this->endWidget(); ?>
     </div>
<?php $this->endWidget(); ?>

and, on your controller action that rendered that page, you would have this:

        if (isset($_POST['LoginForm'])) {
        $login_form_model->attributes = $_POST['LoginForm'];
        if ($login_form_model->validate() and $login_form_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($login_form_model);
            Yii::app()->end();
        }
    }

as for the LoginForm, I just used the default form that gii creates for me.