Carica un contenuto popover Bootstrap con AJAX. È possibile?


90

I pezzi appropriati di ciò che ho provato sono qui:

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

Quando faccio clic, vedo che la richiesta viene effettuata, ma non popola il popover. Non vedo nemmeno l'HTML per il popover aggiunto al DOM, ma potrebbe trattarsi di firebug.

Qualcuno l'ha provato?


1
Non ho lavorato con bootstrap, ma immagino che sia possibile che l'elemento non esista quando stai cercando di aggiungere contenuto, ma è un'ipotesi. Stai ricevendo errori javascript?
Seth

Se hai più popover e desideri caricare contenuti diversi per ogni popover, questa risposta è molto chiara e ti consente di conservare molte delle impostazioni predefinite per i popover: tutto ciò che devi fare è memorizzare l'ID del popover sugli attributi del collegamento e leggerli nel 'shown.bs.popover'gestore: stackoverflow.com/a/39028723/1371408
Matty J

Risposte:


105

Vedi il mio post sul blog per la soluzione funzionante: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4

Per prima cosa dovremmo aggiungere un attributo data-poload agli elementi a cui vorresti aggiungere un pop. Il contenuto di questo attributo dovrebbe essere l'URL da caricare (assoluto o relativo):

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

E in JavaScript, preferibilmente 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')impedisce il caricamento dei dati più di una volta e popover()associa un nuovo evento al passaggio del mouse. Se desideri che i dati vengano aggiornati a ogni evento di passaggio del mouse, devi rimuovere l'opzione off.

Si prega di vedere il JSFiddle funzionante dell'esempio.


4
Ho avuto un po 'di stranezza quando ho passato il mouse due volte prima che la chiamata ajax fosse completata ... I miei popvers si "bloccavano". L'ho risolto spostando "el.unbind ('hover')" subito prima di $ .get ().
Luke The Obscure

1
Funziona, ma il popover si attacca anche a me, anche se lo scioglimento è prima del get
Androme

2
Se stai tentando di caricare un URL esterno, ti imbatterai in restrizioni di accesso tra domini. Per aggirare questo problema, puoi impostare la htmlproprietà del popover su true, quindi impostare la contentproprietà su un tag HTML iframe, come content: '<iframe src="http://www.google.com"></iframe>'. Dovrai anche sovrascrivere la max-widthproprietà del tuo popover usando CSS e molto probabilmente rimuovere anche lo stile dell'iframe usando CSS.
Gavin

1
@FrzKhan puoi usare il e.off('hover')metodo
codenamev

3
questo non funziona a causa di stackoverflow.com/questions/4111194/... passaggio a .hover (function () {}) funziona.
arisalexis

132

Funziona bene per 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>';
}

1
Risposta geniale! ed è per questo che l'ha modificato per renderlo più leggibile
itsazzad

2
Ottima soluzione. Con la versione corrente di bootstrap, tuttavia, sembra che der possa essere un problema per questo metodo github.com/twbs/bootstrap/issues/12563 . Ho avuto il doppio problema e la soluzione rapida era garantire un titolo in ogni popover. Ciò significa anche che in realtà non vedo mai il testo di caricamento che stai utilizzando.
Rasmus Christensen

Funziona, tranne per il fatto che dovevo usare data-link invece di href, quando usando href il mio browser apriva semplicemente l'URL in href in una nuova finestra.
TinusSky

20
Ciò non causa problemi di allineamento? Quando si utilizza questo approccio su 3.3.1 (e si utilizza Chrome), il popover si allinea quando viene visualizzato "Caricamento in corso ...", ma non appena viene caricato il vero contenuto del mio popover, l'allineamento non si regola di conseguenza .. .
Matt

5
Bella soluzione. Uno svantaggio di questa soluzione è che la chiamata ajax viene effettuata due volte. Il componente popover è un suggerimento che prima controlla il contenuto utilizzando hasContent e quindi ottiene il contenuto con setContent.
Liam

24

