I use Ctools Modal to show the login form to users in an overlay. If a user enters right data then he is logged in and the page is refreshed.

The code:

function login_overlay_menu() {
  $items['login-overlay'] = array(
    'title' => t('Sign in'),
    'page callback' => 'login_overlay_callback',
    'page arguments' => array(),
    'type' => MENU_CALLBACK,
    'access callback' => TRUE,
  return $items;

function login_overlay_callback($js = TRUE){
    $form_state = array(
      'ajax' => TRUE,
    $output = ctools_modal_form_wrapper('login_overlay_form', $form_state);
    if (isset($_GET['destination'])) {
        $output[] = login_overlay_redirect($_GET['destination']);
    else {
        $output[] = ctools_ajax_command_reload();
    print ajax_render($output);

function login_overlay_redirect($path) {
  global $user;      
  if (isset($languages[$user->language])) {
    $options = array('language' => $languages[$user->language]);
  return ctools_ajax_command_redirect($path, 0, $options);

The Catch:

It works well for right data entered at first attempt. However, if a validation fails, then the form is rebuild inside the overlay. and then if the user submits the form, he is logged in but the page is not refreshed (which is very important).

When I debugged the JS code I found that the value of Drupal.settings.ajaxPageState.js changing is the only difference before and after the validation fail.

Before: it is an object containing list of all js files loaded for that page. After: it is an empty array. (Array[0]).

THE QUESTION: I am not even sure if this is what causing the error. However if it is, then what may be causing this to happen? OR if not then what may be causing the page refresh to fail?

  • Have you written any rule to the redirect after the login? If not try to write a rule with the rule module using as a condition "user log in (aware of modal windows)". Let me know if it helps.
    – Gianni
    Commented Mar 13, 2014 at 10:06
  • I want a solution for the code I have written above without writing a redirect rule because the code above breaks the JS on my site & I want to fix it. I want a solution which will not overwrite the value of Drupal.settings.ajaxPageState.js to an empty array. Thanks for suggestion anyway.
    – kmdhrm
    Commented Mar 13, 2014 at 11:31
  • What about debugging it with watchdog? Checking out where it goes in and where not and then taking it from there. I think that the array should be empty. As far as I know the form created once and then if it is cached the js and css are not included. What about any js file that you might need and is wrongly included? Can you try without caching? In the case you are not caching the js array should not be empty. If the form works then it means that a js file is #attached to the form but added with drupal_add_js. Commented Oct 14, 2015 at 14:11
  • I have a similar issue. The redirect doesnt work on first time. But works fine the second time I hit the login button. How did you solved this ? This is the code I used ctools_include('ajax'); ctools_add_js('ajax-responder'); $commands[] = ctools_ajax_command_redirect($path); print ajax_render($commands); drupal_exit();
    – mjs
    Commented May 2, 2016 at 7:31
  • Why redirects (login_overlay_redirect and ctools_ajax_command_reload) are in same response with login_overlay_form displayed in modal? This means automatic page refresh after loading the modal. I think redirecting/refreshing should be as a result of submit handler for login_overlay_form.
    – quex
    Commented Jun 29, 2018 at 20:28

2 Answers 2


You can use this hook:

* Implements hook_user_login().
function my_module_user_login(&$edit, $account) {
 // $edit is empty with one time login
 if (!empty($edit)) {
   $_GET['destination'] = 'some-url';
 // Or the form id is the password reset form
 if ($_POST['form_id'] != 'user_pass_reset') {
  $_GET['destination'] = 'some-url';

In case anyone comes here looking for an answer after all this time, I believe the issue was that the JS files were not being correctly attached to the form.

When a cached form is reloaded (which happens after a validation failure) it does not go through all the processing that created it. Any attached files MUST be added using the '#attached' key. https://api.drupal.org/api/drupal/developer%21topics%21forms_api_reference.html/7.x#attached

Eg. from the ctools documentation:

$form['#attached']['js'] = array(ctools_attach_js('auto-submit'));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.