Estoy tratando de implementar una lista ordenable de arrastrar y soltar usando SortableJS y htmx. Lo tengo funcionando una vez, pero después de arrastrar y soltar el primer elemento (y el renderizado parcial) ya no puedo usar la funcionalidad de arrastrar y soltar. Cuando no se vuelve a renderizar un parcial, la funcionalidad de arrastrar y soltar funciona como se esperaba. He intentado usar htmx.on("htmx:load",... así como poner el script en el parcial.
He usado diff para verificar las diferencias entre el html antes y después de que se represente el parcial y, por lo que puedo decir, la única diferencia fuera de la lista reordenada es el token csrf.
¡Cualquier ayuda sería apreciada!
Desde vistas.py:
def sort(request): event_pks_order = request.POST.getlist('event_order') events=[] for idx,event_pk in enumerate(event_pks_order,start=1): event = Event.objects.get(pk=event_pk) event.event_number = idx event.save() events.append(event) return render(request,'timing/partials/eventlist.html',{'events':events})De eventlist.html:
<form class="sortable list-group" hx-trigger="end" hx-post="{% url 'sort' %}" hx-target="#event-list"> {% csrf_token %} <div class="htmx-indicator">Updating...</div> {% for event in events %} <div> <input type="hidden" name="event_order" value="{{event.pk}}"/> <li class="list-group-item">{{event.event_number}} {{event.event_name}} </li> </div> {% endfor %} </form>De base.html:
<script> document.body.addEventListener('htmx:configRequest', (event) => { event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}'; }) htmx.onLoad(function(content) { var sortables = content.querySelectorAll(".sortable"); for (var i = 0; i < sortables.length; i++) { var sortable = sortables[i]; new Sortable(sortable, { animation: 150, ghostClass: 'blue-background-class' }); } }) </script>Creo que SortableJS hace algo de inicialización en HTML.
Por lo tanto, funciona bien por primera vez, pero el nuevo HTML que se intercambia con htmx no se inicializa.
Esta es una trampa común.
Por casualidad, use el mismo ejemplo que usted: ordenable :-)
Aquí tienes la documentación al respecto: https://htmx.org/docs/#3rd-party
En htmx, en su lugar, usaría la función htmx.onLoad y seleccionaría solo del contenido recién cargado, en lugar de todo el documento:
htmx.onLoad(function(content) { var sortables = content.querySelectorAll(".sortable"); for (var i = 0; i < sortables.length; i++) { var sortable = sortables[i]; new Sortable(sortable, { animation: 150, ghostClass: 'blue-background-class' }); } })Esto garantizará que, a medida que htmx agregue contenido nuevo al DOM, los elementos ordenables se inicialicen correctamente.
¿Esto resuelve tu pregunta?
¿Se ha aclarado esto?
Me enfrenté al mismo problema.
Resolví este problema cambiando el archivo de plantilla de destino para representar la función de clasificación en views.py.
Por así decirlo, parece que necesita cambiar esta línea.
return render(request,'timing/partials/eventlist.html',{'events':events})Tiene un comentario "¿Dónde está el elemento que tiene la identificación de la lista de eventos que configuró en hx-target?" –por el Sr./Sra. Dauros
No puedo comentar porque necesito más de 49 reputaciones para comentar.
Pero predigo que su archivo de plantilla "eventlist.html" puede incluirse en otro archivo HTML de plantilla usando la etiqueta {% include %} a juzgar por su código fuente que es similar al tutorial BugBytes HTMX y Django en YouTube y usa hx-target dentro del formulario etiqueta.
El repositorio de ese curso aquí de nuevo.
Hice una publicación en Stackoverflow sobre este mismo problema, así que consúltala.
El enlace está abajo.
HTMX sortable funciona solo una vez, el renderizado lo desactiva
¡Espero que esta respuesta sea útil para su asunto y para otros futuros estudiantes! :)