Recarregue o conteúdo em modal (bootstrap do Twitter)

98

Estou usando o pop-up modal do bootstrap do Twitter.

<div id="myModal" class="modal hide fade in">
    <div class="modal-header">
        <a class="close" data-dismiss="modal">×</a>
        <h3>Header</h3>
    </div>
    <div class="modal-body"></div>
    <div class="modal-footer">
        <input type="submit" class="btn btn-success" value="Save"/>
    </div>
</div>

Posso carregar conteúdo usando ajax com este elemento a:

<a data-toggle="modal" data-target="#myModal" href="edit.aspx">Open modal</a>

Agora tenho que abrir o mesmo modal, mas usando uma url diferente. Estou usando este modal para editar uma entidade do meu banco de dados. Portanto, quando clico em editar em uma entidade, preciso carregar o modal com um ID.

<a data-toggle="modal" data-target="#myModal" href="edit.aspx?id=1">Open modal</a>
<a data-toggle="modal" data-target="#myModal" href="edit.aspx?id=2">Open modal</a>
<a data-toggle="modal" data-target="#myModal" href="edit.aspx?id=3">Open modal</a>

Se eu clicar no link número 1, funciona bem. Mas se eu clicar no link número 2, o conteúdo modal já está carregado e, portanto, mostrará o conteúdo do link número 1.

Como posso atualizar ou redefinir o conteúdo carregado ajax em um pop-up modal bootstrap do Twitter?

stian.net
fonte
2
possível duplicata do modal remoto bootstrap
Marijn
Tive o mesmo problema e usei a mesma solução. Recorri à função .attr () do jquery por algum motivo estranho. A função .data () não estava funcionando.
user1803784

Respostas:

98

Estou tendo o mesmo problema e acho que a maneira de fazer isso será remover o atributo data-toggle e ter um manipulador personalizado para os links.

Algo nas linhas de:

$("a[data-target=#myModal]").click(function(ev) {
    ev.preventDefault();
    var target = $(this).attr("href");

    // load the url and show modal on success
    $("#myModal .modal-body").load(target, function() { 
         $("#myModal").modal("show"); 
    });
});

Vou tentar mais tarde e postar comentários.

Markz
fonte
16
$ ('. modal'). on ('escondido', function () {$ (this) .removeData ();}) esta é a minha modificação da solução abaixo ... mais limpa porque você não tem que pegar o clique e carregar faça você mesmo, então o modelo programático ainda funciona
Carter Cole
1
Estou usando o Bootstrap 3, o conteúdo do modal é atualizado a cada vez, mas cria duas janelas modais. Alguém conseguiu isso?
Sr. B
1
Ei Sid, você está criando 2 divs com a classe "modal-body", na verdade você já está criando, e o modal está criando novamente. A partir desse código, remova o '.modal-body' e deve funcionar bem.
Palantir
1
Funciona para mim com o Bootstrap 3, é muito frustrante que isso não seja suportado pela biblioteca de bootstrap principal por padrão.
Josh Diehl
@markz, também estou usando algo assim e ev.preventDefault (); também, mas ainda com o clique do link, quando eu obtenho a janela modal, todos os menus suspensos da minha página são redefinidos. Alguma ideia, como evitar isso?
Jaikrat
73

Para descarregar os dados quando o modal é fechado, você pode usar isso com o Bootstrap 2.x:

$('#myModal').on('hidden', function() {
    $(this).removeData('modal');
});

