rishabh318
rishabh318

Reputation: 117

Working with forms in drupal 8

I am facing problem with "#markup" in form API.

In Drupal 7 we can use "#markup" form element which look like this:

<?php
$form['test'] = array(
    '#type' => 'markup',
    '#markup' => '<div><script src="http://localhost/drupal7/sites/all/libraries/test.js"></script></div>',
  );
?>
//Here is my custom test.js
(function($) {
    Drupal.behaviors.test = {
        attach: function(context, settings) {
            console.log('testttt');
            document.write('*Hello, there!*');
        }
    };
})(jQuery);

and above code will print "Hello, there!" when form will be render.

Now in Drupal 8 I am using below code but it prints nothing.

<?php
$form['test'] = array(
      '#markup' => '<div><script src="http://localhost/project8/sites/all/libraries/test.js"></script></div>',
    );
?>

So how can implement this functionality in Drupal 8, which is already working in Drupal 7 . Under script tag it can be local script or external script.. Please help...

Thanks

Upvotes: 1

Views: 4417

Answers (2)

Jose D
Jose D

Reputation: 499

In Drupal 8, using "#markup" is not the proposed method to attach javascript files. You can define libraries in your custom module or theme and attach the library to your form. The library can contain multiple js and (or) css files.

To define a library in your module:

Suppose your module name is "my_module", create a file "my_module.libraries.yml" in your module folder and specify the js and css files like this

form-script:
  version: 1.x
  css:
    theme:
      css/form.css: {}
  js:
    js/form.js: {}
    js/form-ajax.js: {}
  dependencies:
    - core/jquery

In order to attach this library to your form:

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

Then clear cache. The js and css files will be loaded in the same order as you mentioned in the libraries.yml file. You can define multiple libraries in the same "my_module.libraries.yml" file.

Upvotes: 3

Stanislav Agapov
Stanislav Agapov

Reputation: 956

#markup still works in Drupal 8, but now it is filtered before output. As it is stated in Render API overview:

#markup: Specifies that the array provides HTML markup directly. Unless the markup is very simple, such as an explanation in a paragraph tag, it is normally preferable to use #theme or #type instead, so that the theme can customize the markup. Note that the value is passed through \Drupal\Component\Utility\Xss::filterAdmin(), which strips known XSS vectors while allowing a permissive list of HTML tags that are not XSS vectors. (I.e, and are not allowed.) See \Drupal\Component\Utility\Xss::$adminTags for the list of tags that will be allowed. If your markup needs any of the tags that are not in this whitelist, then you can implement a theme hook and template file and/or an asset library. Aternatively, you can use the render array key #allowed_tags to alter which tags are filtered.

As an alternative you may use FormattableMarkup:

'#markup' => new FormattableMarkup('<div><script src="http://localhost/project8/sites/all/libraries/test.js"></script></div>', []),

though it is not recommended in this case.

Upvotes: 1

Related Questions