Using ctools modal forms for node edit
For a drupal 6 site I needed a node edit overlay. This is what I did.
Define the urls ajax/node/%node/edit and nojs/node/%node/edit. The idea is to use path similar to the normal drupal paths just prepended with what ctools modal needs. It needs are minor in that the url path must contain a string nojs and in this case a class attribute ctools-use-modal.
<?php
function annotate_ym_menu() {
$items['nojs/node/%node/%'] = array(
'page callback' => 'annotate_ym_ajax_node',
'page arguments' => array(0, 2, 3),
'access arguments' => array('post comments'),
);
$items['ajax/node/%node/%'] = array(
'page callback' => 'annotate_ym_ajax_node',
'page arguments' => array(0, 2, 3),
'access arguments' => array('post comments'),
);
return $items;
}
?>When including the ctools plumbing the nojs part of urls is replaced by ajax. The lazy way is by
<?php
function annotate_ym_init() {
// Load the Ctools modal library and add the modal javascript.
ctools_include('modal');
ctools_modal_add_js();
}
?>How do we generate these path? For this use case we use views. By adding the nid and a general text field linking to nojs/node/[nid]/edit and a class attribute ctools-use-modal we are ready to process the request.
The first part is to check for a javascript enabled browser. If no javascript use the path to redirect to the normal behaviour. That is node/[nid]/edit.
<?php
function annotate_ym_ajax_node($js, $node, $command) {
if (!ctools_js_load($js)) {
drupal_goto(implode('/', array_shift(arg())));
}
?>Now we are into ajax world so we need to use the ctools lib to render forms and content. As we are working with nodes only here we need to include the node handling code.
<?php
// include node file, necessary for node generation
module_load_include('inc', 'node', 'node.pages');
?>Now we need to distinguish between forms and content.
<?php
if ($command == 'edit') {
$config = array(
'form_name' => $node->type . '_node_form',
);
}
else if ($command == 'delete') {
$config = array(
'form_name' => 'node_delete_confirm',
);
}
else if ($command == 'view') {
$config = array(
'content' => node_view($node, TRUE, TRUE, FALSE),
);
}
// TODO: view and others?
else {
// This is bad ajax response :(
drupal_goto();
}
?>Ready, set, go and render the request by ctools
<?php
ctools_include('modal');
ctools_include('ajax');
if (
$config['form_name']) {
$form_state = array(
'title' => t('Node'),
'ajax' => TRUE,
);
$form_state['args'] = array($node);
$output = ctools_modal_form_wrapper($config['form_name'], $form_state);
}
else {
$output = array();
$output[] = ctools_modal_command_display(t('Node'), $config['content']);
}
?>If $output is empty we are done so we can close the modal window.
<?php
if (empty($output)) {
$output = array();
$output[] = ctools_modal_command_dismiss();
}
?>Return the response for the given command.
<?php
ctools_ajax_render($output);
}
?>A feature of my experiment is available on github
Some references:
- ctools module
- ctools ajax sample module
- A peek @ dialog module
- http://zroger.com/node/31
- Putting the comment form in modal by walker2238
Comments
EclipseGc (not verified)
Sat, 2011/03/12 - 10:12pm
Permalink
Actually...
You don't need to define both of those menu items, you can use the %ctools_js in place of 'nojs' and 'ajax'. Then just pass all your links to it as "nojs" and it will figure out whether it should be nojs or ajax for you.
Eclipse
Alex Weber (not verified)
Sun, 2011/03/13 - 11:50pm
Permalink
Awesome!
Great article, thanks for the tips! :)
fourmi4x (not verified)
Thu, 2011/05/26 - 4:07pm
Permalink
Thank you sooooooooo much for
Thank you sooooooooo much for this tutorial!! I'm a big newbie to ctool, you just saved me so many hours!