E no Bootstrap 3 ( https://github.com/twbs/bootstrap/pull/7935#issuecomment-18513516 ):

$(document.body).on('hidden.bs.modal', function () {
    $('#myModal').removeData('bs.modal')
});

//Edit SL: more universal
$(document).on('hidden.bs.modal', function (e) {
    $(e.target).removeData('bs.modal');
});
Steffen Wenzel
fonte
perfeito. funcionou sem nenhum problema. no bootstrap 3. Usei $ ('. modal'). on ('hidden.bs.modal', function () {$ (this) .removeData ('bs.modal');});
Thupten,
4
Não é perfeito: mostra brevemente o conteúdo antigo antes do novo conteúdo.
Laurent
3
@Laurent, você pode limpar o conteúdo anterior adicionando .html (''). Portanto, para 2.x: $ (this) .removeData ('modal'). Find ('. Modal-body'). Html (''). Para 3: $ (this) .removeData ('bs.modal'). Html ('') 2.x carrega conteúdo no .modal-body, enquanto 3 carrega conteúdo direto no contêiner
.modal
pequena correção no último comentário, no bootstrap v3 deve ser: $ (e.target) .removeData ('bs.modal'). html (''); Esta é a solução mais elegante até agora (mas demora um pouco).
Cesc
Usei a edição / versão que a @Softlion postou nesta solução proposta - funcionou e não tive problemas de velocidade / atraso.
user1801810
21

Você pode forçar o Modal a atualizar o pop-up adicionando esta linha no final do método de ocultar do plug-in Modal (se você estiver usando bootstrap-transit.js v2.1.1, deve estar na linha 836)

this.$element.removeData()

Ou com um ouvinte de evento

$('#modal').on('hidden', function() {
    $(this).data('modal').$element.removeData();
})
Sergio
fonte
4
-1 A ideia de colocar o primeiro snippet no plugin Modal diretamente é uma ideia terrível. Se você fosse hackear o plug-in (o que eu evitaria), a coisa mais razoável a fazer seria mover a load()chamada do construtor para o show(), ou adicionar um método ao plug-in para acionar manualmente uma recarga de remote. Sobre a segunda sugestão, eu apenas forneci isso como uma resposta para uma pergunta que explicitamente pedia para não fazer da maneira sugerida por @markz .
merv
2
Eu gosto da abordagem do ouvinte. Acho que pode até ser melhorado usando '.modal' em vez de '#modal' para evitar a codificação do id. Na minha opinião, é uma abordagem mais limpa do que a do markz, porque você continua usando o data-toggle como no modal bootstrap original.
Toni Grimalt
Eu me pergunto por que essa resposta não teve muitos votos positivos. Esta resposta parece ser a primeira a sugerir um ouvinte de evento bastante interessante e rápido de implementar.
Anupam
15

Com o Bootstrap 3, você pode usar o manipulador de eventos 'hidden.bs.modal' para excluir qualquer dado relacionado ao modal, forçando o pop-up a recarregar na próxima vez:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
Arte
fonte
1
Sim, mas ainda há um atraso crucial nessa solução; ele ainda mostra o conteúdo antigo por um ou três segundos antes do novo.
feriado do doc de
em vez de #modal try body
wobsoriano
8

Com base em outras respostas (obrigado a todos).

Eu precisei ajustar o código para funcionar, já que simplesmente chamar .html apagava todo o conteúdo e o modal não carregava com nenhum conteúdo depois que eu fizesse isso. Então, simplesmente procurei a área de conteúdo do modal e apliquei a redefinição do HTML lá.

    $(document).on('hidden.bs.modal', function (e) {
        var target = $(e.target);
        target.removeData('bs.modal')
              .find(".modal-content").html('');
    });

Ainda posso ir com a resposta aceita, pois estou obtendo um salto feio pouco antes do modal carrega, pois o controle é com Bootstrap.

Modika
fonte
5

Um pouco mais comprimido do que o exemplo acima aceito. Pega o alvo do alvo de dados do objeto clicado atual com data-toggle = modal ativado. Isso faz com que você não precise saber qual é o id do modal de destino, apenas reutilize o mesmo! menos código = vitória! Você também pode modificar isso para carregar títulos, rótulos e botões para o seu modal, se desejar.

 $("[data-toggle=modal]").click(function(ev) {
    ev.preventDefault();
    // load the url and show modal on success
    $( $(this).attr('data-target') + " .modal-body").load($(this).attr("href"), function() { 
         $($(this).attr('data-target')).modal("show"); 
    });
});

Links de exemplo:

<a data-toggle="modal" href="/page/api?package=herp" data-target="#modal">click me</a>
<a data-toggle="modal" href="/page/api?package=derp" data-target="#modal">click me2</a>
<a data-toggle="modal" href="/page/api?package=merp" data-target="#modal">click me3</a>
geilt
fonte
3

Fiz uma pequena alteração na resposta do Softlion , então todos os meus modais não serão atualizados em hide. Os modais com atributo data-refresh = 'true' são apenas atualizados, outros funcionam normalmente. Aqui está a versão modificada.

$(document).on('hidden.bs.modal', function (e) {
    if ($(e.target).attr('data-refresh') == 'true') {
        // Remove modal data
        $(e.target).removeData('bs.modal');
        // Empty the HTML of modal
        $(e.target).html('');
    }
});

Agora use o atributo conforme mostrado abaixo,

<div class="modal fade" data-refresh="true" id="#modal" tabindex="-1" role="dialog" aria-labelledby="#modal-label" aria-hidden="true"></div>

Isso garantirá que apenas os modais com data-refresh = 'true' sejam atualizados. E também estou redefinindo o html modal porque os valores antigos são mostrados até que os novos sejam carregados, tornando esse html vazio.

Shiva Avula
fonte
2

Aqui está uma versão em coffeescript que funcionou para mim.

$(document).on 'hidden.bs.modal', (e) ->
  target = $(e.target)
  target.removeData('bs.modal').find(".modal-content").html('')
rgagnon
fonte
resolveu um problema em que o conteúdo recarregava, mas o js dentro do modal não era executado uma segunda vez
Souhaieb
1

Funcionará para todas as versões do twitterbootstrap

Código Javascript:

<script type="text/javascript">
/* <![CDATA[ */
(function(){
   var bsModal = null;
   $("[data-toggle=modal]").click(function(e) {
      e.preventDefault();
      var trgId = $(this).attr('data-target'); 
      if ( bsModal == null ) 
       bsModal = $(trgId).modal;
      $.fn.bsModal = bsModal;
      $(trgId + " .modal-body").load($(this).attr("href"));
      $(trgId).bsModal('show');
    });
 })();
/* <![CDATA[ */
</script>

links para modal são

<a data-toggle="modal" data-target="#myModal" href="edit1.aspx">Open modal 1</a>
<a data-toggle="modal" data-target="#myModal" href="edit2.aspx">Open modal 2</a>
<a data-toggle="modal" data-target="#myModal" href="edit3.aspx">Open modal 3</a>

pop up modal

<div id="myModal" class="modal hide fade in">
<div class="modal-header">
    <a class="close" data-dismiss="modal">×</a>
    <h3>Header</h3>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
    <input type="submit" class="btn btn-success" value="Save"/>
</div>

Bijaya Kumar
fonte
1

Eu também estava preso neste problema quando vi que os ids do modal são os mesmos. Você precisa de diferentes ids de modais se quiser vários modais. Eu usei id dinâmico . Aqui está meu código em haml:

.modal.hide.fade{"id"=> discount.id,"aria-hidden" => "true", "aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1"}

você consegue fazer isso

<div id="<%= some.id %>" class="modal hide fade in">
  <div class="modal-header">
    <a class="close" data-dismiss="modal">×</a>
    <h3>Header</h3>
  </div>
  <div class="modal-body"></div>
  <div class="modal-footer">
    <input type="submit" class="btn btn-success" value="Save" />
  </div>
</div>

e seus links para modal serão

<a data-toggle="modal" data-target="#" href='"#"+<%= some.id %>' >Open modal</a>
<a data-toggle="modal" data-target="#myModal" href='"#"+<%= some.id %>' >Open modal</a>
<a data-toggle="modal" data-target="#myModal" href='"#"+<%= some.id %>' >Open modal</a>

Eu espero que isso funcione para você.

Asnad Atta
fonte
1

Você pode tentar isto:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
bharat
fonte
0

Eu queria que o conteúdo carregado em AJAX fosse removido quando o modal fosse fechado, então ajustei a linha sugerida por outros (sintaxe coffeescript):

$('#my-modal').on 'hidden.bs.modal', (event) ->
  $(this).removeData('bs.modal').children().remove()
paredes vazias
fonte
0

var $ table = $ ('# myTable2');
$ table.bootstrapTable ('destruir');

Funcionou para mim

Ashwin Golani
fonte
0

etapa 1: crie um wrapper para o modal chamado clone-modal-wrapper .

etapa 2: crie um div em branco chamado modal-wrapper.

Etapa 3: copie o elemento modal de clone-modal-wrapperpara modal-wrapper.

etapa 4: Alterne o modal de modal-wrapper.

<a data-toggle="modal" class='my-modal'>Open modal</a>

<div class="clone-modal-wrapper">
   <div class='my-modal' class="modal fade">
      <div class="modal-dialog">
         <div class="modal-content">
            <div class="modal-header">
               <a class="close" data-dismiss="modal">×</a>
               <h3>Header</h3>
            </div>
            <div class="modal-body"></div>
            <div class="modal-footer">
               <input type="submit" class="btn btn-success" value="Save"/>
            </div>
         </div>
      </div>
   </div>
</div>

<div class="modal-wrapper"></div>


$("a[data-target=#myModal]").click(function (e) {
    e.preventDefault();
    $(".modal-wrapper").html($(".clone-modal-wrapper").html());
    $('.modal-wrapper').find('.my-modal').modal('toggle');
});
Soubhagya Kumar Barik
fonte