First of all you will need to define what you want in your forms. Basically with Ajax, you would want something that dynamically changes the contents of your form without having to reload the entire page. In my example, I placed a checkbox which will, after it's been clicked, display additional fields titled 'question' and 'answer'.
Here is basically what you will need to add in your hook_form function:
function activitymanager_form(&$node, $form_state) {
function activitymanager_form(&$node, $form_state) {The Textfield form displays the checkbox itself. The '#ahah' field defines the Ajax behavior. '#path' directory should map to your callback function, which will be called everytime a user clicks on the checkbox. In my case, the callback function is called activitymanager_autoindex_callback. Therefore, the path to the function should be 'activitymanager/autoindex/callback. You must also set the path to your callback function in your hook_menu function as follows:
$form['textfield'] = array(
'#type' => 'checkbox',
'#title' => t('Textfield'),
'#default_value' => $form_state['values']['textfield'],
'#ahah' => array(
'path' => 'activitymanager/autotextfields/callback',
'wrapper' => 'textfields',
'effect' => 'fade',
)
);
$form['textfields'] = array(
'#title' => t("Generated text fields for the verification types"),
'#prefix' => '"textfields">',',
'#suffix' => '
'#type' => 'fieldset',
);
if ($form_state['values']['textfield']) {
$form['textfields']['question'] = array(
'#type' => 'textfield',
'#title' => t('Activity Question'),
);
$form['textfields']['answer'] = array(
'#type' => 'textfield',
'#title' => t('Activity Answer'),
);
}
return $form;
}
define(TEST_PATH,'activitymanager/autotextfields');The above code is necessary to tell Drupal how it can find the callback function. It is quite cumbersome to add a new entry here everytime you create a new callback function, but it is a necessary step.
function activitymanager_menu() {
$items = array();
// Setup the initial menu option.
// yoursite/?q=test
// if you use clear URLs
// yoursite/test
$items['test'] = array(
'title' => 'Test setup',
'description' => 'A simple test form.',
'page callback' => 'drupal_get_form',
'page arguments' => array ('activitymanager_form'),
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM
);
/**
* This is the path in your site to the ajax/ahah callback function.
*/
$items[TEST_PATH] = array(
'title' => 'Test setup',
'description' => 'A simple test AHAH callback.',
'page callback' => 'drupal_get_form',
'page arguments' => array (
// first argument is the callback function.
'activitymanager_autotextfields_callback'),
//'test_ahah_cb'),
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}
Finally here is my callback function:
function activitymanager_autotextfields_callback() {there were some things in this code that I had to tweak to get it to work properly. When I first ran this code, Drupal would for some reason submit the form whenever I clicked on the checkbox without notifying me of it. So if I clicked on the checkbox 5 times, I would end up with 5 duplicate entries in the database. This is obviously not what I wanted, so I began researching what was actually happening. I found out soon that the drupal_process_form function inside my callback function is causing the above behavior. I am yet to understand why Drupal decides to submit the form here, luckily though I figured out a way to work around this issue. I found that the some of the values in $form_state array can be used to change the behavior of drupal_process_form function. I inserted the following code just above my call to drupal_process_form fucntion:
// Get form from cache.
$form_state = array('storage' => NULL, 'submitted' => NULL);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form_state['post'] = $form['#post'] = $_POST;
$form['#programmed'] = $form['#redirect'] = FALSE;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$textfields = $form['textfields'];
$output = drupal_render($textfields);
// Final rendering callback.
print drupal_json(array('status' => TRUE, 'data' => $output));
exit();
}
$form_state['rebuild'] = 'notempty';This eliminated the submit problem I was having. My callback function now looks like this:
function activitymanager_autotextfields_callback() {I hope that somebody in the future finds this posting helpful, as adding an Ajax function in Drupal was not an easy task (at least for me).
// Get form from cache.
$form_state = array('storage' => NULL, 'submitted' => NULL);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form_state['post'] = $form['#post'] = $_POST;
$form['#programmed'] = $form['#redirect'] = FALSE;
$form_state['rebuild'] = 'notempty';
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$textfields = $form['textfields'];
$output = drupal_render($textfields);
// Final rendering callback.
print drupal_json(array('status' => TRUE, 'data' => $output));
exit();
}
No comments:
Post a Comment