I tried making a simple computed field that outputs some html that can be latter modified with Ajax. If we consider a typical hello world example, the computed field output would be a link saying 'say hello' and when you click on it the AJAX adds the text 'hello world' in the div below the link. This is based on a javascript/ajax example inside 'Drupal 7 Module Development' by Matt Butcher. It works inside a normal page, but inside a computed field it gives an error.
Here is the code for my computed field. It just creates a link which is ajax enabled and a second div where ajax content will be inserted.
drupal_add_js('misc/ajax.js');
$link = l(t('Say Hello'), 'hello_world_link_callback/ajax/', array(
'attributes' => array('class' => array('use-ajax'))));
$output = '<div>' . $link . '</div><div id="saying-hello"></div>';
$entity_field[0]['value'] = $output;
Implementation of hook_menu() to create the AJAX callback function:
$items['hello_world_link_callback'] = array(
'page callback' => 'hello_world_link_response',
'access callback' => 'user_access',
'access arguments' => array('access content'),
);
Here is my callback function:
function hello_world_link_response($type = 'ajax') {
if ($type == 'ajax') {
$output = t("Hello World!");
$commands = array();
$commands[] = ajax_command_append('#saying-hello', $output);
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
else {
return t("Hello World in a new page.");
}
}
When I click the link it crashes to a white screen with this text:
[{"command":"settings","settings":{"basePath":"/drupal/","pathPrefix":"","ajaxPageState":{"theme":"bartik","theme_token":"fN8xkldpLQAwubNZ1n0BzdQPnF577BDw6sfuzoVrcmw"},"overlay":{"paths":{"admin":"node/*/maestro\nnode/add/*/maestro/*\nnode/*/edit/maestro/edit/*\nmaestro/trace/*/*/*\nnode/*/edit\nnode/*/delete\nnode/*/revisions\nnode/*/revisions/*/revert\nnode/*/revisions/*/delete\nnode/add\nnode/add/*\noverlay/dismiss-message\nuser/*/shortcuts\nadmin\nadmin/*\nbatch\ntaxonomy/term/*/edit\nuser/*/cancel\nuser/*/edit\nuser/*/edit/*\ndevel/*\nnode/*/devel\nnode/*/devel/*\ncomment/*/devel\ncomment/*/devel/*\nuser/*/devel\nuser/*/devel/*\ntaxonomy/term/*/devel\ntaxonomy/term/*/devel/*","non_admin":"admin/structure/block/demo/*\nadmin/reports/status/php"},"pathPrefixes":[],"ajaxCallback":"overlay-ajax"}},"merge":true},{"command":"insert","method":null,"selector":null,"data":"","settings":null},{"command":"insert","method":"prepend","selector":null,"data":"","settings":null}]
Any ideas?
Updated based on comments from tenken
I've altered hook_menu to be a callback only and set the delivery callback to be an ajax response. I've also split the hook_menu into items for the cases with and without ajax. So the hook_menus now look like this:
$items['hello_world_link_callback/nojs'] = array(
'page callback' => 'hello_world_link_response',
'access callback' => TRUE,
'access arguments' => TRUE,
'type' => MENU_CALLBACK,
'page arguments' => array(1),
);
$items['hello_world_link_callback/ajax'] = array(
'page callback' => 'hello_world_link_response',
'access callback' => TRUE,
'access arguments' => TRUE,
'type' => MENU_CALLBACK,
'delivery callback' => 'ajax_deliver',
'page arguments' => array(1),
);
The callback function is unchanged from above with the exception that it now returns the AJAX commands, rather than calling 'ajax_deliver'. So it returns:
return array('#type' => 'ajax', '#ajax' => $commands);
This code is now working for me, so it had nothing to do with the fact that it was a computed field. This code is also covered here.