4

I am new to Drupal 8. I am trying to implement Chart js in Drupal 8.

I am trying to create a <canvas> element to load the chart. But while rendering the page, <canvas> element is getting removed automatically.
Below the controller code.

class DashboardController extends ControllerBase {

  public function content() {

    return array(
        '#type' => 'markup',
        '#markup'   =>  '<div class="chart"><canvas id="test"></canvas></div>',
    );
  }
}

Here, I am getting only <div class="chart"></div>

I am unable to find the canvas in the page. Because of that, chart is not getting loaded.

Anyone help me to figure out the exact problem.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Edwin Alex
  • 5,118
  • 4
  • 28
  • 50

3 Answers3

2

Apologies for the late answer but having stumbled upon this issue myself, there are two "correct" ways of doing this.

From 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.

So you can either implement a theme hook or do something a bit less elegant:

use Drupal\Component\Utility\Xss;

class DashboardController extends ControllerBase {

  public function content() {

    return array(
        '#type' => 'markup',
        '#markup'   =>  '<div class="chart"><canvas id="test"></canvas></div>',
        '#allowed_tags' => array_merge(Xss::getHtmlTagList(), ['canvas', 'div'])
    );
  }
}
Jamie Hollern
  • 154
  • 3
  • 15
1

This solved my problem. Thanks Jamie.

return array(
    '#type' => 'markup',
    '#markup'   =>  '<div class="chart"><canvas id="test"></canvas></div>',
    '#allowed_tags' => array_merge(Xss::getHtmlTagList(), ['canvas', 'div'])
);

We have other options for Xss (based on admin or non-admin users).

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Component%21Utility%21Xss.php/class/Xss/8.2.x

0

What's happening is that the <canvas> element is getting removed automatically by drupal (duh). I don't know how to stop it, but I do have a work around. You can use the javascript to add the canvas into the document programmatically. Since it's already running javascript it's not too hard to add those elements you need to get it to work in with the javascript.

  $("#chart").append("<canvas id=\"test\">");

This code is saying your div has an <div id="chart"></div> then simply adds the canvas tag in there in the javascript rather than through drupal. Uses JQuery but you can do it without it.

Community
  • 1
  • 1
Tatarize
  • 10,238
  • 4
  • 58
  • 64