УрокPop-up логин при помощи javascript

Обычный логин занимает на сайте много места, а это может быть критично для некоторых сайтах. Так что сегодня я расскажу о том, как можно сделать симпатичный всплывающий логин.

Как это сделать в теории:

  • запихиваем блок логина в какой-нибудь div
  • скрываем этот div через css (display:none;)
  • создаём кнопку/ссылку с надписью ВХОД
  • вешаем скрипт, который при нажатии на кнопку ВХОД показывает/прячет div с блоком логина

А теперь к практике:

Напишем в template.php функцию, которая будет показывать анонимам кнопки ВХОД и РЕГИСТРАЦИЯ, а зарегистрированным - ПРОФИЛЬ и ВЫХОД (а заодно и блок логина обернём в div):

function custom_login()  {
 
  $output = '<div id = "custom_login">'; //оборачиваем наш код в дополнительный div
  global $user;
 
  if ($user->uid)  {
    //если пользователь авторизовался, то
    //выводим ссылку на его профиль и на выход
    $output .= l('Профиль','user/'.$user->uid);
    $output .= l('Выход','logout');
  }
  else {
    //если на сайте пользователь сидит в качестве анонима, то
    //выводим ссылку на вход на сайт и на регистрацию, при этом обернув
    //блок логина в дополнительный div
    $output .= l('Вход','user', array('attributes' => array('class' => 'login')));
    $output .= l('Регистрация','user/register');
 
    //функция module_invoke позволяет "выдирать" любую часть любого модуля
    $block = module_invoke('user', 'block', 'view', 0);
    $output .= '<div class = "login_block">'. $block['content'] .'</div>';
  }
 
  $output .= '</div>';
  return $output;
}

Далее эту функцию вставляем в нужное место в page.tpl.php:

  print custom_login();

Далее создаём пустой файл с расширением .js и пишем туда функцию, которая будет показывать и прятать блок логина при нажатии на кнопку ВХОД:

$(document).ready(function() {
  $('#custom_login a.login').click(function() {
    $('#custom_login .login_block').slideToggle(200);
    // return false для того, чтобы при клике на ВХОД
    // пользователь не перешёл на новую страницу
    return false;
  });
});

Кстати, если вы обратили внимание - ссылка ВХОД хоть и просто открывает блок входа без загрузки страницы, но ведёт всё равно на страницу /user (страницу логина). Это сделано для того, чтобы пользователи, не имеющие поддержку javascript'ов, смогли найти страницу логина (т.е. работа сайта не нарушится)

Далее подключаем этот файл к теме.

И немного css:

div#custom_login {
	position: absolute; /*или relative, смотря как будете использовать*/
	left: 20px;
	top: 50px;
}
 
div#custom_login a {
    color: black;
    padding: 10px;
    position: relative;
    z-index: 9999;
}
 
div#custom_login a:hover {
	background: white;
}
 
div#custom_login .login_block {
    background: none repeat scroll 0 0 white;
    border: 1px dashed;
    display: none;
    padding: 10px;
    position: absolute;
    top: 0;
}

У меня получилось вот так в обычном виде:
Логин
и вот так - при нажатии на кнопку ВХОД
Выпадающий блок логина

С css я не заморачивался, извините =) Поменять цвет и фон, я надеюсь, вы сможете сами.

В принципе тут можно закончить урок - моя миссия завершена - popup логин сделан и готов к использованию. Но, всё же из любви к прекрасному, я подскажу как его немного темизировать.

Для в template.php запишем следующие 2 функции:

function ИМЯТЕМЫ_theme(){
  return array(
    'user_login_block' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}
 
function ИМЯТЕМЫ_user_login_block($form) {
 
  unset($form['name']['#title']);
  unset($form['pass']['#title']);  
 
  $form['name']['#value'] = 'Имя пользователя';
  $form['name']['#attributes'] = array(
	'onBlur'=> "if (this.value.length == 0) {this.value='{$form['name']['#value']}'}",
	'onFocus'=> "if (this.value== '{$form['name']['#value']}') {this.value=''}"
  ); 
  $form['submit']['#value'] = 'Вход';
 
  return drupal_render($form);
}

В итоге получается такой блок:
login2_0.png

Теперь с помощью css можно привести блок к более симпатичному виду. Однако, это уже остаётся на самостоятельную работу по своему вкусу =)

Комментарии

Аватар пользователя Graker
Graker написал:

Как раз недавно про это писал :)

