Carregue um conteúdo popover do Bootstrap com AJAX. Isso é possível?

90

As partes apropriadas do que tentei estão aqui:

<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 clico, vejo a solicitação ser feita, mas não preenche o popover. Eu nem mesmo vejo HTML para o popover ser adicionado ao DOM, mas pode ser firebug.

alguem ja tentou isso?

CambridgeMike
fonte
1
Não trabalhei com bootstrap, mas imagino que seja possível que o elemento não exista quando você está tentando adicionar conteúdo a ele, mas isso é um palpite. Você está recebendo algum erro de javascript?
Seth
Se você tiver vários popover e quiser carregar conteúdo diferente para cada popover, esta resposta é muito interessante e permite que você retenha muito da configuração inicial para popover - tudo o que você precisa fazer é armazenar a ID do popover nos atributos do link e lê-los no 'shown.bs.popover'manipulador: stackoverflow.com/a/39028723/1371408
Matty J

Respostas:

105

Veja minha postagem do blog para a solução de trabalho: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4

Primeiro devemos adicionar um atributo data-poload aos elementos que você gostaria de adicionar um pop-over. O conteúdo deste atributo deve ser o url a ser carregado (absoluto ou relativo):

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

E em JavaScript, preferencialmente em um $ (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')impede o carregamento de dados mais de uma vez e popover()vincula um novo evento de foco. Se você quiser que os dados sejam atualizados a cada evento de foco, você deve remover o off.

Por favor, veja o JSFiddle de trabalho do exemplo.

Çağatay Gürtürk
fonte
4
Fiquei esquisito quando passei o mouse duas vezes antes de completar a chamada ajax ... Meus popvers "grudavam" abertos. Resolvi movendo o "el.unbind ('hover')" para a direita antes de $ .get ().
Luke The Obscure,
1
Funciona, mas o popover também fica grudado em mim, embora a desassociação seja antes de começar
Androme
2
Se estiver tentando carregar um URL externo, você encontrará restrições de acesso entre domínios. Para contornar isso, você pode definir a htmlpropriedade do popover como e true, em seguida, definir a contentpropriedade como uma tag HTML iframe, como content: '<iframe src="http://www.google.com"></iframe>'. Você também precisará substituir a max-widthpropriedade de seu popover usando CSS e, provavelmente, remover o estilo do iframe usando CSS também.
Gavin
1
@FrzKhan você pode usar o e.off('hover')método
codenamev
3
isso não funciona porque stackoverflow.com/questions/4111194/… mudar para .hover (function () {}) funciona.
arisalexis
132

Funciona bem para mim:

$('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
fonte
1
Resposta de gênio! e é por isso que o editei para torná-lo mais legível
itsazzad de
2
Ótima solução. Com a versão atual do bootstrap, no entanto, parece que der pode ser algum problema para este método github.com/twbs/bootstrap/issues/12563 . Tive o problema duas vezes e a solução rápida foi garantir um título em cada popover. Isso também significa que, na verdade, nunca vejo o texto de carregamento que você está usando.
Rasmus Christensen
Funciona, exceto que tive que usar link de dados em vez de href, ao usar href meu navegador simplesmente abriria url em href em uma nova janela.
TinusSky
20
Isso não causa problemas de alinhamento? Ao usar essa abordagem no 3.3.1 (e usando o Chrome), o popover se alinha quando "Carregando ..." é exibido, mas assim que o conteúdo real do meu popover é carregado, o alinhamento não se ajusta de acordo. .
Matt
5
Ótima solução. Uma desvantagem dessa solução é que a chamada ajax é feita duas vezes. O componente popover é uma dica de ferramenta que primeiro verifica o conteúdo usando hasContent e, em seguida, obtém o conteúdo com setContent.
Liam
24

Depois de ler todas essas soluções, acho que a solução se torna muito mais simples se você usar uma chamada ajax síncrona . Você pode então 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');
  });
