Merged after-sort-callback branch and fixed conflicts.
commit
5ad2c0e4ec
|
|
@ -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,
|
||||||
|
|
@ -206,7 +208,11 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
verbose_name_plural = opts.verbose_name_plural
|
verbose_name_plural = opts.verbose_name_plural
|
||||||
|
|
||||||
context = self.admin_site.each_context(request)
|
if VERSION <= (1, 7):
|
||||||
|
context = {}
|
||||||
|
else:
|
||||||
|
context = self.admin_site.each_context(request)
|
||||||
|
|
||||||
context.update({
|
context.update({
|
||||||
'title': u'Drag and drop {0} to change display order'.format(
|
'title': u'Drag and drop {0} to change display order'.format(
|
||||||
capfirst(verbose_name_plural)),
|
capfirst(verbose_name_plural)),
|
||||||
|
|
@ -218,7 +224,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)
|
||||||
|
|
||||||
|
|
@ -241,7 +248,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,
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,54 @@
|
||||||
(function($){
|
<script>
|
||||||
|
(function($){
|
||||||
$(function() {
|
|
||||||
jQuery('.sortable').sortable({
|
$(function() {
|
||||||
axis : 'y',
|
jQuery('.sortable').sortable({
|
||||||
containment : 'parent',
|
axis : 'y',
|
||||||
tolerance : 'pointer',
|
containment : 'parent',
|
||||||
items : 'li',
|
tolerance : 'pointer',
|
||||||
stop : function(event, ui) {
|
items : 'li',
|
||||||
var indexes = [],
|
stop : function(event, ui) {
|
||||||
lineItems = ui.item.parent().find('> li');
|
var indexes = [],
|
||||||
|
lineItems = ui.item.parent().find('> li');
|
||||||
lineItems.each(function(i) {
|
|
||||||
indexes.push($(this).find(':hidden[name="pk"]').val());
|
lineItems.each(function(i) {
|
||||||
});
|
indexes.push($(this).find(':hidden[name="pk"]').val());
|
||||||
|
});
|
||||||
$.ajax({
|
|
||||||
url: ui.item.find('a.admin_sorting_url').attr('href'),
|
$.ajax({
|
||||||
type: 'POST',
|
url: ui.item.find('a.admin_sorting_url').attr('href'),
|
||||||
data: { indexes: indexes.join(',') },
|
type: 'POST',
|
||||||
success: function() {
|
data: { indexes: indexes.join(',') },
|
||||||
// set icons based on position
|
success: function() {
|
||||||
lineItems.each(function(index, element) {
|
// set icons based on position
|
||||||
var icon = $(element).find('a.admin_sorting_url .fa');
|
lineItems.each(function(index, element) {
|
||||||
icon.removeClass('fa-sort-desc fa-sort-asc fa-sort');
|
var icon = $(element).find('a.admin_sorting_url .fa');
|
||||||
|
icon.removeClass('fa-sort-desc fa-sort-asc fa-sort');
|
||||||
if (index === 0) {
|
|
||||||
icon.addClass('fa fa-sort-desc');
|
if (index === 0) {
|
||||||
}
|
icon.addClass('fa fa-sort-desc');
|
||||||
else if (index == lineItems.length - 1) {
|
}
|
||||||
icon.addClass('fa fa-sort-asc');
|
else if (index == lineItems.length - 1) {
|
||||||
}
|
icon.addClass('fa fa-sort-asc');
|
||||||
else {
|
}
|
||||||
icon.addClass('fa fa-sort');
|
else {
|
||||||
}
|
icon.addClass('fa fa-sort');
|
||||||
});
|
}
|
||||||
|
});
|
||||||
ui.item.effect('highlight', {}, 1000);
|
|
||||||
}
|
ui.item.effect('highlight', {}, 1000);
|
||||||
});
|
|
||||||
}
|
{% if after_sorting_js_callback_name %}
|
||||||
}).click(function(e){
|
{# if a callback is defined in a custom template, execute it #}
|
||||||
e.preventDefault();
|
window['{{ after_sorting_js_callback_name }}']();
|
||||||
});
|
{% endif %}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
})(django.jQuery);
|
}
|
||||||
|
}).click(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
})(django.jQuery);
|
||||||
|
</script>
|
||||||
|
|
@ -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 %}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,14 @@
|
||||||
{% 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">
|
<script type="text/javascript">
|
||||||
(function($) {
|
(function($) {
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,78 @@
|
||||||
(function($){
|
<script>
|
||||||
|
(function($){
|
||||||
$(function() {
|
|
||||||
var sorting_urls = $(':hidden[name="admin_sorting_url"]');
|
$(function() {
|
||||||
if (sorting_urls.length > 0)
|
var sorting_urls = $(':hidden[name="admin_sorting_url"]');
|
||||||
{
|
if (sorting_urls.length > 0)
|
||||||
var sortable_inline_groups = sorting_urls.closest('.inline-group')
|
{
|
||||||
var sortable_inline_rows = sortable_inline_groups.find('.inline-related');
|
var sortable_inline_groups = sorting_urls.closest('.inline-group')
|
||||||
|
var sortable_inline_rows = sortable_inline_groups.find('.inline-related');
|
||||||
sortable_inline_groups.addClass('sortable')
|
|
||||||
sortable_inline_rows.addClass('sortable');
|
sortable_inline_groups.addClass('sortable')
|
||||||
|
sortable_inline_rows.addClass('sortable');
|
||||||
sortable_inline_groups.sortable({
|
|
||||||
axis : 'y',
|
sortable_inline_groups.sortable({
|
||||||
containment : 'parent',
|
axis : 'y',
|
||||||
create: function(event, ui) {
|
containment : 'parent',
|
||||||
$('.inline-related :checkbox').unbind();
|
create: function(event, ui) {
|
||||||
},
|
$('.inline-related :checkbox').unbind();
|
||||||
tolerance : 'pointer',
|
},
|
||||||
items : '.inline-related',
|
tolerance : 'pointer',
|
||||||
stop : function(event, ui)
|
items : '.inline-related',
|
||||||
{
|
stop : function(event, ui)
|
||||||
if ($('.inline-deletelink').length > 0) {
|
{
|
||||||
$(ui.sender).sortable('cancel');
|
if ($('.inline-deletelink').length > 0) {
|
||||||
alert($('#localized_save_before_reorder_message').val());
|
$(ui.sender).sortable('cancel');
|
||||||
return false;
|
alert($('#localized_save_before_reorder_message').val());
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
var indexes = [];
|
|
||||||
ui.item.parent().children('.inline-related').each(function(i)
|
var indexes = [];
|
||||||
{
|
ui.item.parent().children('.inline-related').each(function(i)
|
||||||
var index_value = $(this).find(':hidden[name$="-id"]').val();
|
{
|
||||||
if (index_value !== "" && index_value !== undefined) {
|
var index_value = $(this).find(':hidden[name$="-id"]').val();
|
||||||
indexes.push(index_value);
|
if (index_value !== "" && index_value !== undefined) {
|
||||||
}
|
indexes.push(index_value);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
$.ajax({
|
|
||||||
url: ui.item.parent().find(':hidden[name="admin_sorting_url"]').val(),
|
$.ajax({
|
||||||
type: 'POST',
|
url: ui.item.parent().find(':hidden[name="admin_sorting_url"]').val(),
|
||||||
data: { indexes : indexes.join(',') },
|
type: 'POST',
|
||||||
success: function() {
|
data: { indexes : indexes.join(',') },
|
||||||
var fieldsets = ui.item.find('fieldset'),
|
success: function() {
|
||||||
highlightedSelector = fieldsets.filter('.collapsed').length === fieldsets.length ? 'h3' : '.form-row',
|
var fieldsets = ui.item.find('fieldset'),
|
||||||
icons = ui.item.parent().find('h3 > .fa');
|
highlightedSelector = fieldsets.filter('.collapsed').length === fieldsets.length ? 'h3' : '.form-row',
|
||||||
|
icons = ui.item.parent().find('h3 > .fa');
|
||||||
// set icons based on position
|
|
||||||
icons.removeClass('fa-sort-desc fa-sort-asc fa-sort');
|
// set icons based on position
|
||||||
icons.each(function(index, element) {
|
icons.removeClass('fa-sort-desc fa-sort-asc fa-sort');
|
||||||
var icon = $(element);
|
icons.each(function(index, element) {
|
||||||
if (index === 0) {
|
var icon = $(element);
|
||||||
icon.addClass('fa fa-sort-desc');
|
if (index === 0) {
|
||||||
}
|
icon.addClass('fa fa-sort-desc');
|
||||||
else if (index == icons.length - 1) {
|
}
|
||||||
icon.addClass('fa fa-sort-asc');
|
else if (index == icons.length - 1) {
|
||||||
}
|
icon.addClass('fa fa-sort-asc');
|
||||||
else {
|
}
|
||||||
icon.addClass('fa fa-sort');
|
else {
|
||||||
}
|
icon.addClass('fa fa-sort');
|
||||||
});
|
}
|
||||||
|
});
|
||||||
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 %}
|
||||||
|
}
|
||||||
})(django.jQuery);
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(django.jQuery);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -1,69 +1,77 @@
|
||||||
(function($){
|
<script>
|
||||||
|
(function($){
|
||||||
$(function() {
|
|
||||||
var sorting_urls = $(':hidden[name="admin_sorting_url"]');
|
$(function() {
|
||||||
if (sorting_urls.length)
|
var sorting_urls = $(':hidden[name="admin_sorting_url"]');
|
||||||
{
|
if (sorting_urls.length)
|
||||||
var sortable_inline_group = sorting_urls.closest('.inline-group');
|
{
|
||||||
var tabular_inline_rows = sortable_inline_group.find('.tabular table tbody tr');
|
var sortable_inline_group = sorting_urls.closest('.inline-group');
|
||||||
|
var tabular_inline_rows = sortable_inline_group.find('.tabular table tbody tr');
|
||||||
tabular_inline_rows.addClass('sortable');
|
|
||||||
|
tabular_inline_rows.addClass('sortable');
|
||||||
sortable_inline_group.find('.tabular.inline-related').sortable({
|
|
||||||
axis : 'y',
|
sortable_inline_group.find('.tabular.inline-related').sortable({
|
||||||
containment : 'parent',
|
axis : 'y',
|
||||||
create: function(event, ui) {
|
containment : 'parent',
|
||||||
$('td.delete :checkbox').unbind();
|
create: function(event, ui) {
|
||||||
},
|
$('td.delete :checkbox').unbind();
|
||||||
tolerance : 'pointer',
|
},
|
||||||
items : 'tr:not(.add-row)',
|
tolerance : 'pointer',
|
||||||
stop : function(event, ui) {
|
items : 'tr:not(.add-row)',
|
||||||
if ($('.inline-deletelink').length > 0) {
|
stop : function(event, ui) {
|
||||||
$(ui.sender).sortable('cancel');
|
if ($('.inline-deletelink').length > 0) {
|
||||||
alert($('#localized_save_before_reorder_message').val());
|
$(ui.sender).sortable('cancel');
|
||||||
return false;
|
alert($('#localized_save_before_reorder_message').val());
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
var indexes = [];
|
|
||||||
ui.item.parent().children('tr').each(function(i)
|
var indexes = [];
|
||||||
{
|
ui.item.parent().children('tr').each(function(i)
|
||||||
var index_value = $(this).find('.original :input:first').val();
|
{
|
||||||
|
var index_value = $(this).find('.original :input:first').val();
|
||||||
if (index_value !== '' && index_value !== undefined) {
|
if (index_value !== '' && index_value !== undefined) {
|
||||||
indexes.push(index_value);
|
indexes.push(index_value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: ui.item.parent().find(':hidden[name="admin_sorting_url"]').val(),
|
url: ui.item.parent().find(':hidden[name="admin_sorting_url"]').val(),
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: { indexes : indexes.join(',') },
|
data: { indexes : indexes.join(',') },
|
||||||
success: function() {
|
success: function() {
|
||||||
// set icons based on position
|
// set icons based on position
|
||||||
var icons = ui.item.parent().find('.fa');
|
var icons = ui.item.parent().find('.fa');
|
||||||
icons.removeClass('fa-sort-desc fa-sort-asc fa-sort');
|
icons.removeClass('fa-sort-desc fa-sort-asc fa-sort');
|
||||||
icons.each(function(index, element) {
|
icons.each(function(index, element) {
|
||||||
var icon = $(element);
|
var icon = $(element);
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
icon.addClass('fa fa-sort-desc');
|
icon.addClass('fa fa-sort-desc');
|
||||||
}
|
}
|
||||||
else if (index == icons.length - 1) {
|
else if (index == icons.length - 1) {
|
||||||
icon.addClass('fa fa-sort-asc');
|
icon.addClass('fa fa-sort-asc');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
icon.addClass('fa fa-sort');
|
icon.addClass('fa fa-sort');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// highlight sorted row, then re-stripe table
|
// highlight sorted row, then re-stripe table
|
||||||
ui.item.effect('highlight', {}, 1000);
|
ui.item.effect('highlight', {}, 1000);
|
||||||
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 %}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
})(django.jQuery);
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(django.jQuery);
|
||||||
|
|
||||||
|
</script>
|
||||||
Binary file not shown.
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 %}
|
||||||
|
|
@ -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 %}
|
||||||
Loading…
Reference in New Issue