На мой взгляд, сокрытие формы логина через CSS не совсем верно, так как тогда граждане с отключенным JS (e.g. обладатели не очень новых мобильников) будут вынуждены переходить на страницу /user для входа, что еще менее удобно, чем оригинальный большой блок логина. Лучше всего добавить .hide() в JS.

29.12.2010 20:16
Аватар пользователя Spleshka
Spleshka написал:

да, но тогда внешняя красота сайта может быть нарушена торчащим посреди страницы блоком входа :) Хорошо, если блок никому не мешает - тогда ваш вариант работает. Но если блок перекрывает контент - то тут уже лучше через css, на мой взгляд

30.12.2010 01:10
Аватар пользователя Rostislav
Rostislav написал:

Расширенный вариант выпадалок с формами и прочих popup-ов. Подключаем модуль jquery_ui. Подключаем свой модуль из 5-ти строк кода (на hook_init вешаем функцию jquery_ui_add(array('ui.draggable', 'ui.resizable', 'ui.dialog'));) В теме (page.tpl.php) вызываем js-функцию dialog(), в которую передаем название формы и drupal_get_form(form_id) (в нашем случае - user_login_block). Результат - полностью настраиваемая выпадалка-лайтбокс, содержащая форму (ноду, блок, видео, все, что угодно можно засунуть). Рабочий "корпоративный" вариант из последнего сделанного можно посмотреть здесь - http://www.talentory.com/eng/user/register - клик на ссылку View под Terms & conditions (откроется нода). Базовый вариант - http://jqueryui.com/demos/dialog/. Это я к тому, что если необходим функционал чуть более гибкий, то лучше юзать уже готовые jquery-расширения.

04.01.2011 03:05
Аватар пользователя Spleshka
Spleshka написал:

Спасибо, Ростислав! Безусловно, в некоторых случаях гораздо проще воспользоваться готовыми вариантами. Но сайт с небольшим уклоном в самоделки, чтобы понимать "как оно там вертится-то". Именно поэтому я предлагаю всё сделать самим =)

04.01.2011 04:53
Аватар пользователя AK47
AK47 написал:

SplasH привет :)
А если есть модуль формы отправки, самая простая, к примеру:

function form_menu(){

$items['form'] = array(
'title' => 'Отправить',
'description' => 'Отправить',
'page callback' => 'form_page',
'access arguments' => array('access content'),
'type' => MENU_SUGGESTED_ITEM,
);

return $items;
}

function form_page() {

$content = drupal_get_form('form_page_order');
return $content;
}

function form_page_order($form_state) {

$form['name']['fio'] = array(
'#type'=> 'textfield',
'#title'=> t('Ваше имя'),
'#default_value'=> $fio,
'#required'=> TRUE,

$form['submit'] = array(
'#type' => 'submit',
'#name' => 'sendMail',
'#id' => 'sbm_button',
'#value' => t('Submit'),
);

return $form;
}

Как форму можно загрузить в всплывающем окне ? Подскажи пожалуйста

11.01.2011 13:00
Аватар пользователя Spleshka
Spleshka написал:

ну оберни форму в див:

function form_page_order($form_state) {
 
   $form['#preffix'] = '<div id = "popup_form">';
   $form['#suffix'] = '</div>';
 
   $form['name']['fio'] = array(
	'#type'=> 'textfield',
	'#title'=> t('Ваше имя'),
	'#default_value'=> $fio,
	'#required'=> TRUE,
 
   $form['submit'] = array(
	'#type' => 'submit',
	'#name' => 'sendMail',
	'#id'  => 'sbm_button',
	'#value' => t('Submit'),
	);
 
   return $form;	
}

После этого повесь на клик какой-то кнопки/ссылки, чтобы показывало и скрывало твою форму:

$(document).ready(function() {
   //#button - это id кнопки, на которую нажимаем. Можно писать сюда что угодно
   $('#button').click(function() { 
      $('#popup_form').slideToggle();
   });
});
11.01.2011 14:15
Аватар пользователя AK47
AK47 написал:

Спасибо огромное, логику понял :)

11.01.2011 14:22
Аватар пользователя Тайный поклонник
Тайный поклонник написал:

Спасибо Жека) У меня тоже есть пара вопросов:
1. Сделал раскрывающимся стандартный блок входа. Но каждый раз когда авторизуюсь через него у меня все стопорится и белый экран..

Если нажать после этого Ф5 страница загрузится - и я уже авторизован.. Хрень какая-то.

