Recargar contenido en modal (twitter bootstrap)

98

Estoy usando la ventana emergente modal de twitter bootstrap.

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

Puedo cargar contenido usando ajax con este elemento a:

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

Ahora tengo que abrir el mismo modal pero usando una URL diferente. Estoy usando este modal para editar una entidad de mi base de datos. Entonces, cuando hago clic en editar en una entidad, necesito cargar el modal con una 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>

Si hago clic en el enlace número 1, funciona bien. Pero si hago clic en el enlace número 2, el contenido modal ya está cargado y, por lo tanto, mostrará el contenido del enlace número 1.

¿Cómo puedo actualizar o restablecer el contenido cargado ajax en una ventana emergente modal de arranque de Twitter?

stian.net
fuente
2
posible duplicado del modo remoto bootstrap
Marijn
Tenía el mismo problema y estaba acostumbrado a la misma solución. Recurro a la función .attr () de jquery por alguna extraña razón. La función .data () no funcionaba.
user1803784

Respuestas:

98

Estoy teniendo el mismo problema, y ​​supongo que la forma de hacerlo será eliminar el atributo de alternancia de datos y tener un controlador personalizado para los enlaces.

Algo en las líneas 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"); 
    });
});

Lo intentaré más tarde y publicaré comentarios.

Markz
fuente
16
$ ('. modal'). on ('hidden', function () {$ (this) .removeData ();}) esta es mi modificación de la siguiente solución ... más limpia porque no tienes que atrapar el clic y cargar it your self so programmatic model show still works
Carter Cole
1
Estoy usando Bootstrap 3, el contenido en el modal se actualiza cada vez pero crea dos ventanas modales. ¿Alguien más entiende esto?
Mr B
1
Hola Sid, estás creando 2 divs con la clase "modal-body", en realidad ya lo estás creando, y el modal se está creando de nuevo. De ese código, elimine el '.modal-body' y debería funcionar bien.
Palantir
1
Funciona para mí con Bootstrap 3, es muy frustrante que esto no sea compatible con la biblioteca principal de arranque de forma predeterminada.
Josh Diehl
@markz, también estoy usando algo como esto y ev.preventDefault (); también, pero aún al hacer clic en el enlace, cuando obtengo la ventana modal, se restablecen todos los menús desplegables de mi página. ¿Alguna idea, cómo prevenir eso?
Jaikrat
72

Para descargar los datos cuando el modal está cerrado, puede usar esto con Bootstrap 2.x:

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

Y en 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
fuente
Perfecto. funcionó sin ningún problema. en bootstrap 3. Usé $ ('. modal'). on ('hidden.bs.modal', function () {$ (this) .removeData ('bs.modal');});
Thupten
4
No perfecto: muestra brevemente el contenido antiguo antes que el nuevo.
Laurent
3
@Laurent, puede borrar el contenido anterior agregando .html (''). Entonces, para 2.x: $ (this) .removeData ('modal'). Find ('. Modal-body'). Html (''). Para 3: $ (this) .removeData ('bs.modal'). Html ('') 2.x carga contenido en .modal-body, mientras que 3 carga contenido directamente en el contenedor
.modal
pequeña corrección en el último comentario, en bootstrap v3 debería ser: $ (e.target) .removeData ('bs.modal'). html (''); Esta es la solución más elegante hasta ahora (pero se retrasa un poco).
Cesc
Usé la edición / versión que @Softlion publicó en esta solución propuesta; funcionó y no experimenté ningún problema de velocidad / demora.
user1801810
21

Puede forzar a Modal a actualizar la ventana emergente agregando esta línea al final del método hide del complemento Modal (si está usando bootstrap-transition.js v2.1.1, debería estar en la línea 836)

this.$element.removeData()

O con un oyente de eventos

