Tell me more ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I am trying to load a node edit form into a modal frame using Ctools. The following is the function I am using. So far the $op = 'view' part is working fine, but I cannot get the node edit form to load when $op = 'edit'. I have searched for the better part of the day, but I cant find anything about how to load node forms in a modal frame using Ctools in Drupal 7.

function namecards_modalframe_node($op, $nid, $js = FALSE) {
  $output = '';
  switch ($op) {
    case 'view':
      if ($js) {
        ctools_include('ajax');
        ctools_include('modal');
        $output .= theme('namecards_download_cvs_link', $nid);
        // Create table showing contact's information
        $table_structure = namecards_get_table_data($nid);
        $output .= theme('table', array('header' => $table_structure['header'], 'rows' => $table_structure['rows'], 'attributes' => $table_structure['attributes']));
        $output .= theme('namecards_download_cvs_link', $nid);
        // Add close button to bottom of page.
        return ctools_modal_render(t('Details'), $output);;
      }
      else {
        $output .= theme('namecards_download_cvs_link', $nid);
        // Create table showing contact's information
        $table_structure = namecards_get_table_data($nid);
        $output .= theme('table', array('header' => $table_structure['header'], 'rows' => $table_structure['rows'], 'attributes' => $table_structure['attributes']));
        $output .= theme('namecards_download_cvs_link', $nid);
        // Add close button to bottom of page.
        $form = drupal_get_form('namecards_modalframe_close_button_form');
        $output .= drupal_render($form);
        return $output;
      }
      break;

    case 'edit':
      // Include 'node.pages.inc' in order to be able to use node functions
      module_load_include('inc', 'node', 'node.pages');
      //      form_load_include($form_state, 'inc', 'node', 'node.pages');
      $node = node_load($nid);

      if ($js) {
        ctools_include('ajax');
        ctools_include('modal');
        $form_state = array(
            'ajax' => $js,
            'title' => t('Edit'),
            'build_info' => array(
                'args' => array(
                    'node' => $node,
                ),
            ),
        );
        return ctools_modal_form_wrapper('namecards_some_form', $form_state);
      }
      else {
        $node_edit_form = node_page_edit($node);
        return drupal_render($node_edit_form);
      }
      break;
  }
}

Each time I click on the link, the modal frame opens but it is blank (accept for the loading animation). At the same time a js alert box appears containing the following:

An AJAX HTTP error occurred.
HTTP Result Code: 200
Debugging information follows.
Path: /namecards/modalframe/node/edit/4585/ajax
StatusText: OK
ResponseText:
drupal7
@import url("http://drupal7/modules/system/system.base.css?lylwzg");
@import url("http://drupal7/modules/system/system.menus.css?lylwzg");
@import url("http://drupal7/modules/system/system.messages.css?lylwzg");
@import url("http://drupal7/modules/system/system.theme.css?lylwzg");
@import url("http://drupal7/misc/vertical-tabs.css?lylwzg");
@import url("http://drupal7/modules/contextual/contextual.css?lylwzg");
@import url("http://drupal7/modules/comment/comment.css?lylwzg");
@import url("http://drupal7/modules/field/theme/field.css?lylwzg");
@import url("http://drupal7/sites/all/modules/namecards/namecards.css?lylwzg");
@import url("http://drupal7/modules/node/node.css?lylwzg");
@import url("http://drupal7/modules/search/search.css?lylwzg");
@import url("http://drupal7/modules/user/user.css?lylwzg");
@import url("http://drupal7/sites/all/modules/views/css/views.css?lylwzg");
@import url("http://drupal7/sites/all/modules/ctools/css/ctools.css?lylwzg");
@import url("http://drupal7/modules/shortcut/shortcut.css?lylwzg");
@import url("http://drupal7/modules/toolbar/toolbar.css?lylwzg");
@import url("http://drupal7/themes/garland/style.css?lylwzg");
@import url("http://drupal7/themes/garland/print.css?lylwzg");
Skip to main content
Home
Hello drupal7
Log out
Administrative toolbarDashboard (View and customize your dashboard.)
Content (Administer content and comments.)
Structure (Administer blocks, content types, menus, etc.)
Appearance (Select and configure your themes.)
People (Manage user accounts, roles, and permissions.)
Modules (Extend site functionality.)
Configuration (Administer settings.)
Reports (View reports, updates, and errors.)
Advanced help
Help (Reference for usage, configuration, and modules.)
Hide shortcuts
Add content
Find content
Performance
Edit shortcuts
drupal7
Main menuBooks
Home
Namecards
Secondary menuMy account
Log out
Configure block
Search form
Search
Navigation
List links
Edit menu
Configure block
Add content
Development
List links
Edit menu
Configure block
Devel settings
Empty cache
Entity info
Execute PHP Code
Field info
Function reference
Hook_elements()
Menu item
PHPinfo()
Rebuild menus
Reinstall modules
Run cron
Session viewer
Theme registry
Variable editor
You are hereHome
Configure block
Powered by Drupal

Would appreciate any suggestions on how to get this working.

share|improve this question
 
I worked out how to do it. I finally can across an answer with an example in the issues queue of the Ctools module. Anyone else struggling with this should check out the discussion here. –  Benjen Jan 30 '12 at 14:01
3  
If you figured out the solution, please post it as an answer and mark it accepted for future visitors to benefit –  Laxman13 Feb 23 '12 at 19:01
 
