Refactored sorting JS files to be includes so that server-side variables may be passed to them.

Added 'after_sorting_js_callback_name' attribute to SortableAdminBase.
Added callback to be executed after sorting for each of the possible sorting scenarios.
Added custom template examples to add a callback to be executed when sorting is finished.
master
Brandon Taylor 2018-06-18 11:40:24 -04:00
parent fa8a5f12a8
commit e35f36b25a
10 changed files with 270 additions and 193 deletions

View File

@ -32,6 +32,8 @@ class SortableAdminBase(object):
change_form_template_extends = 'admin/change_form.html' change_form_template_extends = 'admin/change_form.html'
change_list_template_extends = 'admin/change_list.html' change_list_template_extends = 'admin/change_list.html'
after_sorting_js_callback_name = None
def changelist_view(self, request, extra_context=None): def changelist_view(self, request, extra_context=None):
""" """
If the model that inherits Sortable has more than one object, If the model that inherits Sortable has more than one object,
@ -215,7 +217,8 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
'sortable_by_class_is_sortable': sortable_by_class_is_sortable, 'sortable_by_class_is_sortable': sortable_by_class_is_sortable,
'sortable_by_class_display_name': sortable_by_class_display_name, 'sortable_by_class_display_name': sortable_by_class_display_name,
'jquery_lib_path': jquery_lib_path, 'jquery_lib_path': jquery_lib_path,
'csrf_cookie_name': getattr(settings, 'CSRF_COOKIE_NAME', 'csrftoken') 'csrf_cookie_name': getattr(settings, 'CSRF_COOKIE_NAME', 'csrftoken'),
'after_sorting_js_callback_name': self.after_sorting_js_callback_name
}) })
return render(request, self.sortable_change_list_template, context) return render(request, self.sortable_change_list_template, context)
@ -238,7 +241,8 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
'change_form_template_extends': self.change_form_template_extends, 'change_form_template_extends': self.change_form_template_extends,
'has_sortable_tabular_inlines': self.has_sortable_tabular_inlines, 'has_sortable_tabular_inlines': self.has_sortable_tabular_inlines,
'has_sortable_stacked_inlines': self.has_sortable_stacked_inlines, 'has_sortable_stacked_inlines': self.has_sortable_stacked_inlines,
'csrf_cookie_name': getattr(settings, 'CSRF_COOKIE_NAME', 'csrftoken') 'csrf_cookie_name': getattr(settings, 'CSRF_COOKIE_NAME', 'csrftoken'),
'after_sorting_js_callback_name': self.after_sorting_js_callback_name
}) })
return super(SortableAdmin, self).change_view(request, object_id, return super(SortableAdmin, self).change_view(request, object_id,

View File

@ -1,4 +1,5 @@
(function($){ <script>
(function($){
$(function() { $(function() {
jQuery('.sortable').sortable({ jQuery('.sortable').sortable({
@ -36,6 +37,11 @@
}); });
ui.item.effect('highlight', {}, 1000); ui.item.effect('highlight', {}, 1000);
{% if after_sorting_js_callback_name %}
{# if a callback is defined in a custom template, execute it #}
window['{{ after_sorting_js_callback_name }}']();
{% endif %}
} }
}); });
} }
@ -44,4 +50,5 @@
}); });
}); });
})(django.jQuery); })(django.jQuery);
</script>

View File

