Suppose I have the following code.

class customCreateForm extends FormBase {

/* code code code... */

  public function getFormId() { /* code */ }
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['label'] = array(
      '#type' => 'textfield',
      '#title' => t('title'),
      '#description' => $this->t('Your title'),
      '#default_value' => "",
      '#size' => 10,
      '#maxlength' => 8,
      '#required' => TRUE,
    /* code code code... */
    return form;
  /* code code code... */

I can understand how to add a form element, but how can I add HTML markup or JavaScript?

For example, I want to add the following in my custom form.

<link type="text/css" rel="stylesheet" href="bla...">

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<div id="something" class="something">
        <img src="bla" /> 
<table id="something" class="something"><tr><td>aaa</td></tr></table>

/* code code code */

<script src="https://maps.googleapis.com/maps/api/js?key=aaaa&libraries=places&callback=initAutocomplete" async defer></script>

you should add a library like this :

$form['#attached']['library'][] = 'my_module/mylibrary';

Create mylibrary.libraries.yml file with the content :

  version: 1.x
      css/my-css.css: {}
    js/my-js.js: {}

more documentation: https://www.drupal.org/developing/api/8/assets

  • If you want to add more than one javascript file, do you need two js: sections or can you put them both under the same one? – Oceanescence Nov 14 '19 at 14:13

Add html content with #markup type form field for example,

$form['html-content'] = array(
  '#markup' => '<div class="your-class"><h2>your content</h2></div>,

Form API have an option to add javascript and css with #attached option, we could add as library,

$form['#attached']['library'][] = 'module/library-name';

See Render API overview. What reported there is also valid in the case of a form, which is a render array nonetheless.

  • Libraries, JavaScript settings, feeds, HTML <head> tags and HTML <head> links are attached to elements using the #attached property.

    $build['#attached']['library'][] = 'core/jquery';
    $build['#attached']['drupalSettings']['foo'] = 'bar';
    $build['#attached']['feed'][] = [$url, $this->t('Feed title')];
  • To output generic HTML markup you use:

    • #type or #theme, which are preferable when the output is complex
    • #markup, which is preferable when the output is simple, considering also that its output is filtered by \Drupal\Component\Utility\Xss::filterAdmin(); in this case, if you need to output one of tags that is not listed in Xss::$adminTags, you need to use #allowed_tags

        '#type' => 'view',
        '#name' => $name,
        '#display_id' => $display_id,
        '#arguments' => $args,
        $form['contacts'] = array(
          '#type' => 'table',
          '#caption' => $this->t('Sample Table'),
          '#header' => array($this->t('Name'), $this->t('Phone')),

        for ($i=1; $i<=4; $i++) {
          $form['contacts'][$i]['name'] = array(
            '#type' => 'textfield',
            '#title' => $this->t('Name'),
            '#title_display' => 'invisible',

          $form['contacts'][$i]['phone'] = array(
            '#type' => 'tel',
            '#title' => $this->t('Phone'),
            '#title_display' => 'invisible',
        $output['filtered_string'] = array(
          '#markup' => '<audio controls><source src="horse.ogg" type="audio/ogg"><source src="horse.mp3" type="audio/mpeg">Your browser does not support the audio tag.</audio>',
          '#allowed_tags' => ['audio', 'source'],

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.