Odpowiednie fragmenty tego, co wypróbowałem, są tutaj:
<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')
})
Kiedy klikam, widzę, że żądanie zostało wysłane, ale nie wypełnia okna popover. Nie widzę nawet, aby HTML popover został dodany do DOM, ale to może być firebug.
Czy ktoś tego próbował?
jquery
twitter-bootstrap
CambridgeMike
źródło
źródło
'shown.bs.popover'
module obsługi: stackoverflow.com/a/39028723/1371408Odpowiedzi:
Zobacz mój post na blogu dotyczący działającego rozwiązania: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4
<a href="#" title="blabla" data-poload="/test.php">blabla</a>
$('*[data-poload]').hover(function() { var e=$(this); e.off('hover'); $.get(e.data('poload'),function(d) { e.popover({content: d}).popover('show'); }); });
źródło
html
właściwośćtrue
, a następnie ustawićcontent
właściwość znacznika iframe HTML, jakcontent: '<iframe src="http://www.google.com"></iframe>'
. Będziesz także musiał nadpisaćmax-width
właściwość swojego popover za pomocą CSS i najprawdopodobniej usunąć styl elementu iframe również za pomocą CSS.e.off('hover')
metodyU mnie działa dobrze:
$('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>'; }
źródło
Po przeczytaniu wszystkich tych rozwiązań myślę, że rozwiązanie staje się znacznie prostsze, jeśli używasz synchronicznego wywołania Ajax. Możesz wtedy użyć czegoś takiego:
$('#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'); });
źródło
async: false
zabija to dla mnieZaktualizowałem najpopularniejszą odpowiedź. Ale na wypadek, gdyby moje zmiany nie zostały zatwierdzone, zamieszczam tutaj oddzielną odpowiedź.
Różnice to:
Najpierw powinniśmy dodać atrybut data-poload do elementów, do których chcesz dodać pop. Treść tego atrybutu powinna być adresem URL do załadowania (bezwzględnym lub względnym):
<a href="#" data-poload="/test.php">HOVER ME</a>
Oraz w JavaScript, najlepiej w $ (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')
zapobiega ładowaniu danych więcej niż raz ipopover()
wiąże nowe zdarzenie najechania. Jeśli chcesz, aby dane były odświeżane przy każdym zdarzeniu najechania myszą, usuń wyłączenie.Zobacz działający JSFiddle przykładu.
źródło
Odmiana kodu z Çağatay Gürtürk, możesz zamiast tego użyć funkcji delegata i wymusić ukrycie popovera po najechaniu myszą.
$('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'); } });
źródło
Rozwiązanie Çağatay Gürtürk jest fajne, ale doświadczyłem tej samej dziwności, którą opisał Luke The Obscure:
Gdy ładowanie AJAX trwa zbyt długo (lub zdarzenia myszy są zbyt szybkie), mamy plik .popover ('show') i brak pliku .popover ('hide') na danym elemencie, co powoduje, że popover pozostaje otwarty.
Wolałem to rozwiązanie masowego ładowania wstępnego, wszystkie treści popover są ładowane, a zdarzenia są obsługiwane przez bootstrap, jak w normalnych (statycznych) popoverach.
$('.popover-ajax').each(function(index){ var el=$(this); $.get(el.attr('data-load'),function(d){ el.popover({content: d}); }); });
źródło
W 2015 roku to najlepsza odpowiedź
$('.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') });
źródło
Inne rozwiązanie:
$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'); });
Chodzi o to, aby ręcznie uruchomić wyświetlanie PopOver za pomocą zdarzeń mouseenter i mouseleave .
W mouseenter , jeśli nie ma utworzonego PopOver dla twojego elementu ( if ($ (this) .data ('popover') == null) ), utwórz go. Co ciekawe, możesz zdefiniować własną zawartość PopOver, przekazując ją jako argument ( szablon ) do funkcji popover () . Nie zapomnij również ustawić parametru html na true .
Tutaj po prostu tworzę ukryty szablon o nazwie popovertemplate i sklonuję go za pomocą JQuery. Nie zapomnij usunąć atrybutu id po jego sklonowaniu, w przeciwnym razie w DOMU będziesz miał zduplikowane identyfikatory. Zauważ również, że style = "display: none", aby ukryć szablon na stronie.
<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>
Po kroku tworzenia (lub jeśli został już utworzony), po prostu wyświetl popOver z $ (this) .popover ('show');
Następnie klasyczne sprawdzenie Ajax. Jeśli się powiedzie, musisz wyczyścić starą zawartość popover przed umieszczeniem nowych, świeżych danych z serwera . Jak możemy pobrać aktualną zawartość Popover? Z selektorem .popover.in ! Plik .in klasa wskazuje, że aktualnie wyświetlana jest popover, że to podstęp tutaj!
Aby zakończyć, w przypadku mouseleave , po prostu ukryj popover.
źródło
Oto moje rozwiązanie, które działa dobrze również z zawartością załadowaną przez AJAX.
/* * 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'; }
źródło
Jeśli zawartość popover prawdopodobnie się nie zmieni, warto byłoby ją pobrać tylko raz. Ponadto w przypadku niektórych rozwiązań występuje problem polegający na tym, że jeśli szybko przejdziesz przez wiele „podglądów”, pojawi się wiele otwartych wyskakujących okienek. To rozwiązanie rozwiązuje obie te kwestie.
$('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'); } }); } });
źródło
Myślę, że moje rozwiązanie jest prostsze z domyślną funkcjonalnością.
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>
źródło
Wypróbowałem rozwiązanie autorstwa Çağatay Gürtürk, ale uzyskałem taką samą dziwność jak Łukasz Niejasny. Następnie wypróbowałem rozwiązanie Asy Kusumy. To działa, ale wierzę, że Ajax czyta za każdym razem, gdy wyświetlane jest okienko popover. Wezwanie do rozwiązania wiązania („hover”) nie ma żadnego efektu. Dzieje się tak, ponieważ delegat monitoruje zdarzenia w określonej klasie - ale ta klasa pozostaje niezmieniona.
Oto moje rozwiązanie, ściśle oparte na rozwiązaniu Asy Kusumy. Zmiany:
delegate
zon
dopasować nowe biblioteki jQuery.źródło
Wypróbowałem kilka propozycji tutaj i chciałbym przedstawić swoją (która jest nieco inna) - mam nadzieję, że komuś pomoże. Chciałem pokazać wyskakujące okienko przy pierwszym kliknięciu i ukryć je przy drugim (oczywiście z każdorazową aktualizacją danych). Użyłem dodatkowej zmiennej,
visable
aby dowiedzieć się, czy popover jest widoczny, czy nie. Oto mój kod: 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); }); } });
Twoje zdrowie!
źródło
<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"); });
źródło
Oto sposób, który rozwiązuje kilka problemów:
._popper.update()
, co przelicza pozycję popovera.max-width
).var e = $("#whatever"); e.popover({ placement: "top", trigger: "hover", title: "Test Popover", content: "<span class='content'>Loading...</span>", html: true }).on("inserted.bs.popover", function() { var popover = e.data('bs.popover'); var tip = $(popover.tip); tip.css("width", "100%"); $.ajax("/whatever") .done(function(data) { tip.find(".content").text(data); popover._popper.update(); }).fail(function() { tip.find(".content").text("Sorry, something went wrong"); }); });
źródło
popover._popper.update()
i upewnij się, żepopover
,_popper
iupdate
wszyscy mają wartości oczekiwane. Jest z pewnością możliwe, że uległy zmianie.Jest tu o wiele za dużo odpowiedzi, ale nie znalazłem też żadnej z nich, która jest tym, czego chciałem. Rozszerzyłem odpowiedź Ivana Klassa, aby zarówno Bootstrap 4 był odpowiedni, jak i inteligentnie buforowany.
Zwróć uwagę, że fragment kodu w rzeczywistości nie załaduje adresu zdalnego z powodu zasad CORS Stackoverflow.
var popoverRemoteContents = function(element) { if ($(element).data('loaded') !== true) { var div_id = 'tmp-id-' + $.now(); $.ajax({ url: $(element).data('popover-remote'), success: function(response) { $('#' + div_id).html(response); $(element).attr("data-loaded", true); $(element).attr("data-content", response); return $(element).popover('update'); } }); return '<div id="' + div_id + '">Loading...</div>'; } else { return $(element).data('content'); } }; $('[data-popover-remote]').popover({ html: true, trigger: 'hover', content: function() { return popoverRemoteContents(this); } });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/> <span data-popover-remote="http://example.com/">Remote Popover test with caching</span>
źródło
odpowiedź podobną do tej została udzielona w tym wątku: Ustawianie zawartości danych i wyświetlanie popover - jest to o wiele lepszy sposób na zrobienie tego, co chcesz osiągnąć. W przeciwnym razie będziesz musiał użyć opcji live: true w opcjach metody popover. Mam nadzieję, że to pomoże
źródło
$("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() }); });
zwróć uwagę, że użyłem tego samego tagu href i zrobiłem to tak, aby nie zmieniał stron po kliknięciu, jest to dobra rzecz dla SEO, a także jeśli użytkownik nie ma javascript!
źródło
Podoba mi się rozwiązanie Çağatay, ale wyskakujące okienka nie chowały się po wyprowadzeniu myszy. Dodałem tę dodatkową funkcjonalność w ten sposób:
// hides the popup $('*[data-poload]').bind('mouseout',function(){ var e=$(this); e.popover('hide'); });
źródło
Użyłem oryginalnego rozwiązania, ale wprowadziłem kilka zmian:
Po pierwsze, użyłem
getJSON()
zamiast,get()
ponieważ ładowałem skrypt json. Następnie dodałem wyzwalające zachowanie kursora, aby naprawić problem z lepkim wyskakującym okienkiem.$('*[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'); }); }); });
źródło
Dodałem html: true, więc nie wyświetla surowego wyjścia html, na wypadek, gdybyś chciał sformatować swoje wyniki. Możesz także dodać więcej elementów sterujących.
$('*[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', { }); }); });
źródło
Wyświetl wyskakujące okienko Ajax w elemencie statycznym z wyzwalaczem aktywowania:
$('.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>
źródło
$('[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>'; }
Zawartość Ajax jest ładowana raz! widzieć
el.data('bs.popover').options.content = response;
źródło
Zrobiłem i działa doskonale z Ajax i ładowaniem treści popover.
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's 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 });
Możesz to sprawdzić http://kienthuchoidap.com . Przejdź do tego i najedź na nazwę użytkownika użytkownika.
źródło
Jak dla mnie działa, zmień zawartość danych przed załadowaniem popover:
$('.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') }}) })
źródło
To działa dla mnie, ten kod naprawia możliwe problemy z wyrównaniem:
<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'); } }); } });
Na wszelki wypadek punkt końcowy, którego używam, zwraca html (częściowe railsy)
Wziąłem część kodu stąd https://stackoverflow.com/a/13565154/3984542
źródło