Laden Sie einen Bootstrap-Popover-Inhalt mit AJAX. Ist das möglich?

90

Die passenden Teile von dem, was ich versucht habe, sind hier:

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

Wenn ich auf klicke, wird die Anforderung angezeigt, das Popover wird jedoch nicht ausgefüllt. Ich sehe nicht einmal, dass HTML für das Popover zum DOM hinzugefügt wird, aber das könnte ein Firebug sein.

Hat jemand das versucht?

CambridgeMike
quelle
1
Ich habe nicht mit Bootstrap gearbeitet, aber ich würde mir vorstellen, dass das Element möglicherweise nicht vorhanden ist, wenn Sie versuchen, Inhalte hinzuzufügen, aber das ist eine Vermutung. Erhalten Sie Javascript-Fehler?
Seth
Wenn Sie mehrere Popovers haben und für jedes Popover unterschiedliche Inhalte laden möchten, ist diese Antwort sehr übersichtlich und ermöglicht es Ihnen, einen Großteil des sofort einsatzbereiten Setups für Popover beizubehalten. Sie müssen lediglich die ID des Popovers speichern auf Attribute des Links, und lesen Sie sie im 'shown.bs.popover'Handler: stackoverflow.com/a/39028723/1371408
Matty J

Antworten:

105

Die funktionierende Lösung finden Sie in meinem Blogbeitrag: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4

Zuerst sollten wir den Elementen, denen Sie ein Pop-Over hinzufügen möchten, ein Datenpoload-Attribut hinzufügen. Der Inhalt dieses Attributs sollte die zu ladende URL sein (absolut oder relativ):

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

Und in JavaScript, vorzugsweise in einem $ (Dokument) .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')verhindert das mehrmalige Laden von Daten und popover()bindet ein neues Hover-Ereignis. Wenn Sie möchten, dass die Daten bei jedem Hover-Ereignis aktualisiert werden, sollten Sie das Aus entfernen.

Bitte beachten Sie die funktionierende JSFiddle des Beispiels.

Çağatay Gürtürk
quelle
4
Ich wurde etwas komisch, als ich zweimal mit der Maus darüber fuhr, bevor der Ajax-Anruf beendet war ... Meine Popvers würden "offen bleiben". Ich habe es gelöst, indem ich "el.unbind ('hover')" nach rechts vor $ .get () verschoben habe.
Luke The Obscure
1
Das funktioniert, aber der Popover bleibt auch für mich, obwohl die Aufhebung vor dem Get ist
Androme
2
Wenn Sie versuchen, eine externe URL zu laden, treten domänenübergreifende Zugriffsbeschränkungen auf. Um dies zu umgehen, können Sie die htmlEigenschaft des Popovers auf trueund dann die contentEigenschaft auf ein iframe-HTML-Tag festlegen , z content: '<iframe src="http://www.google.com"></iframe>'. Sie müssen auch die max-widthEigenschaft Ihres Popovers mithilfe von CSS überschreiben und höchstwahrscheinlich auch das Styling des Iframes mithilfe von CSS entfernen.
Gavin
1
@ FrzKhan können Sie die e.off('hover')Methode verwenden
Codenamev
3
Dies funktioniert nicht, da stackoverflow.com/questions/4111194/… die Änderung in .hover (function () {}) funktioniert.
Arisalexis
132

Funktioniert gut für mich:

