I am trying to implement a drag and drop sortable list using SortableJS and htmx. I have it working once, but after dragging and dropping the first element (and the partial being re rendered) I can no longer use the drag and drop functionality. When a partial isn't rerendered the drag and drop functionality works as expected. I have tried using htmx.on("htmx:load",... as well as putting the script in the partial.
I've used diff to check the differences between the html before and after the partial is rendered and as far as I can tell the only difference outside the reordered list is the csrf token.
Any help would be appreciated!
From views.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})
From 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>
From 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>