Dopo aver letto tutte queste soluzioni, penso che la soluzione diventi molto più semplice se si utilizza una chiamata ajax sincrona . Puoi quindi usare qualcosa come:

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

1
Questo mi ha aiutato moltissimo, poiché avevo un problema con il rendering del popover in una certa posizione prima che l'ajax restituisse i contenuti (facendoli caricare dallo schermo). Grazie Signore!
Derek

Potrebbe essere più semplice, ma è anche meno elegante della soluzione pubblicata da @Ivan Klass.
Ian Kemp

6
async: falseuccide questo per me
mxmissile

Sebbene certamente più facile, JavaScript e il codice sincrono non funzionano bene insieme. Poiché JavaScript è a thread singolo, l'esecuzione di qualsiasi codice verrà bloccata per tutto il tempo necessario alla richiesta.
IluTov

1
AJAX sincrono è deprecato.
Barmar

10

Ho aggiornato la risposta più popolare. Ma nel caso in cui le mie modifiche non vengano approvate, metto qui una risposta separata.

Le differenze sono:

  • LOADING testo mostrato durante il caricamento del contenuto. Ottimo per la connessione lenta.
  • Rimosso lo sfarfallio che si verifica quando il mouse esce dal popover per la prima volta.

Per prima cosa dovremmo aggiungere un attributo data-poload agli elementi a cui vorresti aggiungere un pop. Il contenuto di questo attributo dovrebbe essere l'URL da caricare (assoluto o relativo):

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

E in JavaScript, preferibilmente 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')impedisce il caricamento dei dati più di una volta e popover()associa un nuovo evento al passaggio del mouse. Se desideri che i dati vengano aggiornati a ogni evento di passaggio del mouse, devi rimuovere l'opzione off.

Si prega di vedere il JSFiddle funzionante dell'esempio.


7

Una variazione del codice di Çağatay Gürtürk, potresti invece usare la funzione delegate e forzare l'occultamento del popover all'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');
    }
});

Per jquery recente: $ ('* [data-poload]'). On ('mouseenter mouseleave', function (event) {
jpprade

7

La soluzione di Çağatay Gürtürk è carina ma ho sperimentato la stessa stranezza descritta da Luke The Obscure:

Quando il caricamento di ajax dura troppo (o gli eventi del mouse sono troppo veloci) abbiamo un .popover ('show') e nessun .popover ('hide') su un dato elemento, facendo sì che il popover rimanga aperto.

Ho preferito questa massiccia soluzione di pre-caricamento, tutti i contenuti del popover vengono caricati e gli eventi sono gestiti dal bootstrap come nei normali popover (statici).

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

    var el=$(this);

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

});

7

NEL 2015, questa è la risposta migliore

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

6

Un'altra soluzione:

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

L'idea qui è di attivare manualmente la visualizzazione di PopOver con eventi mouseenter e mouseleave .

Su mouseenter , se non è stato creato alcun PopOver per il tuo articolo ( if ($ (this) .data ('popover') == null) ), crealo . Ciò che è interessante è che puoi definire il tuo contenuto PopOver passandolo come argomento ( modello ) alla funzione popover () . Non dimenticare di impostare anche il parametro html su true .

Qui creo solo un modello nascosto chiamato popovertemplate e lo clono con JQuery. Non dimenticare di eliminare l'attributo id una volta clonato, altrimenti ti ritroverai con ID duplicati nel DOM. Notare anche che style = "display: none" per nascondere il modello nella pagina.

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

Dopo il passaggio di creazione (o se è già stato creato), visualizzi il popOver con $ (this) .popover ('show');

Poi la classica chiamata Ajax. In caso di successo è necessario pulire il vecchio contenuto popover prima di inserire nuovi dati freschi dal server . Come possiamo ottenere il contenuto attuale del popover? Con il selettore .popover.in ! La classe .in indica che il popover è attualmente visualizzato, questo è il trucco qui!

Per finire, in caso di uscita del mouse , basta nascondere il popover.


Stessa cosa per me, la più semplice e la migliore ;-)
Thomas Decaux

