Załaduj zawartość popover Bootstrap za pomocą AJAX. czy to możliwe?

90

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ł?

CambridgeMike
źródło
1
Nie pracowałem z bootstrapem, ale wyobrażam sobie, że możliwe jest, że element nie istnieje, gdy próbujesz dodać do niego zawartość, ale to przypuszczenie. Czy otrzymujesz jakieś błędy javascript?
Seth
Jeśli masz wiele okien popover i chcesz załadować inną zawartość dla każdego popovera, to ta odpowiedź jest bardzo zgrabna i pozwala zachować wiele konfiguracji po wyjęciu z pudełka dla popoverów - wszystko, co musisz zrobić, to zapisać identyfikator popovera o atrybutach linku i przeczytaj je w 'shown.bs.popover'module obsługi: stackoverflow.com/a/39028723/1371408
Matty J

Odpowiedzi:

105

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

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="#" title="blabla" data-poload="/test.php">blabla</a>

Oraz w JavaScript, najlepiej w $ (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')zapobiega ładowaniu danych więcej niż raz i popover()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.

Çağatay Gürtürk
źródło
4
Zrobiło mi się dziwnie, kiedy dwukrotnie przeskoczyłem myszką przed zakończeniem wywołania Ajax ... Moje popvery „przyklejały się”. Rozwiązałem to, przenosząc element „el.unbind ('hover')” na prawo przed $ .get ().
Luke The Obscure
1
To działa, ale popover również trzyma się dla mnie, mimo że rozpięcie jest przed zdobyciem
Androme
2
Jeśli próbujesz załadować zewnętrzny adres URL, napotkasz ograniczenia dostępu między domenami. Aby obejść ten problem, można ustawić popover za htmlwłaściwość true, a następnie ustawić contentwłaściwość znacznika iframe HTML, jak content: '<iframe src="http://www.google.com"></iframe>'. Będziesz także musiał nadpisać max-widthwłaściwość swojego popover za pomocą CSS i najprawdopodobniej usunąć styl elementu iframe również za pomocą CSS.
Gavin
1
@FrzKhan możesz użyć e.off('hover')metody
codenamev
3
to nie działa, ponieważ stackoverflow.com/questions/4111194/ ... zmiana na .hover (funkcja () {}) działa.
arisalexis
132

U 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>';
}
Ivan Klass
źródło
1
Genialna odpowiedź! i dlatego zredagowałem go, aby był bardziej czytelny
itsazzad
2
Świetne rozwiązanie. Jednak w obecnej wersji bootstrapa wydaje się, że może to być problem z tą metodą github.com/twbs/bootstrap/issues/12563. Miałem podwójny problem i szybkim rozwiązaniem było zapewnienie tytułu w każdym popover. Oznacza to również, że tak naprawdę nigdy nie widzę używanego tekstu Loading.
Rasmus Christensen
Działa, z wyjątkiem tego, że musiałem użyć linku danych zamiast href, kiedy używam href, moja przeglądarka po prostu otwiera adres URL w href w nowym oknie.
TinusSky
20
Czy to nie powoduje problemów z wyrównaniem? Podczas korzystania z tego podejścia w wersji 3.3.1 (i przy użyciu przeglądarki Chrome) wyskakujące okienko wyrównuje się po wyświetleniu komunikatu „Ładowanie ...”, ale po załadowaniu prawdziwej zawartości mojego okna popover wyrównanie nie jest odpowiednio dostosowywane. .
Matt
5
Niezłe rozwiązanie. Wadą tego rozwiązania jest to, że wywołanie AJAX jest wykonywane dwukrotnie. Komponent popover to podpowiedź, która najpierw sprawdza zawartość za pomocą hasContent, a następnie pobiera zawartość za pomocą setContent.
Liam
23

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');
  });
Dezorientacja
źródło
1
Pomogło mi to wiele, ponieważ miałem problem z renderowaniem popover w określonej pozycji, zanim ajax zwrócił zawartość (powodując załadowanie się z ekranu). Dziekuje panu!
Derek
Może być prostsze, ale jest też mniej eleganckie niż rozwiązanie opublikowane przez @Ivan Klass.
Ian Kemp
6
async: falsezabija to dla mnie
mxmissile
Chociaż z pewnością łatwiejsze, JavaScript i kod synchroniczny nie działają dobrze razem. Ponieważ JavaScript jest jednowątkowy, blokuje to wykonywanie dowolnego kodu tak długo, jak trwa żądanie.
IluTov
1
Synchroniczny AJAX jest przestarzały.
Barmar
9

Zaktualizowałem najpopularniejszą odpowiedź. Ale na wypadek, gdyby moje zmiany nie zostały zatwierdzone, zamieszczam tutaj oddzielną odpowiedź.

Różnice to:

  • ŁADOWANIE tekstu wyświetlanego podczas wczytywania treści. Bardzo dobre dla wolnego połączenia.
  • Usunięto migotanie, które pojawia się, gdy mysz opuszcza okno po raz pierwszy.

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 i popover()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.

Alexander Chzhen
źródło
7

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');
    }
});
Asa Kusuma
źródło
Dla ostatniego jquery: $ ('* [data-poload]'). On ('mouseenter mouseleave', function (event) {
jpprade
7

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});       
    });     

});
fustaki
źródło
7

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')
});
Dorian Margineanu
źródło
6

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.

