0

I'm wanting to alter the commerce cart page form.

By using var_dump($form_id) or chrome inspect I can see the id is id="views-form-commerce-cart-form-orange-default-42". If I write my hook as :

function module_form_views_form_commerce_cart_form_orange_default_42_alter

I can see that I am altering the form. But this has been altered in my theme hence the extra bit on the id orange_default_42. If I do :

function testingstuffs_form_views_form_commerce_cart_form_alter

I cannot alter the form.

How do I hook into this form correctly / is there a correct way to find form ids?

3
  • @NoSssweat I had seen that. print_r always crashes my site. Through chrome devtools works and is how I found this. What I'm wondering is if I can alter this without the extra orange chunk on there as that's from the theme. – Derek C. Mar 5 '20 at 4:26
  • 1
    Install the Devel module and enable Kint and then you can do kint($form_id);. For more info on how to use kint, see this. – No Sssweat Mar 5 '20 at 4:35
  • I'm wondering is if I can alter this without the extra orange chunk The only way might be by using hook_form_BASE_FORM_ID_alter. You'll need to kint($form); or kint($form_state), I forgot which one, to see if it has a base form ID. – No Sssweat Mar 5 '20 at 4:39
1

The issue here is that there are probably two form IDs for the form. One is the form_id, and the lesser known one is the base_form_id. If a Drupal form is used more than once on a page, weird things come about. To get around this, form developers can set the form ID to be dynamic, so that each time the form is built, it's given a unique ID. Example:

class FooBarForm implements FormInterface {

  protected $id;

  public function __construct($type) {
    $this->id = $id;
  }

  public function getFormId() {
    return 'foo_bar_form-' . $this->id;
  }
}

class FooRouteController {

  public function fooBarForm(ContentEntityInterface $entity) {
    $form = new FooBarForm($entity->id());

    return \Drupal::formBuilder()->getForm($form);
  }
}

Forms can also implement BaseFormIdInterface, which requires them to implement BaseFormIdInterface::getBaseFormId(). The form ID returned from this hook will be the same for all instances of the form, and NOT dynamic.

class FooBarForm implements FormInterface, BaseFormIdInterface {

  protected $id;

  public function __construct($type) {
    $this->id = $id;
  }

  public function getFormId() {
    return 'foo_bar_form-' . $this->id;
  }

  public function getBaseFormId() {
    return 'foo_bar_form';
  }
}

The relevance of this is that there are actually multiple form alter hooks called, in this order:

  1. hook_form_alter()
  2. hook_form_BASE_FORM_ID_alter()
  3. hook_form_FORM_ID_alter()

Looking at your hook - module_form_views_form_commerce_cart_form_orange_default_42_alter, it would appear you are implementing the third hook. The ID of 42 is being appended as part of the dynamic Form ID.

To find out the base form ID (if one exists), you can call the following in your form:

$form_state->getBuildInfo()

This will give you the build info, which you can dump with kint() or however you do your debugging. In the build info will be the base form ID (assuming it's set). If it is, you can implement the second form alter hook above, using that base form ID.

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