Download Bootstrap bootable content using AJAX. Is it possible?

The relevant bits of what I tried are the following:

<a href="#" data-content="<div id='my_popover'></div>"> Click here </a> $(".button").popover({html: true}) $(".button").click(function(){ $(this).popover('show'); $("#my_popover").load('my_stuff') }) 

When I click, I see that the request is made, but does not populate the popover. I don’t even see HTML for popover added to the DOM, but it could be firebug.

Has anyone tried this?

+79
jquery twitter-bootstrap
Nov 15 2018-11-11T00:
source share
24 answers

See my blog post for a working solution: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4

First we need to add the data-poload attribute to the elements that you would like to add a popup. The content of this attribute must be the url to load (absolute or relative):

 <a href="#" title="blabla" data-poload="/test.php">blabla</a> 

And in JavaScript, preferably in $ (document) .ready ();

 $('*[data-poload]').hover(function() { var e=$(this); e.off('hover'); $.get(e.data('poload'),function(d) { e.popover({content: d}).popover('show'); }); }); 

off('hover') prevents data loading more than once, and popover() binding of a new hover event. If you want the data to be updated every time the event hangs, you must delete off.

Refer to the working JSFiddle example.

+93
Feb 01 '12 at 23:40
source share

Works fine for me:

 $('a.popup-ajax').popover({ "html": true, "content": function(){ var div_id = "tmp-id-" + $.now(); return details_in_popup($(this).attr('href'), div_id); } }); function details_in_popup(link, div_id){ $.ajax({ url: link, success: function(response){ $('#'+div_id).html(response); } }); return '<div id="'+ div_id +'">Loading...</div>'; } 
+101
Jan 28 '13 at 10:31
source share

After reading all these solutions, I think the solution becomes much easier if you use the synchronous ajax call. Then you can use something like:

  $('#signin').popover({ html: true, trigger: 'manual', content: function() { return $.ajax({url: '/path/to/content', dataType: 'html', async: false}).responseText; } }).click(function(e) { $(this).popover('toggle'); }); 
+20
Apr 21 '14 at 8:42
source share

By changing the code from Çağatay Gürtürk, you can use the delegate function and force a popover to hide during hoverout.

 $('body').delegate('.withajaxpopover','hover',function(event){ if (event.type === 'mouseenter') { var el=$(this); $.get(el.attr('data-load'),function(d){ el.unbind('hover').popover({content: d}).popover('show'); }); } else { $(this).popover('hide'); } }); 
+8
Mar 03 2018-12-12T00:
source share

