function public function Element::smartDescription

8.x-3.x Element.php public Element::smartDescription(&$target_element = NULL, $input_only = TRUE, $length = NULL)

Converts an element description into a tooltip based on certain criteria.


array|\Drupal\bootstrap\Utility\Element|null $target_element: The target element render array the tooltip is to be attached to, passed by reference or an existing Element object. If not set, it will default this Element instance.

bool $input_only: Toggle determining whether or not to only convert input elements.

int $length: The length of characters to determine if description is "simple".

Return value



Provides helper methods for Drupal render elements.



Source src/Utility/Element.php (line 760)

public function smartDescription(&$target_element = NULL, $input_only = TRUE, $length = NULL) {
  static $theme;
  if (!isset($theme)) {
    $theme = Bootstrap::getTheme();

  // Determine if tooltips are enabled.
  static $enabled;
  if (!isset($enabled)) {
    $enabled = $theme->getSetting('tooltip_enabled') && $theme->getSetting('forms_smart_descriptions');

  // Immediately return if tooltip descriptions are not enabled.
  if (!$enabled) {
    return $this;

  // Allow a different element to attach the tooltip.
  /** @var \Drupal\bootstrap\Utility\Element $target */
  if (is_object($target_element) && $target_element instanceof self) {
    $target = $target_element;
  elseif (isset($target_element) && is_array($target_element)) {
    $target = new self($target_element, $this->formState);
  else {
    $target = $this;

  // For "password_confirm" element types, move the target to the first
  // textfield.
  if ($target->isType('password_confirm')) {
    $target = $target->pass1;

  // Retrieve the length limit for smart descriptions.
  if (!isset($length)) {
    // Disable length checking by setting it to FALSE if empty.
    $length = (int) $theme->getSetting('forms_smart_descriptions_limit') ? : FALSE;

  // Retrieve the allowed tags for smart descriptions. This is primarily used
  // for display purposes only (i.e. non-UI/UX related elements that wouldn't
  // require a user to "click", like a link). Disable length checking by
  // setting it to FALSE if empty.
  static $allowed_tags;
  if (!isset($allowed_tags)) {
    $allowed_tags = array_filter(array_unique(array_map('trim', explode(',', $theme->getSetting('forms_smart_descriptions_allowed_tags') . '')))) ? : FALSE;

  // Return if element or target shouldn't have "simple" tooltip descriptions.
  $html = FALSE;

  // If the description is a render array, it must first be pre-rendered so
  // it can be later passed to Unicode::isSimple() if needed.
  $description = $this->hasProperty('description') ? $this->getProperty('description') : FALSE;
  if (static::isRenderArray($description)) {
    $description = static::createStandalone($description)->renderPlain();

  if (
  // Ignore if element has no #description.

    // Ignore if description is not a simple string or MarkupInterface.
     || (!is_string($description) && !($description instanceof MarkupInterface))

      // Ignore if element is not an input.
       || ($input_only && !$target->hasProperty('input'))

      // Ignore if the target element already has a "data-toggle" attribute set.
       || $target->hasAttribute('data-toggle')

      // Ignore if the target element is #disabled.
       || $target->hasProperty('disabled')

      // Ignore if either the actual element or target element has an explicit
      // #smart_description property set to FALSE.
       || !$this->getProperty('smart_description', TRUE)
     || !$target->getProperty('smart_description', TRUE)

      // Ignore if the description is not "simple".
       || !Unicode::isSimple($description, $length, $allowed_tags, $html)
    ) {
    // Set the both the actual element and the target element
    // #smart_description property to FALSE.
    $this->setProperty('smart_description', FALSE);
    $target->setProperty('smart_description', FALSE);
    return $this;

  // Default attributes type.
  $type = DrupalAttributes::ATTRIBUTES;

  // Use #label_attributes for 'checkbox' and 'radio' elements.
  if ($this->isType(['checkbox', 'radio'])) {
    $type = DrupalAttributes::LABEL;
  // Use #wrapper_attributes for 'checkboxes' and 'radios' elements.
  elseif ($this->isType(['checkboxes', 'radios'])) {
    $type = DrupalAttributes::WRAPPER;

  // Retrieve the proper attributes array.
  $attributes = $target->getAttributes($type);

  // Set the tooltip attributes.
  $attributes['title'] = $allowed_tags !== FALSE ? Xss::filter((string) $description, $allowed_tags) : $description;
  $attributes['data-toggle'] = 'tooltip';
  if ($html || $allowed_tags === FALSE) {
    $attributes['data-html'] = 'true';

  // Remove the element description so it isn't (re-)rendered later.

  return $this;