2

Please I need help with my code. I have a form and a block created programmatically. The block embeds the form to show it on the frontend. The block also has some settings (form preffix text). I want to load the block settings inside my buildForm in my Form.php to get the preffix text and show it in the form markup field. But I can't seem to find a way to pass on the $block_id to the buildForm() so it can load the block.

I have a scenario where there can be two of these blocks on the same page in which Drupal uniques the block by appending some ID with the block id. So for example my page has two of these blocks one would be like feedbackblock the other would be feedbackblock_2 hence I cannot hardcode the block id to load it in my buildForm function.

I want it to dynamically pass on the block id to the form.

build() from my Block.php:

  public function build() {
    $block_id // get the block id of the current block instance
    $feedback_form = $this->formBuilder->getForm(FeedbackForm::class, $block_id);

    $build = [];
    $build['#theme'] = 'feedback_block';
    $build['feedback_block']['#markup'] = render($feedback_form);

    return $build;
  }

buildForm from my FeedbackForm.php:

  public function buildForm(array $form, FormStateInterface $form_state, string $block_id) {
      // Get the block id here.
  }

Is there any way to achieve this?

7
  • 2
    $feedback_form is already a render array, you don't have to render it. Just set it to a variable, let Drupal do the work.
    – Kevin
    Nov 12 at 14:13
  • Also: drupal.stackexchange.com/a/199929/57
    – Kevin
    Nov 12 at 14:14
  • Thanks for the link but I already viewed that and that will not work in my case as I don't have a routing.yml and I don't need one. I am just creating a block and a form block is showing that form and the block can be shown anywhere on the site regardless of a route.
    – New To 'C'
    Nov 12 at 14:19
  • 1
    You don't need a routing yaml. Read the answer. " when using parameters in forms you have to set a null value in the parameter list"
    – Kevin
    Nov 12 at 14:25
  • Oh thanks mate! This worked, I wish I could upvote your comment but don't have the option. I am now able to pass extra arg to the buildForm(). But how can I dynamically get the block id of the current block instance?
    – New To 'C'
    Nov 12 at 14:28
2

There is an abstaction layer between the storage of the block config and the block view building. Block configuration can be stored anywhere and doesn't necessarily have a machine name. You can however transfer the machine name to the block settings when you place a block in Block Layout:

use Drupal\block\BlockInterface;

/**
 * Implements hook_ENTITY_TYPE_presave() for block entities.
 */
function mymodule_block_presave(BlockInterface $block) {
  if ($block->isNew()) {
    $settings = $block->get('settings');
    $settings['block_id'] = $block->get('id');
    $block->set('settings', $settings);
  }
}

Then you can get the machine name in build():

  public function build() {
    // get the block id of the current block instance
    $block_id = !empty($this->configuration['block_id']) ? $this->configuration['block_id'] : '';

As a side note. I don't think the rest of the code in the question does work. You need to add the unique ID to the form instance before you call formBuilder->getForm() and then use it to build a unique form ID. After that buildForm() can get the ID from the class property. See Using the same form more than once per page with AJAX callbacks

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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