Cargue un contenido emergente de Bootstrap con AJAX. es posible?

90

Los bits apropiados de lo que probé están aquí:

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

Cuando hago clic, veo que se realiza la solicitud, pero no completa la ventana emergente. Ni siquiera veo que se agregue HTML para el popover al DOM, pero eso podría ser un error.

¿Alguien ha probado esto?

CambridgeMike
fuente
1
No he trabajado con bootstrap, pero me imagino que es posible que el elemento no exista cuando intentas agregarle contenido, pero eso es una suposición. ¿Está recibiendo algún error de JavaScript?
Set
Si tiene varios popovers y desea cargar contenido diferente para cada popover, esta respuesta es muy clara y le permite retener gran parte de la configuración lista para usar para los popover; todo lo que necesita hacer es almacenar la ID del popover en los atributos del enlace y léalos en el 'shown.bs.popover'controlador: stackoverflow.com/a/39028723/1371408
Matty J

Respuestas:

105

Consulte la publicación de mi blog para conocer la solución de trabajo: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4

Primero debemos agregar un atributo data-poload a los elementos a los que le gustaría agregar un pop encima. El contenido de este atributo debe ser la URL a cargar (absoluta o relativa):

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

Y en JavaScript, preferiblemente en un $ (documento) .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')evita cargar datos más de una vez y popover()vincula un nuevo evento de desplazamiento. Si desea que los datos se actualicen en cada evento de desplazamiento, debe eliminar el off.

Consulte el JSFiddle funcional del ejemplo.

Çağatay Gürtürk
fuente
4
Tuve un poco de rareza cuando pasé el mouse dos veces antes de que se completara la llamada ajax ... Mis popvers se "quedaban" abiertos. Lo resolví moviendo "el.unbind ('hover')" a la derecha antes de $ .get ().
Luke The Obscure
1
Esto funciona, pero el popover también se queda para mí, aunque la desvinculación es antes del get
Androme
2
Si está intentando cargar una URL externa, se encontrará con restricciones de acceso entre dominios. Para evitar esto, puede establecer la htmlpropiedad del popover en true, luego establecer la contentpropiedad en una etiqueta HTML iframe, como content: '<iframe src="http://www.google.com"></iframe>'. También necesitará anular la max-widthpropiedad de su popover usando CSS, y lo más probable es que elimine el estilo del iframe usando CSS también.
Gavin
1
@FrzKhan puede usar el e.off('hover')método
codenamev
3
esto no funciona debido a que stackoverflow.com/questions/4111194/… cambia a .hover (function () {}) funciona.
arisalexis
132

Funciona bien para mi:

$('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
fuente
1
¡Respuesta genial! y por eso lo
edité
2
Gran solucion Sin embargo, con la versión actual de bootstrap, parece que der podría ser un problema para este método github.com/twbs/bootstrap/issues/12563 . Tuve el problema de dos veces y la solución rápida fue asegurar un título en cada popover. Esto también significa que en realidad nunca veo el texto de carga que estás usando.
Rasmus Christensen
Funciona, excepto que tuve que usar data-link en lugar de href, cuando usaba href, mi navegador simplemente abriría la url en href en una nueva ventana.
TinusSky
20
¿No causa esto problemas de alineación? Cuando se usa este enfoque en 3.3.1 (y se usa Chrome), el popover se alinea cuando se muestra "Cargando ...", pero tan pronto como se carga el contenido real de mi popover, la alineación no se ajusta en consecuencia. .
Mt
5
Buena solucion. Una desventaja de esta solución es que la llamada ajax se realiza dos veces. El componente popover es una información sobre herramientas que primero verifica el contenido usando hasContent y luego obtiene el contenido con setContent.
Liam
23

Después de leer todas estas soluciones, creo que la solución se vuelve mucho más simple si usa una llamada ajax sincrónica . Luego puede usar algo como:

  $('#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');
  });
