0

I'm using a block plugin to render a user specified form. I'm retrieving the form like so:

public function blockSubmit($form, FormStateInterface $form_state) {

    $this->configuration['template'] = $form_state->getValue('template');
    $selected_entity_type_bundle     = $form_state->getValue('entity_type');
    $values                          = explode('.', $selected_entity_type_bundle);

    $this->configuration['entity_type']             = $values[0];
    $this->configuration['bundle']                  = $values[1];
    $this->configuration['entity_type_submit_text'] = $form_state->getValue('entity_type_submit_text');

}

private function buildEntityForm() {
    $values = array();
    // Specify selected bundle if the entity has bundles.
    if (\Drupal::entityManager()->getDefinition($this->configuration['entity_type'])->hasKey('bundle')) {
        $bundle_key = \Drupal::entityManager()->getDefinition($this->configuration['entity_type'])->getKey('bundle');
        $values     = array($bundle_key => $this->configuration['bundle']);
    }
    $entity = \Drupal::entityManager()
        ->getStorage($this->configuration['entity_type'])
        ->create($values);

    if ($entity instanceof EntityOwnerInterface) {
        $entity->setOwnerId(\Drupal::currentUser()->id());
    }

    $form = \Drupal::entityManager()
        ->getFormObject($this->configuration['entity_type'], 'default')
        ->setEntity($entity);

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

This grabs the form just fine, and I render it using

public function build() {

    if ($this->configuration['entity_type'] != '') {
        $entityForm                                = $this->buildEntityForm();
        $entityForm['actions']['submit']['#value'] = t($this->configuration['entity_type_submit_text']);// Editable submit button value.
        if ($this->configuration['template'] == 'learnmore') {
            $entityForm['actions']['submit']['#value'] = '<i class="fa fa-mail"></i>'.$entityForm['actions']['submit']['#value'];
        }
    } else {
        $entityForm = '';
    }
    $entityForm['actions']['preview'] = '';

    $content = [
        'template'     => [
            '#type'       => 'container',
            '#attributes' => [
                'class'      => [$this->configuration['template']],
            ],
            'header'  => [
                '#type'  => 'html_tag',
                '#tag'   => 'h5',
                '#value' => $this->configuration['label'],
            ],
            'form' => $entityForm,
        ],
    ];

    return $content;
}

Which renders the form. But I'm setting the submit button text as specified by the user like so

$entityForm['actions']['submit']['#value'] = t($this->configuration['entity_type_submit_text']);

And I want to add an icon inside the button before the text like so

$entityForm['actions']['submit']['#value'] = '<i class="fa fa-mail"></i>'.$entityForm['actions']['submit']['#value'];

The issue is when it renders the button it includes the html tags so the actual submit button text is

<i class="fa fa-mail"></i>Submit Button Text

It displays the html tags instead of rendering the actual icon. Is there a way to allow html tags inside of a submit button on a form?

2
  • Possible duplicate of How do I use Font Awesome on a Drupal form submit button?
    – mradcliffe
    Nov 7, 2016 at 17:56
  • Additionally not listed in an answer there, but submit/button elements exposed the input__submit theme_wrapper, which I believe is targetable in a template preprocess or template itself for adding custom markup and/or attributes.
    – mradcliffe
    Nov 7, 2016 at 17:58

2 Answers 2

4

Use a formattable markup:

use Drupal\Component\Render\FormattableMarkup;

  $value = new FormattableMarkup('<i class="fa fa-mail"></i>@text', [
    '@text' => $value,
  ]);

The formattable string will not be escaped. The variable in the placeholder @text will be escaped and that is important, because it contains user input.

4
  • I tried $entityForm['actions']['submit']['#value'] = t($this->configuration['entity_type_submit_text']);// Editable submit button value. if ($this->configuration['template'] == 'learnmore') { $icon = new FormattableMarkup('<i class="fa fa-envelope-o"></i>@text', ['@text' => $icon]); $entityForm['actions']['submit']['#value'] = $icon.$entityForm['actions']['submit']['#value']; } but it did not escape the icon
    – Amy
    Nov 7, 2016 at 17:17
  • This is a bit easier to read pastie.org/private/n5zjrnu08y5acfil3whuqg
    – Amy
    Nov 7, 2016 at 17:20
  • I realized that it might not be possible since it's inserting the html into the 'value' attribute of the submit input tag. Which I don't believe supports html.
    – Amy
    Nov 7, 2016 at 17:22
  • This is also not a good solution and angry Danish people will bring their wrath upon you for putting markup in code.
    – mradcliffe
    Nov 7, 2016 at 17:57
-1

I don't believe this is possible since it's inserting the html into the value attributes of a submit type input tag rather than in the content within a button tag. To resolve this I appended a button element like so.

    $content = [
        'template'     => [
            '#type'       => 'container',
            '#attributes' => [
                'class'      => [$this->configuration['template']],
            ],
            'header'  => [
                '#type'  => 'html_tag',
                '#tag'   => 'h5',
                '#value' => $this->configuration['label'],
            ],
            'form' => $entityForm,
        ],
    ];
    if ($this->configuration['template'] == 'learnmore') {
        $content['template'][] = [
            'test'           => [
                '#type'         => 'html_tag',
                '#tag'          => 'button',
                '#value'        => '<i class="fa fa-envelope-o"></i> '.$entityForm['actions']['submit']['#value'],
                '#allowed_tags' => 'i',
                '#attributes'   => [
                    'type'         => 'submit',
                    'form'         => 'contact-message-learn-more-form',
                ],
            ],
        ];

    }

    return $content;

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.