I am trying to create custom login form using Ctools modal window. There seems to be a problem upon submitting the correct username and password.

The page callback function is supposed to return a JSON of the ajax commands. Right now it is instead returning an AJAX error, with the response as the HTML text of the user profile page (eg. user/123). The return code is 200. Which seems to suggest that the function got redirected to the user page, which shouldn't happen for AJAX call. I might be wrong on this though.

I have used the same pattern for other forms, such as register form and reset password, which work fine. Anybody has any idea why this is happening? Thank you all.

Here are my codes:


$items['modal/user_login/%ctools_js'] = array(
    'file'=> 'popup_login.inc',
    'page callback' => 'my_module_user_login',
    'page arguments' => array(2),
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
$items['test_ctool_popup'] = array(
    'title' => "Test Login Popup Page",
    'page callback' => 'my_module_test_login_page',
    'access arguments' => array('access content'),
    'type' => MENU_NORMAL_ITEM,

page callback function: my_module_test_login_page

function my_module_test_login_page () {
        $link = ctools_modal_text_button(
            'Log in modal', 
            'Log in');
    } else {
        $link = 'user already logged in';

    return <<< HTML
    <div class="modal-link">$link</div>

modal callback function: my_module_user_login

function my_module_user_login ($js = null) {
    return drupal_get_form('my_module_user_login_form');
$form_state = array(
    'ajax' => TRUE,
    //'title' => t('Log In')
$output = ctools_modal_form_wrapper('my_module_user_login_form',$form_state);
if (!empty($form_state['ajax_commands'])) {
    $output = $form_state['ajax_commands'];
print ajax_render($output);

form function my_module_user_login_form

function my_module_user_login_form ($form, &$form_state) {
    $login_form = user_login($form, $form_state);
    $login_form['name']['#title'] = t('Email');
    $login_form['name']['#size'] = 25;
    $login_form['pass']['#size'] = 25;
    //$login_form['#validate'][] = '_ewp_property_user_login_form_validate';
    return $login_form;

submit function my_module_user_login_form_submit

function my_module_user_login_form_submit ($form, &$form_state) {
    user_login_submit ($form, $form_state);
    $commands = array();
    $commands[] = ctools_modal_command_dismiss(t('Log In Successful.'));
    $commands[] = ctools_ajax_command_reload();
    //$commands[] = ctools_ajax_command_redirect('modal/dismiss_modal/nojs');
    $form_state['ajax_commands'] = $commands; 

1 Answer 1


Turns out the offending part is not the logic, but the function name. The my_module_user_login_form function happens to be a invoke hook form, which interferes with the modal.

Changing the function name solved the problems.

  • Actually, it's my_module_user_login() to collide with hook_user_login(). Drupal doesn't use any hook_user_login_form().
    – apaderno
    Oct 28, 2015 at 6:05

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.