Confusión
fuente
1
Esto me ayudó muchísimo, ya que tenía un problema con el renderizado de popover en una determinada posición antes de que el ajax devolviera el contenido (lo que hacía que se cargara fuera de la pantalla). ¡Gracias Señor!
Derek
Puede ser más simple, pero también es menos elegante que la solución publicada por @Ivan Klass.
Ian Kemp
6
async: falsemata esto para mí
mxmissile
Aunque ciertamente es más fácil, JavaScript y el código síncrono no funcionan bien juntos. Dado que JavaScript es de un solo subproceso, esto bloqueará la ejecución de cualquier código durante el tiempo que dure la solicitud.
IluTov
1
El AJAX sincrónico está en desuso.
Barmar
9

He actualizado la respuesta más popular. Pero en caso de que mis cambios no sean aprobados, pongo aquí una respuesta por separado.

Las diferencias son:

  • CARGANDO texto mostrado mientras se carga el contenido. Muy bueno para conexiones lentas.
  • Se eliminó el parpadeo que se produce cuando el mouse sale del popover por primera vez.

Primero debemos agregar un atributo data-poload a los elementos a los que le gustaría agregar un pop encima. El contenido de este atributo debe ser la URL a cargar (absoluta o relativa):

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

Y en JavaScript, preferiblemente en un $ (documento) .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') evita cargar datos más de una vez y popover() vincula un nuevo evento de desplazamiento. Si desea que los datos se actualicen en cada evento de desplazamiento, debe eliminar el off.

Consulte el JSFiddle funcional del ejemplo.

Alexander Chzhen
fuente
7

Una variación del código de Çağatay Gürtürk, puede usar la función delegar en su lugar y forzar la ocultación del popover en 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');
    }
});
Asa Kusuma
fuente
Para jquery reciente: $ ('* [data-poload]'). On ('mouseenter mouseleave', function (event) {
jpprade
7

La solución de Çağatay Gürtürk es agradable, pero experimenté la misma rareza descrita por Luke The Obscure:

Cuando la carga de ajax dura demasiado (o los eventos del mouse son demasiado rápidos), tenemos un .popover ('mostrar') y no .popover ('ocultar') en un elemento dado, lo que hace que el popover permanezca abierto.

Preferí esta solución de precarga masiva, todos los contenidos de popover se cargan y los eventos se manejan mediante bootstrap como en los popovers normales (estáticos).

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

    var el=$(this);

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

});
fustaki
fuente
7

EN 2015, esta es la mejor respuesta

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

Otra solución:

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

La idea aquí es activar manualmente la visualización de PopOver con mouseenter & mouseleave eventos .

En mouseenter , si no hay un PopOver creado para su artículo ( si ($ (this) .data ('popover') == null) ), créelo. Lo interesante es que puede definir su propio contenido PopOver pasándolo como argumento ( plantilla ) a la función popover () . No olvide establecer el parámetro html en verdadero también.

Aquí solo creo una plantilla oculta llamada popovertemplate y la clono con JQuery. No olvide eliminar el atributo id una vez que lo clone, de lo contrario, terminará con identificadores duplicados en el DOM. También observe que style = "display: none" para ocultar la plantilla en la página.

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

Después del paso de creación (o si ya se ha creado), simplemente muestra el popOver con $ (this) .popover ('show');

Luego, la llamada clásica del Ajax. Si tiene éxito, debe limpiar el contenido anterior de la ventana emergente antes de colocar nuevos datos frescos del servidor . ¿Cómo podemos obtener el contenido actual de popover? ¡Con el selector .popover.in ! La clase .in indica que el popover se muestra actualmente, ¡ese es el truco aquí!

Para terminar, en el evento mouseleave , simplemente oculte el popover.

