Можно ли упорядочить список на основе значений, предоставленных пользователем, используя только HTMX?
У меня работает HTMX. Приведенный ниже код полностью функционален. Единственное, что я хотел бы включить, но не могу понять, как это сделать. Пользователь может указать числовой ранг... но когда он нажимает сохранить, вид возвращается с элементом наверху. Только после того, как пользователь нажимает перезагрузку, список сортируется сам по себе на основе того, как я определил атрибуты в модели.
Вот мой HTML...
<h1 class="title62">Tasks</h1>
<button class="button36" hx-get="{% url 'MyTasks:create_task_form' %}" hx-target="#taskforms">Add Task</button>
<div id="taskforms"></div>
<div id="tblData">
{% if tasks %}
{% for task in tasks %}
{% include "partials/task_detail.html" %}
{% endfor %}
</div>
{% endif %}
<div hx-target="this" hx-swap="outerHTML" hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}' class="" >
<form method="POST">
{% csrf_token %}
<div class="table22">
<table class="table23">
<thead>
<tr>
<th class="title67">Number</th>
<th class="title67">Task</th>
</tr>
</thead>
<tbody>
<button class="button35" hx-post=".">
Save
</button>
<button type="button" class="button33">
Delete
</button>
<tr>
<td class="title73">{{ form.number }}</td>
<td class="title73">{{ form.task }}</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
<script>
document.body.addEventListener('htmx:configRequest', (event) => {
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
})
</script>
<div hx-target="this" class="">
<div class="table22">
<table class="table23">
<thead>
<tr>
<th class="title67">Number</th>
<th class="title67">Task</th>
</tr>
</thead>
<tbody>
<button class="button35" hx-get="{% url 'MyTasks:update_task' task.id %}" hx-swap="outerHTML">
Update
</button>
<button class="button34" hx-confirm="Are you sure you want to delete?" hx-post="{% url 'MyTasks:delete_task' task.id %}" hx-swap="outerHTML">
Delete
</button>
<tr>
<td class="title70">{{ task.number }}</td>
<td class="title70">{{ task.task }}</td>
</tr>
</tbody>
</table>
</div>
</div>
Моя модель...
class Task(models.Model):
task = models.TextField(max_length=264,blank=True,null=True,unique=False)
number = models.PositiveIntegerField(default=1)
class Meta:
ordering = ["number"]
def __str__(self):
return self.task
Я начал изучать использование Javascript для сортировки HTML, чтобы подойти к моей проблеме таким образом. Просто мне кажется, что при наличии возможностей HTMX должен быть способ сделать это, используя HTMX. Заранее спасибо за любые мысли.
Думаю, самым простым способом будет просто подменить весь список при сохранении, а не только новый элемент - так вы сможете воспользоваться упорядочиванием в модели.
Техника HTMX, которую вы ищете, - это Out of Band Swapping, которая в основном представляет собой один запрос с несколькими целями. Цели могут быть в любом месте страницы. В вашем случае: когда пользователь создает, изменяет или удаляет задачу, ответ также должен содержать обновленный список задач. Это требует лишь нескольких модификаций. Например, представление обновления задачи:
def update_view(request):
tasks_updated = False
tasks = None
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
# Update the task in the database
...
task.save()
tasks_updated = True
else:
# Return the form with errors
return render(request, 'task_form.html', {'form': form})
if tasks_updated:
# Fetch new list of tasks
tasks = Task.objects.order_by('number')
return render(request, 'task.html', {'tasks': tasks, 'task': task})
У нас есть переменная отслеживания tasks_updated, на которую мы переключаемся True, если мы обновили задачу в базе данных, поэтому список задач нуждается в обновлении на фронтенде. Непосредственно перед отрисовкой шаблона мы проверяем значение этой переменной и при необходимости подбираем задачи.
И частичный шаблон:
<div>
<!-- Render the task's table as usual. -->
</div>
{% if tasks %}
<div id="tblData" hx-swap-oob="true">
{% for task in tasks %}
{% include "partials/task_detail.html" %}
{% endfor %}
</div>
{% endif %}
Здесь мы отображаем таблицу только у нас есть переменная tasks, поэтому по крайней мере одна из задач была обновлена, поэтому мы загрузили и задачи. Переменная hx-swap-oob="true" говорит HTMX поменять местами элемент, имеющий tblData id.
В принципе, это все. Просто включайте список задач OOB-Swap в каждый ответ, где список задач нуждается в обновлении. Если вы загружаете "форму новой задачи", она вам не нужна, но если вы добавляете/обновляете/удаляете задачу, вам нужен свежий список задач OOB-Swap в ответе (извлекаемый из базы данных после завершения операции задачи).