Confusão
fonte
1
Isso me ajudou muito, pois eu estava tendo um problema com a renderização do popover em uma determinada posição antes que o ajax retornasse o conteúdo (fazendo com que ele carregasse para fora da tela). Obrigado senhor!
Derek
Pode ser mais simples, mas também menos elegante do que a solução postada por @Ivan Klass.
Ian Kemp
6
async: falsemata isso para mim
mxmissile 01 de
Embora certamente seja mais fácil, JavaScript e código síncrono não funcionam bem juntos. Como o JavaScript é de thread único, isso bloqueará a execução de qualquer código pelo tempo que a solicitação levar.
IluTov 01 de
1
O AJAX síncrono está obsoleto.
Barmar de
10

Eu atualizei a resposta mais popular. Mas caso minhas alterações não sejam aprovadas, coloco aqui uma resposta separada.

As diferenças são:

  • LOADING texto mostrado enquanto o conteúdo está sendo carregado. Muito bom para conexão lenta.
  • Removida a cintilação que ocorre quando o mouse sai do popover pela primeira vez.

Primeiro devemos adicionar um atributo data-poload aos elementos que você gostaria de adicionar um pop-over. O conteúdo deste atributo deve ser o url a ser carregado (absoluto ou relativo):

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

E em JavaScript, preferencialmente em um $ (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')impede o carregamento de dados mais de uma vez e popover()vincula um novo evento de foco. Se você quiser que os dados sejam atualizados a cada evento de foco, você deve remover o off.

Por favor, veja o JSFiddle de trabalho do exemplo.

Alexander Chzhen
fonte
7

Uma variação do código de Çağatay Gürtürk, você poderia usar a função delegar em vez disso e forçar a ocultação do popover ao pairar.

$('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
fonte
Para jquery recente: $ ('* [data-poload]'). On ('mouseenter mouseleave', function (event) {
jpprade
7

A solução de Çağatay Gürtürk é boa, mas eu experimentei a mesma estranheza descrita por Luke The Obscure:

Quando o carregamento do ajax dura muito (ou os eventos do mouse são muito rápidos), temos um .popover ('show') e nenhum .popover ('ocultar') em um determinado elemento, fazendo com que o popover permaneça aberto.

Eu preferi essa solução de pré-carregamento massivo, todos os conteúdos do popover são carregados e os eventos são tratados por bootstrap como em popovers normais (estáticos).

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

    var el=$(this);

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

});
Fustaki
fonte
7

EM 2015, esta é a melhor resposta

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

Outra solução:

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

A idéia aqui é para acionar manualmente a exibição de Popover com mouseenter e MouseLeave eventos.

No mouseenter , se não houver PopOver criado para o seu item ( if ($ (this) .data ('popover') == null) ), crie-o. O que é interessante é que você pode definir seu próprio conteúdo PopOver, passando-o como argumento ( modelo ) para a função popover () . Não se esqueça de definir o parâmetro html como verdadeiro também.

Aqui, acabei de criar um modelo oculto chamado popovertemplate e cloná-lo com JQuery. Não se esqueça de excluir o atributo id depois de cloná-lo, caso contrário, você acabará com ids duplicados no DOM. Observe também que style = "display: none" para ocultar o modelo na 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>

Após a etapa de criação (ou se já tiver sido criada), você apenas exibe o popOver com $ (this) .popover ('show');

Em seguida, chamada de Ajax clássico. Em caso de sucesso, você precisa limpar o conteúdo antigo do popover antes de colocar novos dados novos do servidor . Como podemos obter o conteúdo popover atual? Com o seletor .popover.in ! A classe .in indica que o popover está sendo exibido no momento, esse é o truque aqui!

Para finalizar, no evento mouseleave , basta ocultar o popover.

doanduyhai
fonte
A mesma coisa para mim, o mais simples e melhor ;-)
Thomas Decaux
o problema com isso é em cada passagem que você está solicitando dados do servidor. Deve carregar os dados apenas uma vez.
Richard Torcato
2
@Richard Torcato Por um lado você está certo. Deve ser muito fácil colocar o resultado em um cache. Por outro lado, talvez queiramos acessar o servidor para carregar dados novos a cada passagem do mouse. Portanto, depende de você implementar o cache
doanduyhai
Sei que isso é antigo agora, mas caso alguém esteja olhando para isso, não consigo imaginar que funcione bem como se você tivesse vários popovers e rolar sobre cada um deles. Passe o mouse sobre A, solicitação enviada para A, Passe o mouse sobre B e permaneça com o mouse sobre ela, solicitação enviada para B, a resposta de B chega, atualiza o popover para B, a resposta para A chega, atualiza o popover para B (uma vez que a função de sucesso irá apenas desmarque qualquer coisa com essa classe.
Analisar
3

Aqui está minha solução que funciona bem com conteúdo carregado em Ajax também.

/*
 * 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';
}
furador
fonte
3

Se o conteúdo do popover não for alterado, faria sentido recuperá-lo apenas uma vez. Além disso, algumas das soluções aqui apresentam o problema de que, se você mover várias "visualizações" rapidamente, obterá vários pop-ups abertos. Esta solução aborda essas duas coisas.

$('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');
            }
        });
    }
});
reboque
fonte
3

Acho que minha solução é mais simples com a funcionalidade padrão.

http://jsfiddle.net/salt/wbpb0zoy/1/

$("a.popover-ajax").each(function(){
		 $(this).popover({
			trigger:"focus",
			placement: function (context, source) {
                  var obj = $(source);
				  $.get(obj.data("url"),function(d) {
                        $(context).html( d.titles[0].title)
                  });	
			},
			html:true,
			content:"loading"
		 });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>


<ul class="list-group">
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Cras justo odio</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Dapibus ac facilisis in</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Morbi leo risus</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Porta ac consectetur ac</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Vestibulum at eros</a></li>
</ul>

Salt Hareket
fonte
2

Há muitas respostas aqui, mas também não achei nenhuma delas o que eu queria. Eu estendi a resposta de Ivan Klass para ser apropriado ao Bootstrap 4 e inteligentemente armazenado em cache.

Observe que o snippet não carregará realmente o endereço remoto devido à política CORS do 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>

Arquônico
fonte
Consegui adaptar este facilmente à solução de que precisava. Obrigado!
Nieminen
1
Ótima solução, só tive que adicionar "sanitize: false," para popover config para lidar com meu css!
Guillaume
1

uma resposta semelhante a esta foi dada neste tópico: Configurando o conteúdo dos dados e exibindo o popover - é uma maneira melhor de fazer o que você espera alcançar. Caso contrário, você terá que usar a opção live: true nas opções do método popover. Espero que isso ajude

E Steven
fonte
1

Tentei a solução de Çağatay Gürtürk, mas obtive a mesma esquisitice de Luke, o Obscuro. Em seguida, tentei a solução de Asa Kusuma. Isso funciona, mas acredito que o Ajax lê todos o popover é exibido. A chamada para desvincular ('pairar') não tem efeito. Isso ocorre porque o delegado está monitorando eventos em uma classe específica - mas essa classe permanece inalterada.

Aqui está minha solução, estritamente baseada na de Asa Kusuma. Alterar:

  • Substituído delegatepor onpara corresponder às novas bibliotecas JQuery.
  • Remova a classe 'withajaxpopover' em vez do evento de foco desvinculado (que nunca foi vinculado)
  • Adicione "trigger: hover" ao popover para que o Bootstrap trate-o completamente começando com o segundo uso.
  • Minha função de carregamento de dados retorna JSon, o que torna mais fácil especificar o título e o conteúdo do popover.
    / * Objetivo: Exibir uma dica de ferramenta / popover onde o conteúdo é obtido do
              aplicação apenas na primeira vez.

        Como: Busque o conteúdo apropriado e registre a dica de ferramenta / popover pela primeira vez 
              o mouse entra em um elemento DOM com a classe "withajaxpopover". Remova o
              classe do elemento para que não façamos isso na próxima vez que o mouse entrar.
              No entanto, isso não mostra a dica de ferramenta / popover pela primeira vez
              (porque o mouse já está inserido quando a dica de ferramenta é registrada).
              Portanto, temos que mostrar / ocultar nós mesmos.
    * /
    $ (function () {
      $ ('body'). on ('hover', '.withajaxpopover', function (event) {
          if (event.type === 'mouseenter') {
              var el = $ (isto);
              $ .get (el.attr ('data-load'), function (d) {
                  el.removeClass ('withajaxpopover')
                  el.popover ({trigger: 'hover', 
                              título: d.title, 
                              content: d.content}). popover ('show');
              });
          } outro {
              $ (this) .popover ('ocultar');
          }
      });
    });
bwbecker
fonte
1

Experimentei algumas das sugestões aqui apresentadas e gostaria de apresentar a minha (que é um pouco diferente) - espero que ajude alguém. Eu queria mostrar o pop-up no primeiro clique e ocultá-lo no segundo clique (é claro, atualizando os dados a cada vez). Usei uma variável extra visablepara saber se o popover é visível ou não. Aqui está o meu 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);   
    });
}   
});

Felicidades!

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

Esta é uma maneira que aborda alguns problemas:

  1. Problemas de alinhamento após a atualização do conteúdo, especialmente se o canal for "superior". A chave está chamando ._popper.update(), que recalcula a posição do popover.
  2. A largura muda depois que o conteúdo é atualizado. Não quebra nada, apenas parece chocante para o usuário. Para diminuir isso, defino a largura do popover em 100% (que é então limitado pelo 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
fonte
Eu gosto dos conceitos, mas infelizmente eles não estão funcionando para mim ... (ou seja, a atualização de posição e largura de 100%) Não tem certeza se eles mudaram com o Bootstrap 4?
Ben em CA
A largura de 100% provavelmente depende de como seus elementos estão dispostos ... talvez. A caixa ainda está se alargando depois que o conteúdo é carregado?
Gabriel Luci
Para a posição, você pode definir um ponto de interrupção popover._popper.update()e certifique-se de que popover, _poppere updatetodos têm os valores esperados. É certamente possível que aqueles tenham mudado.
Gabriel Luci
Certo - a caixa se alarga após novo conteúdo. E tentei escrever alguns dos valores no console e estava ficando indefinido.
Ben em CA
1
- Você está certo. Acontece que eu estava tentando fazer algumas coisas mais complexas ao mesmo tempo e não estava funcionando. Mas agora também fui capaz de incorporar isso. Aqui está um violino: jsfiddle.net/udfz5wrv/1 Permite que você use seletores (se você precisar vincular manipuladores, etc.), acessar dados do seletor, exibir um botão giratório de carregamento de bootstrap etc.
Ben em 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()
        });

    });

note que usei a mesma tag href e fiz com que ela não mudasse de página quando clicada, isso é uma coisa boa para SEO e também se o usuário não tiver javascript!

Neo
fonte
0

Eu gosto da solução de Çağatay, mas os pop-ups não estavam se escondendo no mouseout. Eu adicionei esta funcionalidade extra com este:

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

Usei a solução original, mas fiz algumas alterações:

Primeiro, usei em getJSON()vez de get()porque estava carregando um script json. Em seguida, adicionei o comportamento de gatilho de foco para corrigir o problema de pop-up pegajoso.

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

Eu adicionei html: true, então ele não mostra a saída html bruta, caso você queira formatar seus resultados. Você também pode adicionar mais 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
fonte
0

Exibir popover ajax no elemento estático com gatilho de foco:

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

O conteúdo Ajax é carregado uma vez! Vejoel.data('bs.popover').options.content = response;

SirCumz
fonte
0

Eu fiz e funcionou perfeitamente com ajax e carregamento de conteúdo 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
            });

Você pode conferir http://kienthuchoidap.com . Vá para isso e passe o mouse até o nome de usuário do usuário.

Ho Thanh Binh
fonte
0

Para mim, o trabalho muda o conteúdo dos dados antes de carregar o 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
fonte
0

Isso funciona para mim, este código corrige possíveis problemas de alinhamento:

<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 precaução, o endpoint que estou usando retorna html (um parcial do rails)

Peguei parte do código daqui https://stackoverflow.com/a/13565154/3984542

vicente.fava
fonte