2. Как сделать на седьмом осле, чтобы блок который мы раскрываем был поверх всего остального? А то он у меня под сайдбаром прячется..

@Graker
Вход и регистрацию можно продублировать в футере. Как на хабре.

13.01.2011 18:00
Аватар пользователя Spleshka
Spleshka написал:

1. Скорее всего надо поменять кодировку в template.php на UTF8 без BOM
2. Пропиши блоку, который должен раскрываться поверх остального в css:

   position: relative /* или absolute */  
   z-index: 9999;

А с логином в футере я подумаю :) Спасибо :)

14.01.2011 03:44
Аватар пользователя Nareg
Nareg написал:

Скажите пожалуйся, а можно ли как-то выводить это меню при наведении на ссылку из Primary links?

Заранее спасибо

26.01.2011 22:08
Аватар пользователя Spleshka
Spleshka написал:

можно) Самый простой вариант - посмотреть код у тэга li этого пункта меню, и повесить на него обработчик событий в скрипте.
Например, если бы я хотел повесить выскакивающий логин на пункт меню "Задать вопрос", то мой javascript файлик содержал бы:

$(document).ready(function() {
  $('#primary_links li.menu-747').click(function() {
    $('#login_block').slideToggle(200);
    return false;
  });
});
26.01.2011 23:24
Аватар пользователя Nareg
Nareg написал:

Ничего не получается( у меня у всех пунктов меню стоит leaf.
а не menu-номер( Я где-то что-то неправильно сделал или не там ищу?

27.01.2011 00:58
Аватар пользователя Spleshka
Spleshka написал:

Выведите это меню через page.tpl.php таким же образом:

<?php if (isset($primary_links)): echo theme('links', $primary_links); endif; ?>
27.01.2011 01:43
Аватар пользователя Тайный поклонник
Тайный поклонник написал:

а форму регистрации как вывести можно?

17.03.2011 11:58
Аватар пользователя Spleshka
Spleshka написал:
  $block = module_invoke('user', 'block', 'view', 0);
  echo $block['content'];
17.03.2011 16:50
Аватар пользователя Eventus
Eventus написал:

Это форма логина. Присоединяюсь к вопросу по поводу регистрации...

23.10.2011 19:31
Аватар пользователя Spleshka
Spleshka написал:
drupal_get_form('user_register_form');
23.10.2011 22:40
Аватар пользователя киска
киска написал:

тупоо:DEVIL::DEVIL:а смайлы класссс

24.06.2011 17:25
Аватар пользователя VVS
VVS написал:

Почему то слетал tabindex, пришлось поправить код:

  $form['name']['#attributes'] = array(
	'onBlur'=> "if (this.value.length == 0) {this.value='{$form['name']['#value']}'}",
	'onFocus'=> "if (this.value== '{$form['name']['#value']}') {this.value=''}",
	'tabindex' => "1"
  );
25.07.2011 16:51
Аватар пользователя VVS
VVS написал:

Как сделать чтобы этот блок не всплывал на страницах /user*
А то это выглядит ужасно!

03.08.2011 12:54
Аватар пользователя VVS
VVS написал:

Решил так:

function phptemplate_login($uri) {
    if (($uri != '/user/register') && ($uri != '/user/login') && ($uri != '/user') && ($uri != '/user/password')) {
      $uri_usr = TRUE;
    }
    $message = '<div id = "login">';
    global $user;
    if (!$user->uid) {
      $message .= '<ul class="user_image menu">
                  <li>'.l(t('Login'),'user/login', array('attributes' => array('rel'=>'nofollow', 'class' => ($uri_usr ? 'login' : '').' menu')) ).'</li>
                  <li>'.l(t('Registration'), 'user/register', array('attributes' => array('rel'=>'nofollow', 'class' => 'menu')) ).'</li>
                </ul>';
      if ($uri_usr) {
        //функция module_invoke позволяет "выдирать" любую часть любого модуля
        $block = module_invoke('user', 'block', 'view', 0);
        $message .= '<div class = "login_block">'. $block['content'] .'</div>';
      }
    } else {
      $message .= '<ul class="user_image menu">
                  <li>'.l($user->name, 'user/'.$user->uid, array('attributes' => array('class' => 'menu'))).'</li>
                  <li>'.l(t('Log out'), 'logout', array('attributes' => array('class' => 'menu'))).'</li>
                </ul>';
    }
    $message .= '</div>';
    return $message;
}

Только для uri не равным /user*
1. Добавляю класс (чтобы не сработал js)
2. Вставляю блок

03.08.2011 19:54
Аватар пользователя joker
joker написал:

Не совсем понятно где создаётся файл js, как он называется и как его подключить. Поясните пожалуйста.

23.08.2011 21:08
Аватар пользователя Eventus
Eventus написал:

Спасибо. Правда для 7-о друпала помучался.

  (function($){ $(document).ready(function() {   
    $('#custom_login a.login').click(function() {
    $('#custom_login .login_block').slideToggle(200);
    return false;
	})});
   })(jQuery);
23.10.2011 17:59
Аватар пользователя Liqor
Liqor написал:

Что то немогу никак заставить под 7 работать, подскажите в чём может быть загвоздка, такое впечатление что он куда то не туда выводит, всплывающее окно, при нажатии на кнопку ничего не происходит

22.02.2012 19:02
Аватар пользователя Spleshka
Spleshka написал:

А блок с логином на странице присутствует?

22.02.2012 22:44
Аватар пользователя gnom22
gnom22 написал:

Уже второй раз перечитываю ваш урок, все описанное выше получается, но вот никак не получается с Pop-up javascript окном, как заставить работать все это на drupal 7, пожалуйста! помогите разобраться

05.03.2012 18:45
Аватар пользователя Forz44
Forz44 написал:

Здравствуйте. Все сделал по уроку, Но! не работает. при нажатии на кнопку вход выводит ошибку, а при нажатии на кнопку регистрации перекидывает на стандартную регистрацию

06.03.2012 00:17
Аватар пользователя Spleshka
Spleshka написал:

Какую ошибку выдаёт при нажатии на вход?

06.03.2012 13:34
Аватар пользователя letjeng
letjeng написал:

на Drupal 5.9 ошибку выдаёт:
warning: preg_match() expects parameter 2 to be string, array given in /home/admin/domains/cliga.ru/public_html/includes/bootstrap.inc on line 670.

12.09.2012 10:21
Аватар пользователя letjeng
letjeng написал:

ошибку исправил с помощью http://www.drupal.ru/node/35647
но попап не работает, перекидывает на стандартную регистрацию

12.09.2012 11:40
Аватар пользователя letjeng
letjeng написал:

Спасибо за оперативную помощь, после вашего ответа всё сразу встало на свои места, такого подробного ответа давно не получал...)))

