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.


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.


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

Alex Andrascu’s picture

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.

telmad’s picture

Good Work!

Rok Žlender’s picture

Try putting these two lines at the top of your hook_form functions

  $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.

Rok Žlender’s picture

Assigned: Unassigned » Rok Žlender
Status: Active » Postponed (maintainer needs more info)
tom.pauwaert’s picture

Ah, sorry please ignore this post.
I added it in the wrong place...

tom.pauwaert’s picture

nienaber’s picture

I posted an alternative solution to this problem here http://drupal.org/node/328201#comment-4434040