$('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
quelle
1
Geniale Antwort! und deshalb hat es bearbeitet, um es lesbarer zu machen
itsazzad
2
Tolle Lösung. Mit der aktuellen Version von Bootstrap jedoch, dass der scheint vielleicht einige Probleme diese Methode seiner github.com/twbs/bootstrap/issues/12563 .Ich hatte das zweimal Problem und die schnelle Lösung , die einen Titel in jedem popover zu gewährleisten war. Dies bedeutet auch, dass ich den von Ihnen verwendeten Ladetext eigentlich nie sehe.
Rasmus Christensen
Funktioniert, außer dass ich Datenlink anstelle von href verwenden musste. Wenn ich href verwende, öffnet mein Browser einfach die URL in href in einem neuen Fenster.
TinusSky
20
Verursacht dies keine Ausrichtungsprobleme? Wenn Sie diesen Ansatz in 3.3.1 (und Chrome) verwenden, richtet sich das Popover selbst aus, wenn "Laden ..." angezeigt wird. Sobald jedoch der wahre Inhalt meines Popovers geladen ist, wird die Ausrichtung nicht entsprechend angepasst. .
Matt
5
Schöne Lösung. Ein Nachteil dieser Lösung ist, dass der Ajax-Anruf zweimal getätigt wird. Die Popover-Komponente ist ein Tooltip, der zuerst mit hasContent nach Inhalten sucht und dann mit setContent den Inhalt abruft.
Liam
23

Nachdem Sie alle diese Lösungen gelesen haben, wird die Lösung meiner Meinung nach viel einfacher, wenn Sie einen synchronen Ajax-Aufruf verwenden. Sie können dann etwas verwenden wie:

  $('#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');
  });
Verwirrtheit
quelle
1
Dies half mir tonnenweise, da ich ein Problem mit dem Popover-Rendering an einer bestimmten Position hatte, bevor der Ajax den Inhalt zurückgab (was dazu führte, dass er vom Bildschirm geladen wurde). Vielen Dank, Sir!
Derek
Es mag einfacher sein, aber es ist auch weniger elegant als die von @Ivan Klass veröffentlichte Lösung.
Ian Kemp
6
async: falsetötet dies für mich
mxmissile
Obwohl es sicherlich einfacher ist, spielen JavaScript und synchroner Code nicht wirklich gut zusammen. Da JavaScript Single-Threaded ist, wird die Ausführung von Code so lange blockiert, wie die Anforderung dauert.
IluTov
1
Synchrones AJAX ist veraltet.
Barmar
9

Ich habe die beliebteste Antwort aktualisiert. Falls meine Änderungen jedoch nicht genehmigt werden, gebe ich hier eine separate Antwort.

Unterschiede sind:

  • LADEN von Text, der angezeigt wird, während der Inhalt geladen wird. Sehr gut für langsame Verbindung.
  • Das Flackern, das auftritt, wenn die Maus das Popover zum ersten Mal verlässt, wurde entfernt.

Zuerst sollten wir den Elementen, denen Sie ein Pop-Over hinzufügen möchten, ein Datenpoload-Attribut hinzufügen. Der Inhalt dieses Attributs sollte die zu ladende URL sein (absolut oder relativ):

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

Und in JavaScript, vorzugsweise in einem $ (Dokument) .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')verhindert das mehrmalige Laden von Daten und popover()bindet ein neues Hover-Ereignis. Wenn Sie möchten, dass die Daten bei jedem Hover-Ereignis aktualisiert werden, sollten Sie das Aus entfernen.

Bitte beachten Sie die funktionierende JSFiddle des Beispiels.

Alexander Chzhen
quelle
7

Als Variation des Codes von Çağatay Gürtürk können Sie stattdessen die Delegate-Funktion verwenden und das Ausblenden des Popovers beim Hoverout erzwingen.