Another solution:

 $target.find('.myPopOver').mouseenter(function() { if($(this).data('popover') == null) { $(this).popover({ animation: false, placement: 'right', trigger: 'manual', title: 'My Dynamic PopOver', html : true, template: $('#popoverTemplate').clone().attr('id','').html() }); } $(this).popover('show'); $.ajax({ type: HTTP_GET, url: "/myURL" success: function(data) { //Clean the popover previous content $('.popover.in .popover-inner').empty(); //Fill in content with new AJAX data $('.popover.in .popover-inner').html(data); } }); }); $target.find('.myPopOver').mouseleave(function() { $(this).popover('hide'); }); 

The idea here is to manually trigger a PopOver display with mouseenter and mouseleave events .

In mouseenter , if PopOver ( if ($ (this) .data ('popover'))> null) ) is not created for your element, create This. Interestingly, you can define your own PopOver content by passing it as an argument ( template ) to the popover () function. Remember to set the html parameter to true .

Here I just create a hidden template called popovertemplate and clone it using jQuery. Remember to remove the id attribute after cloning it , otherwise you will get duplicate identifiers in the DOM. Also note that style = "display: none" to hide the template on the page.

 <div id="popoverTemplateContainer" style="display: none"> <div id="popoverTemplate"> <div class="popover" > <div class="arrow"></div> <div class="popover-inner"> //Custom data here </div> </div> </div> </div> 

After the creation step (or if it has already been created) you simply display popOver with $ (this) .popover ('show');

Then a classic Ajax challenge. If successful, you need to clear the old popover content before entering new fresh data from the server . How can we get the current popover content? Using the .popover.in selector! The .in class indicates that a popover is currently being displayed, that the trick is here!

To complete the mouseleave event, just hide the popover.

+6
May 01 '12 at 21:31
source share

The decision of Chagatay Gyurtyurk is pleasant, but I experienced the same strangeness that Luke the Unclear spoke about:

When the ajax download takes too long (or the mouse events are too fast), we have .popover ('show') and no .popover ('hide') for this element, causing the popover to remain open.

I preferred this solution with massive loading, the entire contents of the popover loaded and the events are handled by bootstrap, as in regular (static) popovers.

 $('.popover-ajax').each(function(index){ var el=$(this); $.get(el.attr('data-load'),function(d){ el.popover({content: d}); }); }); 
+6
Oct 17 '12 at 22:00
source share

In 2015, this is the best answer.

 $('.popup-ajax').mouseenter(function() { var i = this $.ajax({ url: $(this).attr('data-link'), dataType: "html", cache:true, success: function( data{ $(i).popover({ html:true, placement:'left', title:$(i).html(), content:data }).popover('show') } }) }); $('.popup-ajax').mouseout(function() { $('.popover:visible').popover('destroy') }); 
+4
Feb 04 '15 at 18:18
source share

If the content in the popover is unlikely to change, it makes sense to get it only once. In addition, some of the solutions here are related to the fact that if you go through several “previews” quickly, you get several pop-ups open. This decision affects both of these things.

 $('body').on('mouseover', '.preview', function() { var e = $(this); if (e.data('title') == undefined) { // set the title, so we don't get here again. e.data('title', e.text()); // set a loader image, so the user knows we're doing something e.data('content', '<img src="/images/ajax-loader.gif" />'); e.popover({ html : true, trigger : 'hover'}).popover('show'); // retrieve the real content for this popover, from location set in data-href $.get(e.data('href'), function(response) { // set the ajax-content as content for the popover e.data('content', response.html); // replace the popover e.popover('destroy').popover({ html : true, trigger : 'hover'}); // check that we're still hovering over the preview, and if so show the popover if (e.is(':hover')) { e.popover('show'); } }); } }); 
+3
Aug 27 '13 at 14:10
source share

I think my solution is simpler with default functionality.

http://jsfiddle.net/salt/wbpb0zoy/1/

 $("a.popover-ajax").each(function(){ $(this).popover({ trigger:"focus", placement: function (context, source) { var obj = $(source); $.get(obj.data("url"),function(d) { $(context).html( d.titles[0].title) }); }, html:true, content:"loading" }); }); 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> <ul class="list-group"> <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Cras justo odio</a></li> <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Dapibus ac facilisis in</a></li> <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Morbi leo risus</a></li> <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Porta ac consectetur ac</a></li> <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Vestibulum at eros</a></li> </ul> 
+3
Dec 14 '15 at 9:57
source share

I updated the most popular answer. But if my changes are not approved, I will put a separate answer here.

Differences:

  • The downloaded text is displayed while the content is loading. Very good for slow connection.
  • Removed the flicker that occurs when the mouse leaves for the first time.

First we need to add the data-poload attribute to the elements that you would like to add a popup. The content of this attribute must be the url to load (absolute or relative):

 <a href="#" data-poload="/test.php">HOVER ME</a> 

And in JavaScript, preferably in $ (document) .ready ();

  // On first hover event we will make popover and then AJAX content into it. $('[data-poload]').hover( function (event) { var el = $(this); // disable this event after first binding el.off(event); // add initial popovers with LOADING text el.popover({ content: "loading…", // maybe some loading animation like <img src='loading.gif /> html: true, placement: "auto", container: 'body', trigger: 'hover' }); // show this LOADING popover el.popover('show'); // requesting data from unsing url from data-poload attribute $.get(el.data('poload'), function (d) { // set new content to popover el.data('bs.popover').options.content = d; // reshow popover with new content el.popover('show'); }); }, // Without this handler popover flashes on first mouseout function() { } ); 

off('hover') prevents data loading more than once, and popover() binding of a new hover event. If you want the data to be updated every time the event hangs, you must delete off.

See a working JSFiddle example.

+3
May 26 '16 at 10:35
source share

Here is my solution that works great with ajax loaded content.

 /* * popover handler assigned document (or 'body') * triggered on hover, show content from data-content or * ajax loaded from url by using data-remotecontent attribute */ $(document).popover({ selector: 'a.preview', placement: get_popover_placement, content: get_popover_content, html: true, trigger: 'hover' }); function get_popover_content() { if ($(this).attr('data-remotecontent')) { // using remote content, url in $(this).attr('data-remotecontent') $(this).addClass("loading"); var content = $.ajax({ url: $(this).attr('data-remotecontent'), type: "GET", data: $(this).serialize(), dataType: "html", async: false, success: function() { // just get the response }, error: function() { // nothing } }).responseText; var container = $(this).attr('data-rel'); $(this).removeClass("loading"); if (typeof container !== 'undefined') { // show a specific element such as "#mydetails" return $(content).find(container); } // show the whole page return content; } // show standard popover content return $(this).attr('data-content'); } function get_popover_placement(pop, el) { if ($(el).attr('data-placement')) { return $(el).attr('data-placement'); } // find out the best placement // ... cut ... return 'left'; } 
+2
May 15 '13 at 7:11
source share

I tried ağatay Gürtürk's solution, but got the same weirdness as Luke the Unclear. Then I tried the solution of Asa Kusuma. This works, but I believe that Ajax is read every time a popover is displayed. A call to unleash (“freeze”) has no effect. This is because the delegate keeps track of events in a particular class, but this class does not change.

Here is my decision, closely related to Asa Kusuma. Changes:

  • Replaced delegate with on to match new jQuery libraries.
  • Remove the 'withajaxpopover' class instead of expanding the hover event (which has never been connected)
  • Add "trigger: hover" to the popover so that Bootstrap will fully process it starting from the second use.
  • The data loading function returns JSon, making it easy to specify the title and content for a popover.
     / * Goal: Display a tooltip / popover where the content is fetched from the
               application the first time only.

         How: Fetch the appropriate content and register the tooltip / popover the first time 
               the mouse enters a DOM element with class "withajaxpopover".  Remove the 
               class from the element so we don't do that the next time the mouse enters.
               However, that doesn't show the tooltip / popover for the first time
               (because the mouse is already entered when the tooltip is registered).
               So we have to show / hide it ourselves.
     * /
     $ (function () {
       $ ('body'). on ('hover', '.withajaxpopover', function (event) {
           if (event.type === 'mouseenter') {
               var el = $ (this);
               $ .get (el.attr ('data-load'), function (d) {
                   el.removeClass ('withajaxpopover')
                   el.popover ({trigger: 'hover', 
                               title: d.title, 
                               content: d.content}). popover ('show');
               });
           } else {
               $ (this) .popover ('hide');
           }
       });
     });
+1
Dec 12 '12 at 22:20
source share

I tried some of the suggestions here, and I would like to introduce my own (which is slightly different) - I hope this helps someone. I wanted to show the popup from the first click and hide it on the second click (of course, with updating the data every time). I used the optional visable variable to find out if the popover is visible or not. Here is my code: HTML:

 <button type="button" id="votingTableButton" class="btn btn-info btn-xs" data-container="body" data-toggle="popover" data-placement="left" >Last Votes</button> 

JavaScript:

 $('#votingTableButton').data("visible",false); $('#votingTableButton').click(function() { if ($('#votingTableButton').data("visible")) { $('#votingTableButton').popover("hide"); $('#votingTableButton').data("visible",false); } else { $.get('votingTable.json', function(data) { var content = generateTableContent(data); $('#votingTableButton').popover('destroy'); $('#votingTableButton').popover({title: 'Last Votes', content: content, trigger: 'manual', html:true}); $('#votingTableButton').popover("show"); $('#votingTableButton').data("visible",true); }); } }); 

Hurrah!

+1
Feb 10 '14 at 16:18
source share
 <button type="button" id="popover2" title="" data-content="<div id='my_popover' style='height:250px;width:300px;overflow:auto;'>Loading...Please Wait</div>" data-html="true" data-toggle="popover2" class="btn btn-primary" data-original-title="A Title">Tags</button> $('#popover2').popover({ html : true, title: null, trigger: "click", placement:"right" }); $("#popover2").on('shown.bs.popover', function(){ $('#my_popover').html("dynamic content loaded"); }); 
+1
Dec 01 '16 at 10:36
source share

an answer similar to this one was given in this thread: Setting data contents and displaying popover is the best way to do what you hope to achieve, otherwise you will have to use the live: true option in the parameters of the popover method. Hope this helps

0
Nov 22 2018-11-11T00:
source share
 $("a[rel=popover]").each(function(){ var thisPopover=$(this); var thisPopoverContent =''; if('you want a data inside an html div tag') { thisPopoverContent = $(thisPopover.attr('data-content-id')).html(); }elseif('you want ajax content') { $.get(thisPopover.attr('href'),function(e){ thisPopoverContent = e; }); } $(this).attr( 'data-original-title',$(this).attr('title') ); thisPopover.popover({ content: thisPopoverContent }) .click(function(e) { e.preventDefault() }); }); 

Note that I used the same href tag and made it so that it does not change pages when clicked, this is good for SEO, and also if the user does not have javascript!

0
Feb 22 '12 at 20:18
source share

I like ağatay's solution, but I did not hide the pop-ups from the mouse. I added this extra functionality:

 // hides the popup $('*[data-poload]').bind('mouseout',function(){ var e=$(this); e.popover('hide'); }); 
0
Mar 21 '13 at 21:49
source share

I used the original solution, but made a couple of changes:

At first I used getJSON() instead of get() , because I was loading the json script. Then I added trigger freeze behavior to fix the sticky problem.

 $('*[data-poload]').on('mouseover',function() { var e=$(this); $.getJSON(e.data('poload'), function(data){ var tip; $.each(data, function (index, value) { tip = this.tip; e.popover({content: tip, html: true, container: 'body', trigger: 'hover'}).popover('show'); }); }); }); 
0
Oct 22 '13 at 19:29
source share

I added html: true, so it does not display the original html output if you want to format the results. You can also add more controls.

  $('*[data-poload]').bind('click',function() { var e=$(this); e.unbind('click'); $.get(e.data('poload'),function(d) { e.popover({content: d, html: true}).popover('show', { }); }); }); 
0
Jul 12 '14 at 12:10
source share

Show ajax popover on a static element with a hover trigger:

 $('.hover-ajax').popover({ "html": true, trigger: 'hover', "content": function(){ var div_id = "tmp-id-" + $.now(); return details_in_popup($(this).attr('href'), div_id); } }); function details_in_popup(link, div_id){ $.ajax({ url: link, success: function(response){ $('#'+div_id).html(response); } }); return '<div id="'+ div_id +'">Loading...</div>'; } 

Html:

 <span class="hover-ajax" href="http://domain.tld/file.php"> Hey , hoover me ! </span> 
0
Jan 26 '15 at 0:34
source share
  $('[data-poload]').popover({ content: function(){ var div_id = "tmp-id-" + $.now(); return details_in_popup($(this).data('poload'), div_id, $(this)); }, delay: 500, trigger: 'hover', html:true }); function details_in_popup(link, div_id, el){ $.ajax({ url: link, cache:true, success: function(response){ $('#'+div_id).html(response); el.data('bs.popover').options.content = response; } }); return '<div id="'+ div_id +'"><i class="fa fa-spinner fa-spin"></i></div>'; } 

Ajax content loads once! see el.data('bs.popover').options.content = response;

0
Mar 25 '15 at 11:47
source share

I did, and it works fine with ajax and loads popover content.

 var originalLeave = $.fn.popover.Constructor.prototype.leave; $.fn.popover.Constructor.prototype.leave = function(obj){ var self = obj instanceof this.constructor ? obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) var container, timeout; originalLeave.call(this, obj); if(obj.currentTarget) { container = $(obj.currentTarget).siblings('.popover') timeout = self.timeout; container.one('mouseenter', function(){ //We entered the actual popover – call off the dogs clearTimeout(timeout); //Let monitor popover content instead container.one('mouseleave', function(){ $.fn.popover.Constructor.prototype.leave.call(self, self); }); }) } }; var attr = 'tooltip-user-id'; if ($('a['+ attr +']').length) $('a['+ attr +']').popover({ html: true, trigger: 'click hover', placement: 'auto', content: function () { var this_ = $(this); var userId = $(this).attr(attr); var idLoaded = 'tooltip-user-id-loaded-' + userId; var $loaded = $('.' + idLoaded); if (!$loaded.length) { $('body').append('<div class="'+ idLoaded +'"></div>'); } else if ($loaded.html().length) { return $loaded.html(); } $.get('http://example.com', function(data) { $loaded.html(data); $('.popover .popover-content').html(data); this_.popover('show'); }); return '<img src="' + base_url + 'assets/images/bg/loading.gif"/>'; }, delay: {show: 500, hide: 1000}, animation: true }); 

You can check it out at http://kienthuchoidap.com . Go to this and hover over your username.

0
Jun 09 '15 at 1:32
source share

For me, work changes the content data before downloading:

 $('.popup-ajax').data('content', function () { var element = this; $.ajax({ url: url, success: function (data) { $(element).attr('data-content', data) $(element).popover({ html: true, trigger: 'manual', placement: 'left' }); $(element).popover('show') }}) }) 
0
Apr 25 '17 at 14:24
source share

This works for me, this code fix solves alignment problems:

 <a class="ajax-popover" data-container="body" data-content="Loading..." data-html="data-html" data-placement="bottom" data-title="Title" data-toggle="popover" data-trigger="focus" data-url="your_url" role="button" tabindex="0" data-original-title="" title=""> <i class="fa fa-info-circle"></i> </a> $('.ajax-popover').click(function() { var e = $(this); if (e.data('loaded') !== true) { $.ajax({ url: e.data('url'), dataType: 'html', success: function(data) { e.data('loaded', true); e.attr('data-content', data); var popover = e.data('bs.popover'); popover.setContent(); popover.$tip.addClass(popover.options.placement); var calculated_offset = popover.getCalculatedOffset(popover.options.placement, popover.getPosition(), popover.$tip[0].offsetWidth, popover.$tip[0].offsetHeight); popover.applyPlacement(calculated_offset, popover.options.placement); }, error: function(jqXHR, textStatus, errorThrown) { return instance.content('Failed to load data'); } }); } }); 

Just in case, the endpoint I use returns html (partial rail)

I took part of the code here https://stackoverflow.com/a/166778/

0
Nov 22 '17 at 20:04 on
source share



All Articles