doanduyhai
fuente
Lo mismo para mí, el más simple y el mejor ;-)
Thomas Decaux
el problema con esto está en cada vez que está solicitando datos del servidor. Debería cargar los datos solo una vez.
Richard Torcato
2
@Richard Torcato En una mano tienes razón. Sin embargo, debería ser bastante fácil poner el resultado en un caché. Por otro lado, tal vez QUEREMOS presionar el servidor para cargar datos nuevos en cada hover. Así que depende de usted implementar el almacenamiento en caché
doanduyhai
Me doy cuenta de que esto es antiguo ahora, pero en caso de que alguien esté mirando esto, no puedo imaginar que esto funcione bien si tiene varios elementos emergentes y se desplaza sobre cada uno de ellos. Desplácese sobre A, solicitud enviada para A, Desplácese sobre B y permanezca en él, solicitud enviada para B, llega la respuesta de B, actualiza el popover para B, llega la respuesta para A, actualiza el popover para B (ya que la función de éxito simplemente aclare cualquier cosa con esa clase. Ver esto para complementar lo anterior podría ayudar a través de stackoverflow.com/a/34030999/2524589
KSib
3

Aquí está mi solución que también funciona bien con contenido cargado 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';
}
perforador
fuente
3

Si no es probable que cambie el contenido de la ventana emergente, tendría sentido recuperarlo solo una vez. Además, algunas de las soluciones aquí tienen el problema de que si se desplaza rápidamente sobre varias "vistas previas", obtendrá varias ventanas emergentes abiertas. Esta solución aborda ambas cosas.

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

Creo que mi solución es más simple con la funcionalidad predeterminada.

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>

Sal Hareket
fuente
1

Probé la solución de Çağatay Gürtürk pero obtuve la misma rareza que Luke the Obscure. Luego probé la solución de Asa Kusuma. Esto funciona, pero creo que el Ajax lee cada vez que se muestra el popover. La llamada a desvincular ('hover') no tiene ningún efecto. Eso es porque el delegado está monitoreando eventos en una clase específica, pero esa clase no ha cambiado.

Aquí está mi solución, muy basada en la de Asa Kusuma. Cambios:

  • Reemplazado delegatepor onpara que coincida con las nuevas bibliotecas de JQuery.
  • Elimine la clase 'withajaxpopover' en lugar de desvincular el evento de desplazamiento (que nunca estuvo vinculado)
  • Agregue "trigger: hover" al popover para que Bootstrap lo maneje completamente comenzando con el segundo uso.
  • Mi función de carga de datos devuelve JSon, lo que facilita la especificación tanto del título como del contenido del popover.
    / * Objetivo: mostrar una información sobre herramientas / ventana emergente donde el contenido se obtiene del
              aplicación solo la primera vez.

        Cómo: obtenga el contenido apropiado y registre la información sobre herramientas / popover la primera vez 
              el ratón entra en un elemento DOM con la clase "withajaxpopover". Eliminar el
              class del elemento para que no lo hagamos la próxima vez que ingrese el mouse.
              Sin embargo, eso no muestra la información sobre herramientas / popover por primera vez
              (porque el mouse ya está ingresado cuando se registra la información sobre herramientas).
              Así que tenemos que mostrarlo / ocultarlo nosotros mismos.
    * /
    $ (función () {
      $ ('body'). on ('hover', '.withajaxpopover', function (event) {
          if (event.type === 'mouseenter') {
              var el = $ (esto);
              $ .get (el.attr ('carga de datos'), función (d) {
                  el.removeClass ('conjaxpover')
                  el.popover ({trigger: 'hover', 
                              título: d.title, 
                              contenido: d.content}). popover ('mostrar');
              });
          } más {
              $ (esto) .popover ('ocultar');
          }
      });
    });
bwbecker
fuente
1

Probé algunas de las sugerencias aquí y me gustaría presentar la mía (que es un poco diferente). Espero que ayude a alguien. Quería mostrar la ventana emergente en el primer clic y ocultarla en el segundo clic (por supuesto, actualizando los datos cada vez). Usé una variable adicional visablepara saber si el popover es visible o no. Aquí está mi código: 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);   
    });
}   
});

