Jump to:
| Project: | AHAH helper |
| Version: | 6.x-2.0 |
| Component: | Code |
| Category: | support request |
| Priority: | normal |
| Assigned: | Rok Žlender |
| Status: | postponed (maintainer needs more info) |
Issue Summary
I used the example that came with the ahah_helper_demo.
When I place the form in the hook_form function and I run it, it doesn't work correctly. It loads with the default company fields as the default option is "Company" however when I select "Private" and the form reloads, it does not display the private fields but instead displays the company fields.
I modified the module to have the form in the hook_form_alter instead and it seems to work. My question is, is there a specific reason why I need to have the form in the hook_form_alter instead of the hook_form?
I have the code below, the first example is having the form in the hook_form() and the 2nd example (the one that works) I have the form in the hook_form_alter().
Thanks!
Version that does not work.
<?php
function testmodule_node_info()
{
return array(
'testmodule' => array(
'name' => t('testmodule'),
'module' => 'testmodule',
'description' => t('Node for testing'),
'has_title' => TRUE,
'title_label' => t('Title'),
'has_body' => TRUE,
'body_label' => t('Description'),
'min_word_count' => 0,
'locked' => TRUE
)
);
}
function testmodule_menu()
{
$items['testmodule'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('testmodule_form'),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function testmodule_form_alter(&$form, &$form_state, $form_id)
{
if ($form_id =='testmodule_node_form')
{
ahah_helper_register($form, $form_state);
}
}
/**
* Implementation of hook_form().
*/
function testmodule_form($node)
{
if (!isset($form_state['storage']['billing_info']['usage']))
{
$usage_default_value = 'company';
}
else
{
$usage_default_value = $form_state['storage']['billing_info']['usage'];
}
$form['billing_info'] = array(
'#type' => 'fieldset',
'#title' => t('Billing information'),
'#prefix' => '<div id="billing-info-wrapper">', // This is our wrapper div.
'#suffix' => '</div>',
'#tree' => TRUE, // Don't forget to set #tree!
);
$form['billing_info']['usage'] = array(
'#type' => 'select',
'#title' => t('Usage'),
'#options' => array(
'private' => t('Private'),
'company' => t('Company'),
),
'#default_value' => $usage_default_value,
'#ahah' => array(
'event' => 'change',
// This is the "magical path". Note that the parameter is an array of
// the parents of the form item of the wrapper div!
'path' => ahah_helper_path(array('billing_info')),
'wrapper' => 'billing-info-wrapper',
),
);
$form['billing_info']['update_usage'] = array(
'#type' => 'submit',
'#value' => t('Update usage'),
// Note that we can simply use the generic submit callback provided by the
// ahah_helper module here!
// All it does, is set $form_state['rebuild'] = TRUE.
'#submit' => array('ahah_helper_generic_submit'),
// We set the 'no-js' class, which means this submit button will be hidden
// automatically by Drupal if JS is enabled.
'#attributes' => array('class' => 'no-js'),
);
// If 'company' is selected, then these two form items will be displayed.
if ($usage_default_value == 'company')
{
$form['billing_info']['company_name'] = array(
'#type' => 'textfield',
'#title' => t('Company name'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Private usage and back to Company usage, we
// remembered his company's name!
'#default_value' => $form_state['storage']['billing_info']['company_name'],
);
$form['billing_info']['vat'] = array(
'#type' => 'textfield',
'#title' => t('VAT number'),
'#description' => t('Please enter a Belgian VAT number, the format is: <em>BE0999999999</em>.'),
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Private usage and back to Company usage, we
// remembered his VAT number!
'#default_value' => $form_state['storage']['billing_info']['vat'],
'#ahah' => array(
'event' => 'blur',
'path' => ahah_helper_path(array('billing_info', 'vat')),
'wrapper' => 'edit-billing-info-vat-wrapper',
'effect' => 'none',
'method' => 'replace',
),
);
// Provide instantaneous (#ahah-powered) feedback to the user about the
// VAT number he entered.
if (isset($form_state['storage']['billing_info']['vat']) && strlen($form_state['storage']['billing_info']['vat']) > 0)
{
$form['billing_info']['vat']['#field_suffix'] = theme('image', (preg_match('/^BE0\d{9}$/', $form_state['storage']['billing_info']['vat'])) ? 'misc/watchdog-ok.png' : 'misc/watchdog-error.png');
}
}
// And if 'private' is selected, then these two form items will be displayed.
else
{
$form['billing_info']['first_name'] = array(
'#type' => 'textfield',
'#title' => t('First name'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Company usage and back to Private usage, we
// remembered his first name!
'#default_value' => $form_state['storage']['billing_info']['first_name'],
);
$form['billing_info']['last_name'] = array(
'#type' => 'textfield',
'#title' => t('Last name'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Company usage and back to Private usage, we
// remembered his last name!
'#default_value' => $form_state['storage']['billing_info']['last_name'],
);
}
$form['billing_info']['address'] = array(
'#type' => 'textfield',
'#title' => t('Address'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// Always set #default_value, even if it's not a dynamically added form item!
'#default_value' => $form_state['storage']['billing_info']['address'],
);
$form['billing_info']['country'] = array(
'#type' => 'textfield',
'#title' => t('Country'),
'#size' => 20,
'#maxlength' => 255,
// Always set #default_value, even if it's not a dynamically added form item!
'#default_value' => $form_state['storage']['billing_info']['country'],
);
$form['save'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
?>Version that works.
<?php
function testmodule_node_info()
{
return array(
'testmodule' => array(
'name' => t('testmodule'),
'module' => 'testmodule',
'description' => t('Node for testing'),
'has_title' => TRUE,
'title_label' => t('Title'),
'has_body' => TRUE,
'body_label' => t('Description'),
'min_word_count' => 0,
'locked' => TRUE
)
);
}
function testmodule_form_alter(&$form, &$form_state, $form_id)
{
if ($form_id =='testmodule_node_form')
{
ahah_helper_register($form, $form_state);
testmodule_theform(&$form, $form_state);
}
}
function testmodule_theform(&$form, $form_state)
{
if (!isset($form_state['storage']['billing_info']['usage']))
{
$usage_default_value = 'company';
}
else
{
$usage_default_value = $form_state['storage']['billing_info']['usage'];
}
$form['billing_info'] = array(
'#type' => 'fieldset',
'#title' => t('Billing information'),
'#prefix' => '<div id="billing-info-wrapper">', // This is our wrapper div.
'#suffix' => '</div>',
'#tree' => TRUE, // Don't forget to set #tree!
);
$form['billing_info']['usage'] = array(
'#type' => 'select',
'#title' => t('Usage'),
'#options' => array(
'private' => t('Private'),
'company' => t('Company'),
),
'#default_value' => $usage_default_value,
'#ahah' => array(
'event' => 'change',
// This is the "magical path". Note that the parameter is an array of
// the parents of the form item of the wrapper div!
'path' => ahah_helper_path(array('billing_info')),
'wrapper' => 'billing-info-wrapper',
),
);
$form['billing_info']['update_usage'] = array(
'#type' => 'submit',
'#value' => t('Update usage'),
// Note that we can simply use the generic submit callback provided by the
// ahah_helper module here!
// All it does, is set $form_state['rebuild'] = TRUE.
'#submit' => array('ahah_helper_generic_submit'),
// We set the 'no-js' class, which means this submit button will be hidden
// automatically by Drupal if JS is enabled.
'#attributes' => array('class' => 'no-js'),
);
// If 'company' is selected, then these two form items will be displayed.
if ($usage_default_value == 'company')
{
$form['billing_info']['company_name'] = array(
'#type' => 'textfield',
'#title' => t('Company name'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Private usage and back to Company usage, we
// remembered his company's name!
'#default_value' => $form_state['storage']['billing_info']['company_name'],
);
$form['billing_info']['vat'] = array(
'#type' => 'textfield',
'#title' => t('VAT number'),
'#description' => t('Please enter a Belgian VAT number, the format is: <em>BE0999999999</em>.'),
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Private usage and back to Company usage, we
// remembered his VAT number!
'#default_value' => $form_state['storage']['billing_info']['vat'],
'#ahah' => array(
'event' => 'blur',
'path' => ahah_helper_path(array('billing_info', 'vat')),
'wrapper' => 'edit-billing-info-vat-wrapper',
'effect' => 'none',
'method' => 'replace',
),
);
// Provide instantaneous (#ahah-powered) feedback to the user about the
// VAT number he entered.
if (isset($form_state['storage']['billing_info']['vat']) && strlen($form_state['storage']['billing_info']['vat']) > 0)
{
$form['billing_info']['vat']['#field_suffix'] = theme('image', (preg_match('/^BE0\d{9}$/', $form_state['storage']['billing_info']['vat'])) ? 'misc/watchdog-ok.png' : 'misc/watchdog-error.png');
}
}
// And if 'private' is selected, then these two form items will be displayed.
else
{
$form['billing_info']['first_name'] = array(
'#type' => 'textfield',
'#title' => t('First name'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Company usage and back to Private usage, we
// remembered his first name!
'#default_value' => $form_state['storage']['billing_info']['first_name'],
);
$form['billing_info']['last_name'] = array(
'#type' => 'textfield',
'#title' => t('Last name'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// If the user switched to Company usage and back to Private usage, we
// remembered his last name!
'#default_value' => $form_state['storage']['billing_info']['last_name'],
);
}
$form['billing_info']['address'] = array(
'#type' => 'textfield',
'#title' => t('Address'),
'#required' => TRUE,
'#size' => 20,
'#maxlength' => 255,
// Always set #default_value, even if it's not a dynamically added form item!
'#default_value' => $form_state['storage']['billing_info']['address'],
);
$form['billing_info']['country'] = array(
'#type' => 'textfield',
'#title' => t('Country'),
'#size' => 20,
'#maxlength' => 255,
// Always set #default_value, even if it's not a dynamically added form item!
'#default_value' => $form_state['storage']['billing_info']['country'],
);
}
?>
Comments
#1
Thanks for the code buddy! I was stucked in the very same place and kept banging my head to the desk. Otherwise ahah_helper is just wonderfull. Just poor Wim doesn't have much time to document it properly. I think if it does it can make it quickly to the core.
#2
Good Work!
#3
Try putting these two lines at the top of your hook_form functions
<?php$form = array();
ahah_helper_register($form, $form_state);
?>
also you should change hook_form function definition to comply with http://api.drupal.org/api/function/hook_form/6 . I haven't tried it but I think it should work.
#4
#5
Ah, sorry please ignore this post.
I added it in the wrong place...
#6
#7
I posted an alternative solution to this problem here http://drupal.org/node/328201#comment-4434040