doanduyhai
źródło
Dla mnie to samo, najprostsze i najlepsze ;-)
Thomas Decaux
Problem z tym dotyczy każdego najechania myszą o dane z serwera. Powinien załadować dane tylko raz.
Richard Torcato
2
@Richard Torcato W jednej ręce masz rację. Jednak umieszczenie wyniku w pamięci podręcznej powinno być dość łatwe. Z drugiej strony, być może chcemy trafić do serwera, aby ładować nowe dane przy każdym najechaniu myszą. Więc to do Ciebie należy wdrożenie buforowania
doanduyhai
Zdaję sobie sprawę, że jest to teraz stare, ale na wypadek, gdyby ktoś na to patrzył, nie wyobrażam sobie, żeby to działało dobrze, ponieważ masz wiele okien podręcznych i przewijasz każdy z nich. Najedź na A, żądanie wysłane do A, najedź na B i pozostań na nim, żądanie wysłane do B, nadejdzie odpowiedź od B, zaktualizuje wyskakujące okienko dla B, nadejdzie odpowiedź dla A, zaktualizuje wyskakujące okienko dla B (ponieważ funkcja sukcesu będzie po prostu wyczyść wszystko z tą klasą. Spojrzenie na to, aby uzupełnić powyższe, może pomóc, chociaż stackoverflow.com/a/34030999/2524589
KSib
3

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';
}
wiertarka
źródło
3

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');
            }
        });
    }
});
towr
źródło
3

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>

Salt Hareket
źródło
1

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:

  • Zastąpione delegatez ondopasować nowe biblioteki jQuery.
  • Usuń klasę „withajaxpopover” zamiast odblokowywania zdarzenia najechania na kurs (które nigdy nie zostało powiązane)
  • Dodaj „trigger: hover” do wyskakującego okienka, aby Bootstrap obsłużył go w całości, począwszy od drugiego użycia.
  • Moja funkcja ładowania danych zwraca kod JSon, co ułatwia określenie zarówno tytułu, jak i zawartości popover.
    / * Cel: wyświetl podpowiedź / okno podręczne, w którym zawartość jest pobierana z
              aplikacja tylko za pierwszym razem.

        Jak: pobierz odpowiednią zawartość i zarejestruj podpowiedź / okienko po raz pierwszy 
              mysz wchodzi do elementu DOM z klasą „withajaxpopover”. Usunąć
              class z elementu, więc nie robimy tego następnym razem, gdy mysz wejdzie.
              Jednak to nie pokazuje podpowiedzi / okna podręcznego po raz pierwszy
              (ponieważ mysz jest już wpisana w momencie rejestracji podpowiedzi).
              Więc sami musimy to pokazać / ukryć.
    * /
    $ (funkcja () {
      $ ('body'). on ('hover', '.withajaxpopover', function (event) {
          if (event.type === 'mouseenter') {
              var el = $ (this);
              $ .get (el.attr ('ładowanie danych'), funkcja (d) {
                  el.removeClass ('withajaxpopover')
                  el.popover ({trigger: 'hover', 
                              tytuł: d.title, 
                              content: d.content}). popover ('show');
              });
          } else {
              $ (this) .popover ('ukryj');
          }
      });
    });
bwbecker
źródło
1

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, visableaby 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!

ItayB
źródło
1
<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");

});
Shankar Gupta
źródło
1

Oto sposób, który rozwiązuje kilka problemów:

  1. Problemy z wyrównaniem po zaktualizowaniu treści, zwłaszcza jeśli miejsce docelowe znajduje się „na górze”. Klawisz dzwoni ._popper.update(), co przelicza pozycję popovera.
  2. Zmiana szerokości po zaktualizowaniu zawartości. Niczego nie psuje, po prostu wygląda na drażniącą dla użytkownika. Aby to zmniejszyć, ustawiłem szerokość popover na 100% (która jest następnie ograniczona przez 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");
        });
});
Gabriel Luci
źródło
Podobają mi się koncepcje, ale niestety nie działają dla mnie ... (mianowicie aktualizacja pozycji i 100% szerokości) Nie jesteś pewien, czy zmieniły się one w Bootstrap 4?
Ben w Kalifornii
100% szerokości prawdopodobnie zależy od tego, jak ułożone są twoje elementy ... może. Czy po załadowaniu zawartości pole nadal się poszerza?
Gabriel Luci
Dla pozycji, można ustawić punkt przerwania na popover._popper.update()i upewnij się, że popover, _popperi updatewszyscy mają wartości oczekiwane. Jest z pewnością możliwe, że uległy zmianie.
Gabriel Luci
Po prawej - pudełko rozszerza się po nowej zawartości. Próbowałem zapisać niektóre wartości na konsoli i stawałem się niezdefiniowany.
Ben w Kalifornii
1
- Masz rację. Okazało się, że próbowałem zrobić bardziej złożone rzeczy w tym samym czasie, ale to nie działało. Ale teraz byłem w stanie to również włączyć. Oto skrzypce: jsfiddle.net/udfz5wrv/1 Umożliwia korzystanie z selektorów (jeśli chcesz powiązać moduły obsługi itp.), Uzyskać dostęp do danych z selektora, wyświetlić spinner ładowania programu ładującego itp.
Ben w Kalifornii
1

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>

Archonic
źródło
Udało mi się łatwo dostosować to rozwiązanie do potrzebnego mi rozwiązania. Dziękuję Ci!
Nieminen
0

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

E Steven
źródło
0
$("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!

Neo
źródło
0

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'); 
});
Mino
źródło
0

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');
        });
    });
});
Mark Flavin
źródło
0

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', {

            });
        });
    });
Warren Landis
źródło
0

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>
Alin Razvan
źródło
0
  $('[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;

SirCumz
źródło
0

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.

Ho Thanh Binh
źródło
0

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')
        }})
})
Thiago Bussiki
źródło
0

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

vicente.fava
źródło