$('#modal').on('hidden', function() {
    $(this).data('modal').$element.removeData();
})
Sergio
fuente
4
-1 La idea de poner ese primer fragmento en el complemento modal directamente es una idea terrible. Si fuera a piratear el complemento (lo que evitaría), lo más razonable sería mover la load()llamada fuera del constructor a la show(), o agregar un método al complemento para activar manualmente una recarga de remote. En la segunda sugerencia, solo proporcioné eso como respuesta a una pregunta que pedía explícitamente no hacerlo de la manera que sugirió @markz .
merv
2
Me gusta el enfoque del oyente. Creo que incluso se puede mejorar usando '.modal' en lugar de '#modal' para evitar codificar la identificación. En mi opinión, es un enfoque más limpio que el de markz, porque sigues usando el cambio de datos como en el modal de arranque original.
Toni Grimalt
Me pregunto por qué esta respuesta no tiene muchos votos a favor. Esta respuesta parece ser la primera que sugiere un detector de eventos que es bastante interesante y rápido de implementar.
Anupam
15

Con Bootstrap 3 puede usar el controlador de eventos 'hidden.bs.modal' para eliminar cualquier dato relacionado con el modo, lo que obliga a que la ventana emergente se vuelva a cargar la próxima vez:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
Arte
fuente
1
Sí, pero todavía hay un retraso crucial en esta solución; todavía muestra contenido antiguo durante uno o tres segundos antes que el nuevo.
doc feriado
en lugar de #modal try body
wobsoriano
8

Basado en otras respuestas (gracias a todos).

Necesitaba ajustar el código para que funcionara, ya que simplemente llamar a .html borraba todo el contenido y el modal no se cargaba con ningún contenido después de hacerlo. Así que simplemente busqué el área de contenido del modal y apliqué el restablecimiento del HTML allí.

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

Todavía puede ir con la respuesta aceptada, ya que estoy obteniendo un salto feo justo antes de las cargas modales, ya que el control es con Bootstrap.

Modika
fuente
5

Un poco más comprimido que el ejemplo aceptado anteriormente. Agarra el objetivo del objetivo de datos del actual clic en cualquier cosa con data-toggle = modal activado. Esto hace que no tenga que saber cuál es la identificación del modal de destino, ¡simplemente reutilice el mismo! menos código = ganar! También puede modificar esto para cargar títulos, etiquetas y botones para su modal si lo desea.

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

Enlaces de ejemplo:

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

Hice un pequeño cambio en la respuesta de Softlion , por lo que todos mis modales no se actualizarán en hide. Los modales con el atributo data-refresh = 'true' solo se actualizan, otros funcionan como de costumbre. Aquí está la versión 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('');
    }
});

Ahora use el atributo como se muestra a continuación,

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

Esto asegurará que solo se actualicen los modales con data-refresh = 'true'. Y también estoy restableciendo el html modal porque los valores antiguos se muestran hasta que se cargan los nuevos, lo que hace que el html vacío corrija ese.

Shiva Avula
fuente
2

Aquí hay una versión de coffeescript que me funcionó.

$(document).on 'hidden.bs.modal', (e) ->
  target = $(e.target)
  target.removeData('bs.modal').find(".modal-content").html('')
rgagnon
fuente
resolvió un problema donde el contenido se recarga pero js dentro del modal no se ejecuta por segunda vez
Souhaieb
1

Funcionará para todas las versiones de 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>

enlaces a modal son

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

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

También me quedé atrapado en este problema, luego vi que los identificadores del modal son los mismos. Necesita diferentes identificadores de modales si desea múltiples modales. Usé identificación dinámica . Aquí está mi código en haml:

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

Puedes hacerlo

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

y tus enlaces a modal serán

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

Espero que esto funcione para tí.

Asnad Atta
fuente
1

Puedes probar esto:

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

Quería eliminar el contenido cargado de AJAX cuando se cerró el modal, así que ajusté la línea sugerida por otros (sintaxis de coffeescript):

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

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

Trabajó para mi

Ashwin Golani
fuente
0

paso 1: crea un contenedor para el modal llamado clone-modal-wrapper.

paso 2: crea un div en blanco llamado modal-wrapper.

Paso 3: Copie el elemento modal de clone-modal-wrappera modal-wrapper.

paso 4: Alternar el 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
fuente