Am also getting a same error using in ctools_modal_text_button in custom module for viewing the user profile edit page –  user9175 Aug 9 '12 at 6:57

2 Answers

I used the following code in a resent project, hope this helps:

Add this code to custom_module.module:

/**
 * Implementation of hook_menu().
 */
function custom_module_menu() {
  $items = array();

  // @see node_menu in node.module:
  // @todo Remove this loop when we have a 'description callback' property.
  // Reset internal static cache of _node_types_build(), forces to rebuild the
  // node type information.
  node_type_cache_reset();
  foreach (node_type_get_types() as $type) {
    $type_url_str = str_replace('_', '-', $type->type);
    $items['modal/node/add/' . $type_url_str . '/%ctools_js/%'] = array(
      'title' => $type->name,
      'title callback' => 'check_plain',
      'page callback' => 'custom_module_node_page_add',
      'page arguments' => array($type->type, 4, 5),
      'access callback' => 'node_access',
      'access arguments' => array('create', $type->type),
      'description' => $type->description,
      'file' => 'custom_module.pages.inc',
    );
  }
  $items['modal/node/%node/edit/%ctools_js/%'] = array(
    'title' => 'Edit',
    'page callback' => 'custom_module_node_page_edit',
    'page arguments' => array(2, 4, 5),
    'access callback' => 'node_access',
    'access arguments' => array('update', 2),
    'weight' => 0,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
    'file' => 'custom_module.pages.inc',
  );


  return $items;
}

add the following to custom_module.pages.inc:

 /**
  * Page Callback - Modal: Add Node
  */
function custom_module_node_page_add($type, $js, $force_page_reload = FALSE) {
  // Fall back if $js is not set.
  if (!$js) {
    return drupal_goto('node/add/' . str_replace('_', '-', $type));
  }

  // Get node form defaults.
  global $user;
  $types = node_type_get_types();
  $node = (object) array(
    'uid' => $user->uid,
    'name' => (isset($user->name) ? $user->name : ''),
    'type' => $type,
    'language' => LANGUAGE_NONE
  );

  $title = t('Create @name', array('@name' => $types[$type]->name));

  custom_module_node_form($node, $title, $force_page_reload);
}

/**
 * Page Callback - Modal: Edit Node
 */
function custom_module_node_page_edit($node, $js, $force_page_reload = FALSE) {
  // Fall back if $js is not set.
  if (!$js) {
    return drupal_goto('node/' . $node->nid . '/edit/');
  }

  $type_name = node_type_get_name($node);
  $title = t('<em>Edit @type</em> @title', array('@type' => $type_name, '@title' => $node->title));

  custom_module_node_form($node, $title, $force_page_reload);
}


/**
 * Build the Modal Form.
 *
 * @param object $node
 *   The node Object in edit case. In Add case it's only a pseudo node object.
 * @param string $title
 *   The Modal Popup Title.
 * @param boolean $force_page_reload 
 *   Indicates if page should be reloaded after form submission.
 */
function custom_module_node_form($node, $title, $force_page_reload = FALSE) {
  $commands = array();

  ctools_include('node.pages', 'node', '');
  ctools_include('modal');
  ctools_include('ajax');

  $form_state = array(
    'title' => $title,
    'ajax'  => TRUE,
    'build_info' => array(
      'args'  => array($node),
    ),
  );

  $commands = ctools_modal_form_wrapper($node->type . '_node_form', $form_state);

  if (!empty($form_state['executed']) && empty($form_state['rebuild'])) {

      // overwrite commands.
      $commands = array();

      ctools_add_js('ajax-responder');
      $commands[] = ctools_modal_command_dismiss();
      // if (t('Delete') == $form_state['values']['op']) {
      //   $commands[] = ctools_ajax_command_redirect('modal/node/' . $node->nid . '/delete/ajax/reload');
      // }
      // else 
      if ($force_page_reload) {
        $commands[] = ctools_ajax_command_reload();
      }
  }

  // add CSS class to Modal-Frame
  $commands[] = ajax_command_invoke('#modalContent', 'addClass', array('custom-module-node', 'custom-module-node-form'));

  print ajax_render($commands);
  exit;
}
share|improve this answer
 
This solution looks great, but I can't get it working. Is that all I need to do. Make a new module and put this 2 files in there. (and my module.info off course) Modal forms is enabled, but when I go to an node/add/mytype page nothing happens, the page opens like before, not in a modal. The same behaviour of node/%/edit, no modal. I also tried modal/node/add/, but this page could not be found. This solution should redirect all node/add pages to a modal, right? –  user12011 Dec 11 '12 at 14:41

Here's how to make a module from Lars Schroeter code (below).

Put both files (custom_module.module & custom_module.pages.inc) in a folder named custom_module. Of course, both files must begin with <?php. Then create the required custom_module.info file. Something like this will do.

name = "Node edit modal"
description = "How to load a node edit form using Ctools module in Drupal 7."
package = "Modal Gallery"
core = 7.x
files[] = custom_module.module

dependencies[] = "ctools"

Put the .info file in the custom_module folder. Put the folder in sites/all/modules. Go to your modules pages and enable it. Then, create a link on a test page. For example

<a href="node/add/nojs/">Create content (node/add)</a>

Thanks Lars, the code really helped me get going!

share|improve this answer

protected by Community Jan 21 at 3:38

This question is protected to prevent "thanks!", "me too!", or spam answers by new users. To answer it, you must have earned at least 10 reputation on this site.

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