Login

Hide and Show the Login Block

A member of the Western Massachusetts Drupal Users Group posed the question, 'what techniques do you use to hide or display a login block?'  As this is a feature that gets request with some regularity, I started playing around with a jQuery solution.  You can see it in action by pressing the login link in the upper right corner of this site, just under the primary links.

Here's how I did it.

First, I created a file called login.js that contained this code:

Drupal.behaviors.loginPopup = function(context){
 
$('body.not-logged-in a.popLogin', context).click(loginPopup);
$('#login-close', context).click(loginClose)
   
function loginPopup(){
  $('#popup').show('slow');
  $('a.popLogin', context).click(loginClose)
return false;
}
   
function loginClose(){
  $('a.popLogin').unbind('click', loginClose);
  $('#popup').hide('slow');
}
};

This toggles block visibility.  Also, it toggles which function is called when the login/logout link is pressed.  When you login, the link click event will call the function loginPopup().  That function, along with allowing the login block to be shown, changes the login link click event function to loginClose().  This allows you to close the block by clicking the login link again.  Click the login link again, and the block becomes hidden and the login link click event unbinds the call to loginClose().  You have to unbind it, else if the user decide to login and clicks the link, loginClose() gets called instead of loginPopup().

Next, I added a region in the theme's .info file called login_popup along with a call to load the login.js file

regions[login_popup] = Login Popup
scripts[] = login.js

Then, I made sure the page.tpl.php and page-front.tpl.php body tag included the $body_classes.  Note in the jQuery code uses this to verify a not-logged-in condition.

<body class="<?php print $body_classes; ?>">

Right under the body tag on the pages, add this.  It prints the region login_popup I added in the .info file.  It also identifies the <div> as 'popup' which will be used by css.

<div id="popup"><?php print $login_popup; ?></div>

In order to display the login/logout link, this was added beneath the primary links,

<div id="login">
<!-- login link start -->
<?php print $pop_login; ?>
<!-- login link end -->

Now, in the template.php file this was added to create the login/logout link that appears when you print the $pop_login variable

function <yourthemename>_preprocess_page(&$variables) {
  if ($variables['logged_in']){
    $variables['pop_login'] = '<a href="'.url('logout').'" class="popLogin">Log out</a>';
  }else{
    $variables['pop_login'] = l(t('Login'), 'user/login' , array('attributes' => array('class' =>'popLogin')));
  }
}

Style it a bit

#login-close {
  float:right;
  padding:0 10px 0 0;
}
#popup {
  position:absolute;
  top:60px;
  left:775px;
  width:300px;
  z-index:100;
  background-color:#FFFde8;
  display:none;
}

In my case, I added a block-user-0.tpl.php file so I could add a CLOSE link to the login block.  The code in the block:

<div id="login-close"><?php print '<a href=# class="loginCloseBlock">close</a>'; ?></div>
<?php print $block->content ?>

Almost there.  Now, flush the cache.  If you don't have the admin-menu module installed, another way to do this via admin/settings/performance and press the Clear cached data button.

Finally, I assigned the User Login block to the Login Popup region created in the .info file.

So there you have a solution for hiding and showing a login block.


UPDATE:

Since writing the post on hiding and showing the login block, I've done some work on the site's theme and the on the jQuery code.  The basic info applies, but I found that this jQuery code seems to work more consistently across browsers, particularly IE.  Here it is:

function loginPopup(){
       
    $('#popup').toggle('slow');
   
    if($('a.popLogin').text() == 'Cancel'){
      $('a.popLogin').text('Login');
    }else{
      $('a.popLogin').text('Cancel');
      $('#popup').css('display', 'inline');
    }

    if($('a.popLogin').text() == 'Login'){
      $('#messages').css('display', 'none');
    }

        return false;
    }

Instead of binding a click event as in the earlier version, this time it's simply toggling it's state whether it's displayed or not.

Post new comment

Leave a comment