@ -7,17 +7,17 @@
{% url 'admin:jsi18n' as jsi18nurl %} {% url 'admin:jsi18n' as jsi18nurl %}
{% if has_sortable_tabular_inlines or has_sortable_stacked_inlines %} {% if has_sortable_tabular_inlines or has_sortable_stacked_inlines %}
<script type="text/javascript" src="{% static 'adminsortable/js/jquery-ui-django-admin.min.js' %}"></script> <script src="{% static 'adminsortable/js/jquery-ui-django-admin.min.js' %}"></script>
<script src="{% static 'adminsortable/js/jquery.ui.touch-punch.min.js' %}"></script> <script src="{% static 'adminsortable/js/jquery.ui.touch-punch.min.js' %}"></script>
{% include 'adminsortable/csrf/jquery.django-csrf.html' with csrf_cookie_name=csrf_cookie_name %} {% include 'adminsortable/csrf/jquery.django-csrf.html' with csrf_cookie_name=csrf_cookie_name %}
{% endif %} {% endif %}
{% if has_sortable_tabular_inlines %} {% if has_sortable_tabular_inlines %}
<script type="text/javascript" src="{% static 'adminsortable/js/admin.sortable.tabular.inlines.js' %}"></script> {% include 'adminsortable/edit_inline/admin.sortable.stacked.inlines.html' with after_sorting_js_callback_name=after_sorting_js_callback_name %}
{% endif %} {% endif %}
{% if has_sortable_stacked_inlines %} {% if has_sortable_stacked_inlines %}
<script type="text/javascript" src="{% static 'adminsortable/js/admin.sortable.stacked.inlines.js' %}"></script> {% include 'adminsortable/edit_inline/admin.sortable.tabular.inlines.html' with after_sorting_js_callback_name=after_sorting_js_callback_name %}
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -21,14 +21,31 @@
{% endblock %} {% endblock %}
{% block extrahead %} {% block extrahead %}
{{ block.super }}
{{ media.js }}
<script src="{% static jquery_lib_path %}"></script> <script src="{% static jquery_lib_path %}"></script>
<script src="{% static 'admin/js/jquery.init.js' %}"></script> <script src="{% static 'admin/js/jquery.init.js' %}"></script>
{{ block.super }}
{{ media.js }}
<script src="{% static 'adminsortable/js/jquery-ui-django-admin.min.js' %}"></script> <script src="{% static 'adminsortable/js/jquery-ui-django-admin.min.js' %}"></script>
<script src="{% static 'adminsortable/js/jquery.ui.touch-punch.min.js' %}"></script> <script src="{% static 'adminsortable/js/jquery.ui.touch-punch.min.js' %}"></script>
{% include 'adminsortable/csrf/jquery.django-csrf.html' with csrf_cookie_name=csrf_cookie_name %} {% include 'adminsortable/csrf/jquery.django-csrf.html' with csrf_cookie_name=csrf_cookie_name %}
<script src="{% static 'adminsortable/js/admin.sortable.js' %}"></script> {% include 'adminsortable/admin.sortable.html' with after_sorting_js_callback_name=after_sorting_js_callback_name %}
<script type="text/javascript">
(function($) {
$(document).ready(function($) {
var url = window.location.href;
var urlParts = url.split('?');
var changeListUrl = $('a#return-to-changelist').attr('href');
if (urlParts.length === 2) {
$('a#return-to-changelist').attr(
'href',
changeListUrl + '?' + urlParts[1].replace('filter_expression=', '')
);
}
});
})(django.jQuery);
</script>
{% endblock %} {% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-list{% endblock %} {% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-list{% endblock %}

View File

@ -1,4 +1,5 @@
(function($){ <script>
(function($){
$(function() { $(function() {
var sorting_urls = $(':hidden[name="admin_sorting_url"]'); var sorting_urls = $(':hidden[name="admin_sorting_url"]');
@ -60,6 +61,11 @@
}); });
ui.item.find(highlightedSelector).effect('highlight', {}, 1000); ui.item.find(highlightedSelector).effect('highlight', {}, 1000);
{% if after_sorting_js_callback_name %}
{# if a callback is defined in a custom template, execute it #}
window['{{ after_sorting_js_callback_name }}']();
{% endif %}
} }
}); });
} }
@ -67,4 +73,6 @@
} }
}); });
})(django.jQuery); })(django.jQuery);
</script>

View File

@ -1,4 +1,5 @@
(function($){ <script>
(function($){
$(function() { $(function() {
var sorting_urls = $(':hidden[name="admin_sorting_url"]'); var sorting_urls = $(':hidden[name="admin_sorting_url"]');
@ -59,6 +60,11 @@
tabular_inline_rows.removeClass('row1 row2'); tabular_inline_rows.removeClass('row1 row2');
$('.tabular table tbody tr:odd').addClass('row2'); $('.tabular table tbody tr:odd').addClass('row2');
$('.tabular table tbody tr:even').addClass('row1'); $('.tabular table tbody tr:even').addClass('row1');
{% if after_sorting_js_callback_name %}
{# if a callback is defined in a custom template, execute it #}
window['{{ after_sorting_js_callback_name }}']();
{% endif %}
} }
}); });
} }
@ -66,4 +72,6 @@
} }
}); });
})(django.jQuery); })(django.jQuery);
</script>

View File

@ -83,6 +83,9 @@ class ProjectAdmin(SortableAdmin):
NonSortableCreditInline, NonSortableNoteInline NonSortableCreditInline, NonSortableNoteInline
] ]
list_display = ['__str__', 'category'] list_display = ['__str__', 'category']
after_sorting_js_callback_name = 'afterSortCallback'
sortable_change_list_template = 'adminsortable/custom_change_list.html'
sortable_change_form_template = "adminsortable/custom_change_form.html"
admin.site.register(Project, ProjectAdmin) admin.site.register(Project, ProjectAdmin)

View File

@ -0,0 +1,15 @@
{% extends "adminsortable/change_form.html" %}
{% block extrahead %}
{{ block.super }}
<script>
django.jQuery(document).on('order:changed', function(event) {
console.log(event.message);
});
window['{{ after_sorting_js_callback_name }}'] = function() {
django.jQuery(document).trigger({ type: 'order:changed', message: 'Order changed', time: new Date() });
};
</script>
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends 'adminsortable/change_list.html' %}
{% block extrahead %}
{{ block.super }}
<script>
django.jQuery(document).on('order:changed', function(event) {
console.log(event.message);
});
window['{{ after_sorting_js_callback_name }}'] = function() {
django.jQuery(document).trigger({ type: 'order:changed', message: 'Order changed', time: new Date() });
};
</script>
{% endblock %}