How to make drupal hook_form_alter run after validation hook in a module

1.9k views Asked by At

I have made a drupal 7 module recently and I want to customise the way drupal show validation errors. I want to place error message in a popup. And I put the popup generation code in form alter hook.

But I cannot make drupal hook_form_alter run after validation hook. I have tried to clear the form cache and tried to use "#after_build" instead of form alter hook, but they are all run before the validation. It seems that the validation is last thing to run in that process. I have put my code below, please help me on this.

Thank you very much in advance.

function quote_line_menu() {

    $items ['quote_line'] = array (
            'page callback' => 'drupal_get_form',
            'page arguments' => array (
                    'quote_line_form'
            ),
            'access arguments' => array (
                    'access content'
            ),
            'type' => MENU_CALLBACK
    );

    $items ['ajax_manually_get_price'] = array(
            'page callback' => 'ajax_update_price_callback',
            'access arguments' => array (
                    'access content'
            ),
            'type' => MENU_CALLBACK
    );

    return $items;
}


function quote_line_form($form, &$form_state) {

    // Initialize.
    if ($form_state ['rebuild']) {
        // Don't hang on to submitted data in form state input.
        $form_state ['input'] = array ();
    }
    if (empty ( $form_state ['storage'] )) {

        $form_state ['storage'] = array (
                'step' => 'quote_line_form_first'
        );
    }


    // Add general settings
    $form['#attributes']['class'][] = 'separate-border';

    // No cache
    /*
     $form['#cache'] = FALSE;
    $form['#no_cache'] = TRUE;
    $form_state['cache'] = FALSE;*/
    $form['#after_build'][] = 'quote_line_form_after_build';
    // $form['#validate'][] = 'quote_line_form_validate';

    // Return the form for the current step.
    $function = $form_state ['storage'] ['step'];
    $form = $function ( $form, $form_state );

    return $form;
}

function quote_line_form_after_build($form, &$form_state) {
    error_log(0);
    return $form;
}


function quote_line_form_quote_line_form_alter(&$form, &$form_state, $form_id) {

    error_log(1);
    quote_line_handle_form_set_error($form, $form_state, $form_id); //generate popup here

    // Preset form state
    if($form_state['storage']['step'] == 'quote_line_form_bike_info'){
        if(isset($form_state['storage']['bike_0_oversea_travel_days']) && !empty($form_state['storage']['bike_0_oversea_travel_days'])){
            $form ['default_open_oversea'] = array (
                    '#markup' => '<script>jQuery("a#over0-yes").click();</script>'
            );
        }
    }
}


function quote_line_form_validate($form, &$form_state) {

    error_log(2);
    error_log($_POST['form_build_id']);
    //cache_clear_all('form', 'cache_form', true);

    $values = $form_state ['values'];

    if(isset($_POST['back']) && !empty($_POST['back'])){
        if(!isset($form_state ['values']['back']) || $form_state ['values']['back'] != $_POST['back']){
            $form_state ['values']['back'] = $_POST['back'];
        }
        if(!isset($form_state ['values']['op']) || $form_state ['values']['op'] != $_POST['back']){
            $form_state ['values']['op'] = $_POST['back'];
        }

        $function = 'quote_line_form_submit';
        $function ( $form, $form_state );

        return;
    }

    // Call step validate handler if it exists.
    if (function_exists ( $form_state ['storage'] ['step'] . '_validate' )) {
        $function = $form_state ['storage'] ['step'] . '_validate';
        $function ( $form, $form_state );
    }

    return;
}
2

There are 2 answers

1
Muhammad Reda On

You can stop the error messages being printed to the theme using drupal_get_messages('error'). Then, display custom error messages in anyway you like.

0
Charles On

I just found a dirty fix. The validation and form build process has been defined in drupal_process_form. And I just hacked that function to make sure the hook_form_alter is called again after the validation failed.

If anyone has a better solution, please post here. Thanks.