Why isn't HTML working in Bootstrap v5 Popover?

Viewed 88

When I add HTML into my Bootstrap v5 popover, it does not display the HTML in the popover. I believe that I have all of the correct options passed as described in the docs. Almost all of the results which I've gotten from searches to try and understand this issue deal with Bootstrap v4 and v3, so they aren't of use to me.

The popover all of the way on the right should have the switch affordance ("Toggle") appear below "Hello World" in the popover. The HTML code is present.

Bootstrap v5 HTML Popover Not Working

The code of the above tests centers around these 3 affordances:

<!-- Popover Works -->
<span class="fs-3 actions-link-style ai-more-horizontal" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" title="Title" data-bs-sanitize="false" data-bs-html="true" data-bs-content="Hello World"></span>

<!-- HTML Switch Works -->
<div class='form-check form-switch'><input type='checkbox' class='form-check-input' id='customSwitch1'><label class='form-check-label' for='customSwitch1'>Toggle</label></div>

<!-- Popover with HTML Switch Does Not Work -->
<span class="fs-3 actions-link-style ai-more-horizontal" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" title="Title" data-bs-sanitize="false" data-bs-html="true" data-bs-content="Hello World<br><div class='form-check form-switch'><input type='checkbox' class='form-check-input' id='customSwitch2'><label class='form-check-label' for='customSwitch2'>Toggle</label></div>"></span>

Have I missed something? Please let me know. Thank you!

2 Answers

Ok, reading and re-reading the Bootstrap v5 documentation's fine print finally led me to the solution.

Even though data-bs-sanitize="false" is a valid option that can be passed, per the documentation... the documentation also notes elsewhere that:

Note that for security reasons the sanitize, sanitizeFn, and allowList options cannot be supplied using data attributes.

So... in order for the HTML to execute, because data-bs-sanitize="false" is ignored, one has to manually add non-default values to the Sanitizer whitelist which are used with the HTML code inside the popover. In my case, they were as follows:

var myDefaultAllowList = bootstrap.Tooltip.Default.allowList

// To allow elements
myDefaultAllowList.input = ['type', 'checked']
myDefaultAllowList.label = ['for']

And now... it's working as intended. A lesson in sanitization.

I'm not sure if you initialize the popovers correctly as data-bs-sanitize="false" should allow any html used.
You are adding elements that are not in the bootstrap.Tooltip.Default.allowList object. So to allow the elements and attributes used in your code the following config options will work to render the popover as intended:

$(document).ready(function() {
  const myDefaultAllowList = bootstrap.Tooltip.Default.allowList
  // To allow elements and attributes on elements
  myDefaultAllowList.input = ['type', 'checked']
  myDefaultAllowList.label = ['for']

  $('[data-bs-toggle="popover"]').popover({
    allowList: myDefaultAllowList,
    html: true
  })

  /* or just disable the sanitzer
  $('[data-bs-toggle="popover"]').popover({
    sanitize: false
  })
  */
})
<link rel="stylesheet" media="screen" href="https://hopspin.com/testing/testing2.css">
<link rel="stylesheet" media="screen" href="https://hopspin.com/testing/testing3.css">
<link rel="stylesheet" media="screen" href="https://hopspin.com/testing/testing.css">

<div class="container">
  <div class="row" style="padding-top: 15em !important;">
    <!-- Body -->
    <div class="col-lg-12 content py-4 mb-2 mb-sm-0 pb-sm-1 no-sidebar-padding-override">
      <div class="row row-panel-hs">
        <div class="row section-container-bottom row-section-hs">
          <table class="table keep-table-fixed no-margin-bottom entities-table">
            <tbody>
              <tr>
                <td>Work alone:
                </td>
                <td>
                  <!-- Popover Works -->
                  <span class="fs-3 actions-link-style ai-more-horizontal" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" title="" data-bs-sanitize="false" data-bs-html="true" data-bs-content="Hello World" data-bs-original-title="Title" aria-label="Title"></span>

                </td>
                <td>
                  <!-- HTML Switch Works -->
                  <div class="form-check form-switch"><input type="checkbox" class="form-check-input" id="customSwitch1"><label class="form-check-label" for="customSwitch1">Toggle</label></div>

                </td>
                <td>
                </td>
                <td>
                </td>
                <td>Fail combined:
                </td>
                <td>
                  <!-- Popover with HTML Switch Does Not Work -->
                  <span class="fs-3 actions-link-style ai-more-horizontal" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" title="" data-bs-sanitize="false" data-bs-html="true" data-bs-content="Hello World<br><div class='form-check form-switch'><input type='checkbox' class='form-check-input' id='customSwitch2'><label class='form-check-label' for='customSwitch2'>Toggle</label></div>"
                    data-bs-original-title="Title" aria-label="Title">...</span>

                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>

Note:

You need to do more work in order to preserve the checked state of the toggle. As it is, the toggle reverts back to the initial state when closed and re-opened. Fixing this would be a different question.

Related