Reordering questions with drag'n'drop

This commit is contained in:
sohalt
2019-10-07 23:21:33 +02:00
parent 9e85d3c94c
commit 587f0a53f7
7 changed files with 3757 additions and 3 deletions
@@ -43,6 +43,7 @@
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/quota.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/subevent.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/question.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/dragndroplist.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/mail.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/orderchange.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/typeahead.js" %}"></script>
@@ -51,6 +52,7 @@
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/tabs.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/details.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/asynctask.js" %}"></script>
<script type="text/javascript" src="{% static "sortable/Sortable.js" %}"></script>
<script type="text/javascript" src="{% static "colorpicker/bootstrap-colorpicker.js" %}"></script>
<script type="text/javascript" src="{% static "fileupload/jquery.ui.widget.js" %}"></script>
<script type="text/javascript" src="{% static "fileupload/jquery.fileupload.js" %}"></script>
@@ -39,9 +39,9 @@
<th class="action-col-2"></th>
</tr>
</thead>
<tbody>
<tbody data-dnd-url="{% url "control:event.items.questions.reorder" organizer=request.event.organizer.slug event=request.event.slug %}">
{% for q in questions %}
<tr>
<tr data-dnd-id="{{q.id}}">
<td><strong><a href="
{% url "control:event.items.questions.show" organizer=request.event.organizer.slug event=request.event.slug question=q.id %}">{{ q.question }}</a></strong>
</td>
+1
View File
@@ -164,6 +164,7 @@ urlpatterns = [
name='event.items.categories.edit'),
url(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'),
url(r'^questions/$', item.QuestionList.as_view(), name='event.items.questions'),
url(r'^questions/reorder$', item.reorder_questions, name='event.items.questions.reorder'),
url(r'^questions/(?P<question>\d+)/delete$', item.QuestionDelete.as_view(),
name='event.items.questions.delete'),
url(r'^questions/(?P<question>\d+)/up$', item.question_move_up, name='event.items.questions.up'),
+17 -1
View File
@@ -7,7 +7,7 @@ from django.core.files import File
from django.db import transaction
from django.db.models import Count, F, Prefetch, Q
from django.forms.models import inlineformset_factory
from django.http import Http404, HttpResponseRedirect
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect
from django.urls import resolve, reverse
from django.utils.functional import cached_property
@@ -283,6 +283,22 @@ class QuestionList(PaginationMixin, ListView):
return self.request.event.questions.prefetch_related('items')
def reorder_questions(request, organizer, event):
ids = json.loads(request.body.decode('utf-8'))['ids']
questions = request.event.questions
if questions.count() != questions.filter(id__in=ids).count():
raise Http404(_("The provided question ids are invalid."))
for i, id in enumerate(ids):
qt = questions.get(id=id)
if qt.position != i:
qt.position = i
qt.save()
return HttpResponse()
def question_move(request, question, up=True):
"""
This is a helper function to avoid duplicating code in question_move_up and
@@ -0,0 +1,30 @@
/*global $, Sortable*/
$(function () {
$("[data-dnd-url]").each(function(){
var container = $(this),
url = container.data("dnd-url"),
handle = $("<span>", {class: "btn btn-default btn-sm dnd-sort-handle"});
handle.append('<i class="fa fa-arrows"></i>');
container.find("a:has(.fa-arrow-up)").remove();
container.find("a:has(.fa-arrow-down)").replaceWith(handle);
Sortable.create(container.get(0), {
handle: ".dnd-sort-handle",
onSort: function(evt){
var ids = $(evt.to).find("[data-dnd-id]").toArray().map(e => e.dataset.dndId);
$.ajax(
{
'type': 'POST',
'url': url,
'headers': {'X-CSRFToken': $("input[name=csrfmiddlewaretoken]").val()},
'data': JSON.stringify({
ids: ids
}),
'contentType': "application/json",
'timeout': 30000
}
);
}
});
});
});
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long