3

I'm rendering a form programmatically. The following code works:

$addressForm = \Drupal::entityTypeManager()
  ->getStorage('profile')
  ->create(array('type' => 'customer', 'uid' => $uid));
$finalform =  $this->entityFormBuilder()->getForm($addressForm);

However, it is rendering the form before hook_form_alter() has been called.

For example, in hook_form_alter() we added a #after_build callback method and custom validations, but the changes made in these functions are not reflected in $finalform.

How do I ensure hook_form_alter() changes are made to the rendered output?

.module file

function custom_profile_form_profile_customer_add_form_alter(&$form, FormStateInterface &$form_state, $form_id) {
  $form['formtitle'] =  array(
    '#type' => 'markup',
    '#weight' => -100,
    '#markup' => '<h2>Old Address Form</h2>',
  );
  /* ....
.... */
}

function custom_profile_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_FORM_ID_alter') {
    $group = $implementations['custom_profile'];
    unset($implementations['custom_profile']);
    $implementations['custom_profile'] = $group;
  }
}

.routing.yml

I have created a new route for the Address page in /modules/custom/custom_profile/custom_profile.routing.yml,

commerce_add_address.get:
  path: '/checkout/{uid}/customer/add'
  defaults:
    _controller: '\Drupal\custom_profile\Controller\newAddressBook::commerce_add_address'
  options:
    parameters:
      uid:
        type: integer
  methods:  [GET,POST]
  requirements:
    _permission: 'access content'

Controller

in src/Controller/newAddressBook.php file

public function commerce_add_address($uid) {
  //To get profile Add Address form
  $addressForm = \Drupal::entityTypeManager()
      ->getStorage('profile')
      ->create(array( 
        'type' => 'customer',
        'uid'  => $uid
      ));

  $finalform = $this->entityFormBuilder()->getForm($addressForm);
  $build['#theme'] = 'usernewaddress';
  $build['#data'] = array();
  $build['#data']['form'] = $finalform;

  return $build;
3
  • just now implemented hook_module_implements_alter(), No luck. form_alter callback function are not triggered. Commented Jun 21, 2017 at 10:14
  • 1
    Please add your hook_module_implements_alter() code to your question.
    – leymannx
    Commented Jun 21, 2017 at 10:15
  • @leymannx any other idea? to render/trigger form_alter. Commented Jun 22, 2017 at 8:47

1 Answer 1

2
+25

Ensure that your implementation of hook_form_alter() runs at the right time via hook_module_implements_alter().

This hook is invoked during \Drupal::moduleHandler()->getImplementations(). A module may implement this hook in order to reorder the implementing modules, which are otherwise ordered by the module's system weight.

But pay attention when using possible variations of hook_form_alter().

Note that hooks invoked using \Drupal::moduleHandler->alter() can have multiple variations(such as hook_form_alter() and hook_form_FORM_ID_alter()). \Drupal::moduleHandler->alter() will call all such variants defined by a single module in turn. For the purposes of hook_module_implements_alter(), these variants are treated as a single hook. Thus, to ensure that your implementation of hook_form_FORM_ID_alter() is called at the right time, you will have to change the order of hook_form_alter() implementation in hook_module_implements_alter().

See? Right now you are checking for if ($hook == 'form_FORM_ID_alter') which won't work. Fix it by replacing it with if ($hook == 'form_alter').


If that doesn't work try to change your module's weight via module_set_weight().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.