21.09.2012 10:55
Аватар пользователя Мота
Мота написал:

Почему то не выводиться блок входа... пересылает на страницу /user или /user

30.10.2012 19:46
Аватар пользователя Spleshka
Spleshka написал:

Если переадресовывает на другую страницу, значит, скрипт не отрабатывает. Это возможно по разным причинам. Наиболее вероятная - вы используете Drupal 7, а статья писалась под Drupal 6. Для того, чтобы скрипт отработал в семерке, он должен быть таким:

(function($) {
 
  Drupal.behaviors.myScript = {
    attach:function (context, settings) {
 
      $('#custom_login a.login', context).click(function(e) {
        $('#custom_login .login_block', context).slideToggle(200);
        e.preventDefault();
      });
 
    }
  }
 
})(jQuery);

И ещё не забудьте убедиться, что файл подключен к странице.

31.10.2012 22:35
Аватар пользователя Mota
Mota написал:

а теперь Fatal error: [] operator not supported for strings in /home/everho/public_html/avtobelor.ru/includes/common.inc on line 2358 в нем находиться
$options['attributes']['class'][] = 'active';

31.10.2012 23:26
Аватар пользователя mota
mota написал:

Прошу прощения разобрался c ошибкой, но все же скрипт, не работает(( да он подключен scripts[] = js/theme.js таким способом. и при щелчке а вход он открывается /user но не блок входа может долны иметься какие нибудь дополнительные скрипты для 7ки?

31.10.2012 23:56
Аватар пользователя Арсений
Арсений написал:

попытался прописать
.login_block {
padding: 150px 140px 67px;
} и увидел что сам блок он выводит но неправильно и боксы отсутствуют там... помогите почему так(

14.11.2012 18:21
Аватар пользователя oleg.ch
oleg.ch написал:

для корректной работы функции l() строчку :"$output .= l('Вход','user', array('attributes' => array('class' => 'login')));" нужно записывать как : "$output .= l('Вход','user', array('attributes' => array('class' =>array('login'))));"

28.11.2013 10:59

Комментировать