HTML inside Twitter Bootstrap popover
HtmlTwitter BootstrapPopoverHtml Problem Overview
I am trying to display HTML inside a bootstrap popover, but somehow it's not working. I found some answers here but it won't work for me. Please let me know if I'm doing something wrong.
<script>
$(function(){
$('[rel=popover]').popover({
html : true,
content: function() {
return $('#popover_content_wrapper').html();
}
});
});
</script>
<li href="#" id="example" rel="popover" data-content="" data-original-title="A Title">
popover
</li>
<div id="popover_content_wrapper" style="display: none">
<div>This is your div content</div>
</div>
Html Solutions
Solution 1 - Html
You cannot use <li href="#"
since it belongs to <a href="#"
that's why it wasn't working, change it and it's all good.
Here is working JSFiddle which shows you how to create bootstrap popover.
Relevant parts of the code is below:
HTML:
<!--
Note: Popover content is read from "data-content" and "title" tags.
-->
<a tabindex="0"
class="btn btn-lg btn-primary"
role="button"
data-html="true"
data-toggle="popover"
data-trigger="focus"
title="<b>Example popover</b> - title"
data-content="<div><b>Example popover</b> - content</div>">Example popover</a>
JavaScript:
$(function(){
// Enables popover
$("[data-toggle=popover]").popover();
});
And by the way, you always need at least $("[data-toggle=popover]").popover();
to enable the popover. But in place of data-toggle="popover"
you can also use id="my-popover"
or class="my-popover"
. Just remember to enable them using e.g: $("#my-popover").popover();
in those cases.
Here is the link to the complete spec: Bootstrap Popover
Bonus:
If for some reason you don't like or cannot read content of a popup from the data-content
and title
tags. You can also use e.g. hidden divs and a bit more JavaScript. Here is an example about that.
Solution 2 - Html
you can use attribute data-html="true"
:
<a href="#" id="example" rel="popover"
data-content="<div>This <b>is</b> your div content</div>"
data-html="true" data-original-title="A Title">popover</a>
Solution 3 - Html
Another way to specify the popover content in a reusable way is to create a new data attribute like data-popover-content
and use it like this:
HTML:
<!-- Popover #1 -->
<a class="btn btn-primary" data-placement="top" data-popover-content="#a1" data-toggle="popover" data-trigger="focus" href="#" tabindex="0">Popover Example</a>
<!-- Content for Popover #1 -->
<div class="hidden" id="a1">
<div class="popover-heading">
This is the heading for #1
</div>
<div class="popover-body">
This is the body for #1
</div>
</div>
JS:
$(function(){
$("[data-toggle=popover]").popover({
html : true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
});
This can be useful when you have a lot of html to place into your popovers.
Here is an example fiddle: http://jsfiddle.net/z824fn6b/
Solution 4 - Html
You need to create a popover instance that has the html option enabled (place this in your javascript file after the popover JS code):
$('.popover-with-html').popover({ html : true });
Solution 5 - Html
I used a pop over inside a list, Im giving an example via HTML
<a type="button" data-container="body" data-toggle="popover" data-html="true" data-placement="right" data-content='<ul class="nav"><li><a href="#">hola</li><li><a href="#">hola2</li></ul>'>
Solution 6 - Html
You only need put data-html="true"
in the link popover. Is gonna work.
Solution 7 - Html
This is an old question, but this is another way, using jQuery to reuse the popover and to keep using the original bootstrap data attributes to make it more semantic:
The link
<a href="#" rel="popover" data-trigger="focus" data-popover-content="#popover">
Show it!
</a>
Custom content to show
<!-- Let's show the Bootstrap nav on the popover-->
<div id="list-popover" class="hide">
<ul class="nav nav-pills nav-stacked">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
Javascript
$('[rel="popover"]').popover({
container: 'body',
html: true,
content: function () {
var clone = $($(this).data('popover-content')).clone(true).removeClass('hide');
return clone;
}
});
Fiddle with complete example: http://jsfiddle.net/tomsarduy/262w45L5/
Solution 8 - Html
This is a slight modification on Jack's excellent answer.
The following makes sure simple popovers, without HTML content, remain unaffected.
JavaScript:
$(function(){
$('[data-toggle=popover]:not([data-popover-content])').popover();
$('[data-toggle=popover][data-popover-content]').popover({
html : true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
});
Solution 9 - Html
I really hate to put long HTML inside of the attribute, here is my solution, clear and simple (replace ? with whatever you want):
<a class="btn-lg popover-dismiss" data-placement="bottom" data-toggle="popover" title="Help">
<h2>Some title</h2>
Some text
</a>
then
var help = $('.popover-dismiss');
help.attr('data-content', help.html()).text(' ? ').popover({trigger: 'hover', html: true});
Solution 10 - Html
On the latest version of bootstrap 4.6, you might also need to use sanitize:false
for adding complex html.
$('.popover-with-html').popover({ html : true, sanitize : false })
Solution 11 - Html
You can change the 'template/popover/popover.html' in file 'ui-bootstrap-tpls-0.11.0.js' Write: "bind-html-unsafe" instead of "ng-bind"
It will show all popover with html. *its unsafe html. Use only if you trust the html.
Solution 12 - Html
You can use the popover event, and control the width by attribute 'data-width'
$('[data-toggle="popover-huongdan"]').popover({ html: true });
$('[data-toggle="popover-huongdan"]').on("shown.bs.popover", function () {
var width = $(this).attr("data-width") == undefined ? 276 : parseInt($(this).attr("data-width"));
$("div[id^=popover]").css("max-width", width);
});
<a class="position-absolute" href="javascript:void(0);" data-toggle="popover-huongdan" data-trigger="hover" data-width="500" title="title-popover" data-content="html-content-code">
<i class="far fa-question-circle"></i>
</a>
Solution 13 - Html
Actually if you're using Bootstrap5 with Django then their method of passing in content as a string is perfect and in line with Django's template inclusion. You can create a template file with whatever partial HTML that you need, so for example, there is not X-editable for Bootstrap5 that seems to work, so maybe you'd want to make a line edit together with Ok|Cancel buttons as content. Anyway, this is what I mean:
<button data-bs-content="{% include './popover_content.html' %}" type="button" class="btn btn-lg btn-danger" data-bs-toggle="popover" title="Popover title" >
Click to toggle popover
</button>
Where my settings.py
templates section looks like this:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True, # True is necessary for django-bootstrap5 to work!
'OPTIONS': {
'debug': True,
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I keep my templates (of every single app) in a <project dir>/templates/<app name>
folder. I have MyMainApp/popover_content.html
right beside MyMainApp/home.html
wher the above example code was tested. But if you keep your templates in each app's Django folder, then you'll need to add "MyApp/templates" to the TEMPLATES[0]{'DIRS': ['MyApp/templates', 'MyApp2/templates']}
list.
So at least this will give you the ability to put your popover HTML in the usual, syntax-highlighted Django template format, and makes good use of modularizaton of your Django template into components.
I'm personally going to use it to make an editable label (title and description fields of some data in my app).
One drawback is that if you use doublequotes (") when including: "{% include './popover_content.html' %}", then you must use single quotes all throughout the
popover_content.html` template.
You also need to enable html for popovers, so your site-wide popover initializer would go:
<script type="text/javascript">
$(document).ready(() => {
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
var popoverList = popoverTriggerList.map(
function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl, {
html: true,
});
});
});
</script>
Here is the (unstyled) result. In conclusion, use the default-provided string method of passing in, and pass in an included Django template file. Problem solved!