il problema con questo è su ogni hover che richiedi dati dal server. Dovrebbe caricare i dati solo una volta.
Richard Torcato

2
@Richard Torcato In una mano hai ragione. Tuttavia, dovrebbe essere abbastanza facile mettere il risultato in una cache. In un'altra mano, forse vogliamo colpire il server per caricare nuovi dati ad ogni hover. Quindi sta a te implementare la memorizzazione nella cache
doanduyhai

Mi rendo conto che questo è vecchio ora, ma nel caso qualcuno lo stia guardando, non riesco a immaginare che funzioni bene perché lo è se hai più popover e scorri su ciascuno di essi. Passa il mouse su A, la richiesta inviata per A, passa il mouse su B e rimani su di essa, la richiesta inviata per B, arriva la risposta di B, aggiorna il popover per B, arriva la risposta per A, aggiorna il popover per B (poiché la funzione di successo lo farà . solo chiaro nulla con quella classe Guardando a questo per integrare l'aiuto potenza sopra se stackoverflow.com/a/34030999/2524589
KSib

3

Ecco la mia soluzione che funziona bene anche con i contenuti caricati 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';
}

3

Se è improbabile che il contenuto del popover cambi, avrebbe senso recuperarlo una sola volta. Inoltre, alcune delle soluzioni qui hanno il problema che se ci si sposta su più "anteprime" velocemente, si ottengono più popup aperti. Questa soluzione risolve entrambe queste cose.

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

Penso che la mia soluzione sia più semplice con la funzionalità predefinita.

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>


2

Ci sono troppe risposte qui, ma ho anche scoperto che nessuna di esse era ciò che volevo. Ho esteso la risposta di Ivan Klass in modo che sia Bootstrap 4 appropriato e memorizzato nella cache in modo intelligente.

Tieni presente che lo snippet non caricherà effettivamente l'indirizzo remoto a causa della politica CORS di 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>


Sono stato in grado di adattarlo facilmente alla soluzione di cui avevo bisogno. Grazie!
Nieminen

1
Ottima soluzione, dovevo solo aggiungere "sanitize: false" alla configurazione popover per gestire il mio css!
Guillaume


1

Ho provato la soluzione di Çağatay Gürtürk ma ho avuto la stessa stranezza di Luke the Obscure. Quindi ho provato la soluzione di Asa Kusuma. Funziona, ma credo che l'Ajax legga ogni volta che viene visualizzato il popover. La chiamata a svincolare ('hover') non ha effetto. Questo perché il delegato sta monitorando gli eventi in una classe specifica, ma quella classe è invariata.

Ecco la mia soluzione, strettamente basata su quella di Asa Kusuma. I cambiamenti:

  • Sostituito delegatecon onper abbinare le nuove librerie JQuery.
  • Rimuovi la classe "withajaxpopover" anziché annullare l'associazione dell'evento al passaggio del mouse (che non è mai stato associato)
  • Aggiungi "trigger: hover" al popover in modo che Bootstrap lo gestisca completamente a partire dal secondo utilizzo.
  • La mia funzione di caricamento dei dati restituisce JSon, che rende facile specificare sia il titolo che il contenuto per il popover.
    / * Obiettivo: visualizzare una descrizione comando / popover in cui il contenuto viene recuperato dal file
              applicazione solo la prima volta.

        Come: recupera il contenuto appropriato e registra il tooltip / popover la prima volta 
              il mouse entra in un elemento DOM con classe "withajaxpopover". Rimuovi il
              class dall'elemento in modo da non farlo la prossima volta che il mouse entra.
              Tuttavia, ciò non mostra il tooltip / popover per la prima volta
              (perché il mouse è già inserito quando il tooltip è registrato).
              Quindi dobbiamo mostrarlo / nasconderlo noi stessi.
    * /
    $ (function () {
      $ ('body'). on ('hover', '.withajaxpopover', function (event) {
          if (event.type === 'mouseenter') {
              var el = $ (questo);
              $ .get (el.attr ('data-load'), function (d) {
                  el.removeClass ('withajaxpopover')
                  el.popover ({trigger: 'hover', 
                              titolo: d.title, 
                              contenuto: d.content}). popover ('mostra');
              });
          } altro {
              $ (questo) .popover ('nascondi');
          }
      });
    });

