Quiero poder arrastrar un elemento en la página a un elemento desplegable dentro de un div cargado con ajax. Puedo hacer que el código funcione cuando coloco el elemento desplegable en la página normal, pero no cuando tengo el mismo elemento en el div cargado con ajax. Estoy bastante seguro de que es por la forma en que llamo a los scripts y cómo se cargan en el dom, pero no puedo encontrar la solución. Nota: He intentado llamar al código que carga el contenido de ajax antes de llamar a jquery ui pero tampoco funcionó. Así es como llamo a todo, eliminé el código extraño por brevedad.

Pagina principal

<head>
<scripts -- jquery, jquery ui>
<script>
  $(document).ready(function(){
      $( "#site-preview" ).load( "/site/preview" );
   });
</script>
</head>
<body>

<div class="draggable><img src=//etc/> </div>

//if I put this div here, I can drop to it, so i know the drop code works.
// <div class="droppable col-md-2" style="height:100px;border:1px solid gray"><p> </p></div>

<div id="site-preview"></div>

<script>
  $(function() {
    $( ".draggable" ).draggable({
      helper:'clone',
      appendTo: 'body',
      scroll: false
     });
$( ".droppable" ).droppable({
      drop: function( event, ui ) {
        $( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
      }
    });
  });
  </script>


</body>

Código cargado ajax

<div class="droppable col-md-2" style="height:100px;border:1px solid gray">
  <p> </p>
</div>
0
Severian 28 ago. 2014 a las 18:18

3 respuestas

La mejor respuesta

Esto se aplica porque intenta llamar al droppable en un elemento no existente en ese momento. Para resolver esto, puede usar la función de devolución de llamada que se puede adjuntar a la función load y ejecutar el resto después de eso.

$(document).ready(function(){
  $("#site-preview").load("/site/preview", function() {
    // Page loaded and injected
    // We launch the rest of the code
    $( ".draggable" ).draggable({
      helper:'clone',
      appendTo: 'body',
      scroll: false
     });
    $( ".droppable" ).droppable({
      drop: function( event, ui ) {
        $( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
      }
    });
  });
});

Puede encontrar otra información sobre la función load aquí. La devolución de llamada puede tomar argumentos y puede usarse, por ejemplo, para verificar si es un 404 o no.

1
gaelgillard 28 ago. 2014 a las 14:45

Bueno, pude hacerlo funcionar agregando el código arrastrable / soltable al div cargado con ajax. Entonces, lo anterior se enmendaría así

Código cargado ajax

<div class="droppable col-md-2" style="height:100px;border:1px solid gray">
  <p> </p>
</div>

<script>
  $(function() {
    $( ".draggable" ).draggable({
      helper:'clone',
      appendTo: 'body',
      scroll: false //stops scrolling container when moved outside boundaries
    });
$( ".droppable" ).droppable({
      drop: function( event, ui ) {
        $( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
      }
    });
  });
  </script>

Y esas líneas de guión serían sacadas de la página principal

0
Severian 28 ago. 2014 a las 14:44

Ajax es Asíncrono . Entonces, si llamas a un ajax y luego llamas a otro comando, el ajax generalmente terminará después.

Aquí es donde las devoluciones de llamada son útiles. Intente agregar una devolución de llamada a la llamada ajax load como se muestra aquí: http://api.jquery.com / load /

Algo así como:

$( "#site-preview" ).load( "/site/preview", function(){
    $( ".droppable" ).droppable({
        drop: function( event, ui ) {
            $( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
        }
    });
});

Nota al margen: probablemente debería comenzar a usar scripts en lugar de las etiquetas <script>.

0
DanielST 28 ago. 2014 a las 14:48