2

I am trying to move 2 form fields to the advanced sidebar: dismissible and status. Status was already part of the meta container and setting #group='meta' on dismissable also placed it there; but these weren't in the proper order. Nothing I do seems to have any impact on:

  • dismissible
  • standard meta fields: published, author, revision log
  • status

Both dismissible and status are fields added by the Sitewide Alert module which defines the entity which this is the edit form for.

I gave up trying to move my 2 fields (together) so I created my own details block as:

  $form['alert_settings'] = [
    '#type' => 'details',
    '#group' => 'advanced',
    '#weight' => -99,  
    '#title' => t('Alert settings'),
    '#tree' => TRUE,
    '#access' => TRUE,
    '#open' => TRUE,
  ];

and then assigned both fields #group='alert_settings'. This works fine as it creates a new details group which is placed at the top of the right sidebar. Perfect, except I want status to be the top item in this block, followed by dismissible.

No matter which of the status #weight options I set (or dismissable ones); I can't change the order of these.

I have tried:

  $form['status']['#weight'] = -99;
  $form['status']['widget']['#weight'] = -99;
  $form['status']['widget']['value']['#weight'] = -99;

What am I missing here?

0

1 Answer 1

2

It seems ultimately to be down to this code in EntityFormDisplay::processForm():

// Assign the weights configured in the form display.
foreach ($this->getComponents() as $name => $options) {
  if (isset($element[$name])) {
    $element[$name]['#weight'] = $options['weight'];
  }
}

This method is a #process callback for the form which runs after form alter hooks, so your changes are lost.

You could add your own process callback and change the weights there, but it might be a bit cleaner to alter it at the component level with hook_entity_form_display_alter(), e.g.:

function MODULE_entity_form_display_alter(\Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display, array $context) {
  if ($context['entity_type'] == 'sitewide_alert') {
    $status = $form_display->getComponent('status');
    // 'dismissible' is set to the base field's weight, -10.
    $status['weight'] = -11;
    $form_display->setComponent('status', $status);
  }
}

Incidentally, $form['status']['#weight'] would have been the right choice if the process callback wasn't overriding it.

4
  • This does work. Thanks for this. Have never used that hook before but willcertainly keep it in mind as I have come across this issue a few times now where sidebar elements we not movable.
    – liquidcms
    Oct 21, 2021 at 20:29
  • 1
    No problem, I tracked down where the issue comes from and updated the answer in case you’re interested. Seems to be at least somewhat “by design”
    – Clive
    Oct 22, 2021 at 8:54
  • Thanks for the added info. Also not surprising that the module has coded something to force something odd. It took me a while to figure out why i couldn't make the entity fieldable when someone pointed out there was code in the module to explicitly block making the entity fieldable (for no good reason).
    – liquidcms
    Oct 22, 2021 at 19:20
  • 1
    I saw that question too, spent 20mins of confused poking around the code before 4k4 thankfully worked it out and brought some sanity. I would never have thought to look for what turned out to be the problem either. Funnily enough the problem for this question isn't that module, the weight override code is in core.
    – Clive
    Oct 22, 2021 at 19:39

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.