$('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
quelle
Für die aktuelle Abfrage: $ ('* [data-poload]'). On ('mouseenter mouseleave', Funktion (Ereignis) {
jpprade
7

Die Lösung von Çağatay Gürtürk ist schön, aber ich habe die gleiche Verrücktheit erlebt, die Luke The Obscure beschrieben hat:

Wenn das Laden von Ajax zu lange dauert (oder Mausereignisse zu schnell sind), haben wir ein .popover ('show') und kein .popover ('hide') für ein bestimmtes Element, wodurch das Popover geöffnet bleibt.

Ich habe diese massive Pre-Load-Lösung bevorzugt, alle Popover-Inhalte werden geladen und Ereignisse werden wie bei normalen (statischen) Popovers vom Bootstrap behandelt.

$('.popover-ajax').each(function(index){

    var el=$(this);

    $.get(el.attr('data-load'),function(d){
        el.popover({content: d});       
    });     

});
Fustaki
quelle
7

Im Jahr 2015 ist dies die beste Antwort

$('.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
quelle
6

Eine andere Lösung:

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

Die Idee hier ist, die Anzeige von PopOver mit mouseenter & mouseleave Ereignissen manuell auszulösen .

Auf MouseEnter- , wenn es keine popover für Ihren Artikel (erstellt ist if ($ (this) .data ( 'popover') == null) ), erstellen Sie es. Interessant ist, dass Sie Ihren eigenen PopOver-Inhalt definieren können, indem Sie ihn als Argument ( Vorlage ) an die Funktion popover () übergeben . Vergessen Sie nicht, auch den HTML- Parameter auf true zu setzen .

Hier erstelle ich einfach eine versteckte Vorlage namens popovertemplate und klone sie mit JQuery. Vergessen Sie nicht, das ID-Attribut nach dem Klonen zu löschen, da sonst doppelte IDs im DOM angezeigt werden. Beachten Sie auch, dass style = "display: none" ist , um die Vorlage auf der Seite auszublenden.

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

Nach dem Erstellungsschritt (oder wenn er bereits erstellt wurde) zeigen Sie einfach den popOver mit $ (this) .popover ('show') an.

Dann klassischer Ajax-Anruf. Bei Erfolg müssen Sie den alten Popover-Inhalt bereinigen, bevor Sie neue frische Daten vom Server ablegen . Wie können wir den aktuellen Popover-Inhalt erhalten? Mit dem .popover.in Selektor! Die .in- Klasse zeigt an, dass das Popover gerade angezeigt wird, das ist hier der Trick!

Zum Abschluss des Mausblatt- Ereignisses verstecken Sie einfach das Popover.

doanduyhai
quelle
Das Gleiche für mich, das einfachste und beste ;-)
Thomas Decaux
Das Problem dabei ist, dass Sie bei jedem Hover Daten vom Server anfordern. Die Daten sollten nur einmal geladen werden.
Richard Torcato
2
@ Richard Torcato In einer Hand hast du recht. Es sollte jedoch ziemlich einfach sein, das Ergebnis in einen Cache zu stellen. In einer anderen Hand möchten wir vielleicht den Server treffen, um bei jedem Hover neue Daten zu laden. Es liegt also an Ihnen, das Caching zu implementieren
doanduyhai
Mir ist klar, dass dies jetzt alt ist, aber falls sich jemand das ansieht, kann ich mir nicht vorstellen, dass dies gut funktioniert, wenn Sie mehrere Popover haben und über jeden von ihnen scrollen. Bewegen Sie den Mauszeiger über A, die Anforderung wird für A gesendet, bewegen Sie den Mauszeiger über B und bleiben Sie auf der Maus, die Anforderung wird für B gesendet, die Antwort von B kommt an, aktualisiert das Popover für B, die Antwort für A kommt an, aktualisiert das Popover für B (da die Erfolgsfunktion dies tut Löschen Sie einfach alles mit dieser Klasse. Ein Blick darauf, um das oben Gesagte
KSib
3

Hier ist meine Lösung, die auch mit Ajax-geladenen Inhalten funktioniert.

/*
 * 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';
}
Bohrer
quelle
3

Wenn sich der Inhalt im Popover wahrscheinlich nicht ändert, ist es sinnvoll, ihn nur einmal abzurufen. Einige der hier aufgeführten Lösungen haben außerdem das Problem, dass Sie mehrere offene Popups erhalten, wenn Sie schnell über mehrere "Vorschauen" wechseln. Diese Lösung befasst sich mit beiden Dingen.

$('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
quelle
3

Ich denke, meine Lösung ist einfacher mit Standardfunktionalität.

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>

Salz Hareket
quelle
1

Ich habe die Lösung von Çağatay Gürtürk ausprobiert, aber die gleiche Verrücktheit wie bei Luke the Obscure. Dann versuchte die Lösung von Asa Kusuma. Dies funktioniert, aber ich glaube, es liest den Ajax jedes Mal, wenn das Popover angezeigt wird. Der Aufruf zum Aufheben der Bindung ('Hover') hat keine Auswirkung. Dies liegt daran, dass der Delegat Ereignisse in einer bestimmten Klasse überwacht - diese Klasse bleibt jedoch unverändert.

Hier ist meine Lösung, die eng auf der von Asa Kusuma basiert. Änderungen:

  • Ersetzt delegatedurch on, um neuen JQuery-Bibliotheken zu entsprechen.
  • Entfernen Sie die Klasse 'withajaxpopover', anstatt das Hover-Ereignis zu lösen (das nie gebunden wurde).
  • Fügen Sie dem Popover "trigger: hover" hinzu, damit Bootstrap es ab der zweiten Verwendung vollständig verarbeitet.
  • Meine Funktion zum Laden von Daten gibt JSon zurück, wodurch es einfach ist, sowohl den Titel als auch den Inhalt für das Popover anzugeben.
    / * Ziel: Zeigt einen Tooltip / Popover an, in dem der Inhalt aus dem abgerufen wird
              Anwendung nur beim ersten Mal.

        Wie: Holen Sie sich den entsprechenden Inhalt und registrieren Sie den Tooltip / Popover beim ersten Mal 
              Die Maus gibt ein DOM-Element mit der Klasse "withajaxpopover" ein. Entferne das
              Klasse aus dem Element, damit wir das nicht tun, wenn die Maus das nächste Mal eintritt.
              Der Tooltip / Popover wird jedoch nicht zum ersten Mal angezeigt
              (weil die Maus bereits bei der Registrierung des Tooltips eingegeben wurde).
              Also müssen wir es selbst zeigen / verstecken.
    * /
    $ (function () {
      $ ('body'). on ('hover', '.withajaxpopover', function (event) {
          if (event.type === 'mouseenter') {
              var el = $ (this);
              $ .get (el.attr ('Daten laden'), Funktion (d) {
                  el.removeClass ('withajaxpopover')
                  el.popover ({trigger: 'hover', 
                              Titel: d.title, 
                              Inhalt: d.content}). popover ('show');
              });
          } else {
              $ (this) .popover ('hide');
          }}
      });
    });
bwbecker
quelle
1

Ich habe einige der Vorschläge hier ausprobiert und möchte meine vorstellen (was etwas anders ist) - ich hoffe, es wird jemandem helfen. Ich wollte das Popup beim ersten Klick anzeigen und beim zweiten Klick ausblenden (natürlich mit jeder Aktualisierung der Daten). Ich habe eine zusätzliche Variable verwendet, um visablezu wissen, ob das Popover sichtbar ist oder nicht. Hier ist mein 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);   
    });
}   
});

Prost!

ItayB
quelle
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
quelle
1

Hier ist ein Weg, der einige Probleme angeht:

  1. Ausrichtungsprobleme nach der Aktualisierung des Inhalts, insbesondere wenn die Platzierung "oben" ist. Der Schlüssel ruft auf ._popper.update(), wodurch die Position des Popovers neu berechnet wird.
  2. Breitenänderung nach Aktualisierung des Inhalts. Es macht nichts kaputt, es sieht für den Benutzer nur irritierend aus. Um dies zu verringern, habe ich die Breite des Popovers auf 100% eingestellt (die dann durch das begrenzt wird 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
quelle
Ich mag die Konzepte, aber leider funktionieren sie nicht für mich ... (nämlich die Positionsaktualisierung und 100% Breite) Sie sind sich nicht sicher, ob sich diese mit Bootstrap 4 geändert haben?
Ben in CA
Die 100% Breite hängt wahrscheinlich davon ab, wie Ihre Elemente angeordnet sind ... vielleicht. Erweitert sich die Box nach dem Laden des Inhalts noch?
Gabriel Luci
Für die Position können Sie einen Haltepunkt an gesetzt popover._popper.update()und stellen Sie sicher , dass popover, _popperund updatealle haben die erwarteten Werte. Es ist durchaus möglich, dass sich diese geändert haben.
Gabriel Luci
Rechts - das Feld wird nach neuem Inhalt erweitert. Und ich habe versucht, einige der Werte in die Konsole zu schreiben und wurde undefiniert.
Ben in CA
1
- Du hast recht. Es stellte sich heraus, dass ich gleichzeitig versucht habe, komplexere Dinge zu tun, und dann hat es nicht funktioniert. Aber jetzt konnte ich das auch einbauen. Hier ist eine Geige: jsfiddle.net/udfz5wrv/1 Ermöglicht die Verwendung von Selektoren (wenn Sie Handler binden müssen usw.), den Zugriff auf Daten aus dem Selektor, die Anzeige eines Bootstrap-Ladespinners usw.
Ben in CA,
1

Es gibt hier viel zu viele Antworten, aber ich fand auch keine, die das war, was ich wollte. Ich habe die Antwort von Ivan Klass so erweitert, dass sie sowohl für Bootstrap 4 geeignet als auch intelligent zwischengespeichert ist.

Beachten Sie, dass das Snippet die Remote-Adresse aufgrund der CORS-Richtlinie von Stackoverflow nicht wirklich lädt.

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>

Archonisch
quelle
Ich konnte diese problemlos an die von mir benötigte Lösung anpassen. Vielen Dank!
Nieminen
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()
        });

    });

Beachten Sie, dass ich das gleiche href-Tag verwendet habe und es so gestaltet habe, dass beim Klicken keine Seiten geändert werden. Dies ist eine gute Sache für SEO und auch, wenn der Benutzer kein Javascript hat!

Neo
quelle
0

Ich mag die Lösung von Çağatay, aber die Popups haben sich nicht beim Mouseout versteckt. Ich habe diese zusätzliche Funktionalität hinzugefügt:

// hides the popup
$('*[data-poload]').bind('mouseout',function(){
   var e=$(this);
   e.popover('hide'); 
});
Mino
quelle
0

Ich habe die ursprüngliche Lösung verwendet, aber einige Änderungen vorgenommen:

Zuerst habe ich getJSON()statt , get()weil ich ein json Skript geladen werden . Als nächstes habe ich das Triggerverhalten von Hover hinzugefügt, um das Problem mit dem Sticky Pop Over zu beheben.

$('*[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
quelle
0

Ich habe html: true hinzugefügt, sodass keine rohe HTML-Ausgabe angezeigt wird, falls Sie Ihre Ergebnisse formatieren möchten. Sie können auch weitere Steuerelemente hinzufügen.

    $('*[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
quelle
0

Ajax-Popover auf statischem Element mit Hover-Trigger anzeigen:

$('.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
quelle
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>';
  }   

Ajax-Inhalte werden einmal geladen! sehenel.data('bs.popover').options.content = response;

SirCumz
quelle
0

Ich habe es getan und es funktioniert perfekt mit Ajax und dem Laden von Popover-Inhalten.

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

Sie können es unter http://kienthuchoidap.com überprüfen . Gehen Sie dazu und bewegen Sie den Mauszeiger zum Benutzernamen des Benutzers.

Ho Thanh Binh
quelle
0

Bei mir ändern sich die Dateninhalte vor dem Laden des Popovers:

$('.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
quelle
0

Dies funktioniert für mich, dieser Code behebt mögliche Ausrichtungsprobleme:

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

Nur für den Fall, dass der Endpunkt, den ich verwende, HTML zurückgibt (ein Rails-Teil)

Ich habe einen Teil des Codes von hier https://stackoverflow.com/a/13565154/3984542 übernommen

vicente.fava
quelle