¡Salud!

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

A continuación, se muestra una forma que aborda algunos problemas:

  1. Problemas de alineación después de que se actualiza el contenido, especialmente si la ubicación es "superior". La clave es llamar ._popper.update(), que recalcula la posición del popover.
  2. El ancho cambia después de que se actualiza el contenido. No rompe nada, simplemente le parece discordante al usuario. Para disminuir eso, configuro el ancho del popover al 100% (que luego está limitado por 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
fuente
Me gustan los conceptos, pero desafortunadamente no funcionan para mí ... (es decir, la actualización de la posición y el 100% de ancho) ¿No estás seguro de si han cambiado con Bootstrap 4?
Ben en CA
El ancho del 100% probablemente depende de cómo estén distribuidos los elementos ... tal vez. ¿Sigue ensanchándose el cuadro después de cargar el contenido?
Gabriel Luci
Para la posición, se puede establecer un punto de interrupción en popover._popper.update()y asegúrese de que popover, _poppery updatetodos tienen los valores esperados. Ciertamente es posible que hayan cambiado.
Gabriel Luci
Derecha: el cuadro se amplía después de contenido nuevo. E intenté escribir algunos de los valores en la consola y no se definieron.
Ben en CA
1
- Tienes razón. Resulta que estaba tratando de hacer cosas más complejas al mismo tiempo y luego no funcionó. Pero ahora he podido incorporar eso también. Aquí hay un violín: jsfiddle.net/udfz5wrv/1 Le permite usar selectores (si necesita vincular controladores, etc.), acceder a datos desde el selector, mostrar un control giratorio de carga de arranque, etc.
Ben en CA
1

Hay demasiadas respuestas aquí, pero tampoco encontré ninguna de ellas como quería. Extendí la respuesta de Ivan Klass para que Bootstrap 4 sea apropiada y se almacene en caché de manera inteligente.

Tenga en cuenta que el fragmento no cargará la dirección remota debido a la política CORS de 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
fuente
Pude adaptar este fácilmente a la solución que necesitaba. ¡Gracias!
Nieminen
0

Se ha dado una respuesta similar a esta en este hilo: Configurar el contenido de datos y mostrar el popover : es una manera mucho mejor de hacer lo que espera lograr. De lo contrario, tendrá que usar la opción live: true en las opciones del método popover. Ojalá esto ayude

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

    });

tenga en cuenta que utilicé la misma etiqueta href y la hice para que no cambie de página cuando se hace clic, esto es bueno para SEO y también si el usuario no tiene javascript.

Neo
fuente
0

Me gusta la solución de Çağatay, pero las ventanas emergentes no se escondían en el mouseout. Agregué esta funcionalidad adicional con esto:

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

Usé la solución original pero hice un par de cambios:

Primero, usé en getJSON()lugar de get()porque estaba cargando un script json. A continuación, agregué el comportamiento de activación de hover para solucionar el problema del pop-over.

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

Agregué html: true, por lo que no muestra la salida html sin procesar, en caso de que desee formatear sus resultados. También puede agregar más controles.

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

Mostrar popover ajax en un elemento estático con el disparador de desplazamiento:

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

¡El contenido de Ajax se carga una vez! verel.data('bs.popover').options.content = response;

SirCumz
fuente
0

Lo hice y funciona perfecto con ajax y cargando contenido emergente.

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

Puede consultarlo en http://kienthuchoidap.com . Vaya a esto y coloque el cursor sobre el nombre de usuario del usuario.

Ho Thanh Binh
fuente
0

Para mí, funciona cambiar el contenido de datos antes de cargar 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
fuente
0

Esto funciona para mí, este código corrige posibles problemas de alineación:

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

Por si acaso, el punto final que estoy usando devuelve html (un parcial de rieles)

Tomé parte del código de aquí https://stackoverflow.com/a/13565154/3984542

vicente.fava
fuente