1

Ho provato alcuni dei suggerimenti qui e vorrei presentare il mio (che è un po 'diverso) - spero che possa aiutare qualcuno. Volevo mostrare il popup al primo clic e nasconderlo al secondo (ovviamente aggiornando i dati ogni volta). Ho usato una variabile extra visableper sapere se il popover è visibile o meno. Ecco il mio codice: 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);   
    });
}   
});

Saluti!


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

});

1

Ecco un modo che risolve alcuni problemi:

  1. Problemi di allineamento dopo l'aggiornamento dei contenuti, soprattutto se il posizionamento è "in alto". La chiave sta chiamando ._popper.update(), che ricalcola la posizione del popover.
  2. Modifica della larghezza dopo l'aggiornamento del contenuto. Non rompe nulla, sembra solo fastidioso per l'utente. Per ridurlo, ho impostato la larghezza del popover al 100% (che viene quindi limitato dal 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");
        });
});

Mi piacciono i concetti, ma sfortunatamente non funzionano per me ... (vale a dire l'aggiornamento della posizione e la larghezza del 100%) Non sei sicuro che siano cambiati con Bootstrap 4?
Ben in CA

La larghezza del 100% probabilmente dipende da come sono disposti i tuoi elementi ... forse. La casella si allarga ancora dopo che il contenuto è stato caricato?
Gabriel Luci

Per la posizione, puoi impostare un punto di interruzione su popover._popper.update()e assicurarti che popover, _poppere updatetutti abbiano i valori previsti. È certamente possibile che quelli siano cambiati.
Gabriel Luci

A destra: la casella si allarga dopo il nuovo contenuto. E ho provato a scrivere alcuni valori sulla console e stavo diventando indefinito.
Ben in California,

1
- Hai ragione. È venuto fuori che stavo cercando di fare alcune cose più complesse allo stesso tempo e poi non funzionava. Ma ora sono stato in grado di incorporare anche questo. Ecco un violino: jsfiddle.net/udfz5wrv/1 Consente di utilizzare selettori (se è necessario associare gestori, ecc.), Accedere ai dati dal selettore, visualizzare uno spinner di caricamento bootstrap, ecc.
Ben in CA

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

    });

nota che ho usato lo stesso tag href e ho fatto in modo che non cambiasse pagina quando cliccato, questa è una buona cosa per il SEO e anche se l'utente non ha javascript!


0

Mi piace la soluzione di Çağatay, ma i popup non si nascondevano al mouseout. Ho aggiunto questa funzionalità extra con questo:

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

0

Ho usato la soluzione originale ma ho apportato un paio di modifiche:

Innanzitutto, ho usato getJSON()invece di get()perché stavo caricando uno script JSON. Successivamente ho aggiunto il comportamento di attivazione del passaggio del mouse per risolvere il problema del pop appiccicoso.

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

Ho aggiunto html: true, quindi non mostra l'output html grezzo, nel caso in cui desideri formattare i risultati. Puoi anche aggiungere più controlli.

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

Visualizza il popover ajax sull'elemento statico con il trigger al passaggio del mouse:

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

Il contenuto Ajax viene caricato una volta! vedereel.data('bs.popover').options.content = response;


0

L'ho fatto e funziona perfettamente con ajax e caricamento su contenuti 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
            });

Puoi verificarlo http://kienthuchoidap.com . Vai a questo e passa con il mouse sul nome utente dell'utente.


0

Per me funziona cambia il contenuto dei dati prima di caricare il 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')
        }})
})

0

Questo funziona per me, questo codice risolve possibili problemi di allineamento:

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

Per ogni evenienza, l'endpoint che sto usando restituisce html (un rails parziale)

Ho preso parte del codice da qui https://stackoverflow.com/a/13565154/3984542

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.