Fixed #10615 - Added selection counter to admin change list. Thanks to Martin Mahner for the idea and initial patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12107 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
33afa13af5
commit
afa4c5ac60
|
@ -228,6 +228,12 @@
|
|||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.action_counter{
|
||||
font-size: 11px;
|
||||
margin: 0 0.5em;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#changelist table input {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,22 @@
|
|||
var Actions = {
|
||||
init: function() {
|
||||
var selectAll = document.getElementById('action-toggle');
|
||||
counterSpans = document.getElementsBySelector('span._acnt');
|
||||
counterContainer = document.getElementsBySelector('span.action_counter');
|
||||
actionCheckboxes = document.getElementsBySelector('tr input.action-select');
|
||||
selectAll = document.getElementById('action-toggle');
|
||||
for(var i = 0; i < counterContainer.length; i++) {
|
||||
counterContainer[i].style.display = 'inline';
|
||||
}
|
||||
if (selectAll) {
|
||||
selectAll.style.display = 'inline';
|
||||
addEvent(selectAll, 'click', function() {
|
||||
Actions.checker(selectAll.checked);
|
||||
Actions.counter();
|
||||
});
|
||||
}
|
||||
for(var i = 0; i < actionCheckboxes.length; i++) {
|
||||
addEvent(actionCheckboxes[i], 'click', function() {
|
||||
Actions.counter();
|
||||
});
|
||||
}
|
||||
var changelistTable = document.getElementsBySelector('#changelist table')[0];
|
||||
|
@ -16,6 +28,7 @@ var Actions = {
|
|||
if (target.className == 'action-select') {
|
||||
var tr = target.parentNode.parentNode;
|
||||
Actions.toggleRow(tr, target.checked);
|
||||
Actions.checked();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -27,13 +40,26 @@ var Actions = {
|
|||
tr.className = tr.className.replace(' selected', '');
|
||||
}
|
||||
},
|
||||
checked: function() {
|
||||
selectAll.checked = false;
|
||||
},
|
||||
checker: function(checked) {
|
||||
var actionCheckboxes = document.getElementsBySelector('tr input.action-select');
|
||||
for(var i = 0; i < actionCheckboxes.length; i++) {
|
||||
actionCheckboxes[i].checked = checked;
|
||||
Actions.toggleRow(actionCheckboxes[i].parentNode.parentNode, checked);
|
||||
}
|
||||
},
|
||||
counter: function() {
|
||||
counter = 0;
|
||||
for(var i = 0; i < actionCheckboxes.length; i++) {
|
||||
if(actionCheckboxes[i].checked){
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < counterSpans.length; i++) {
|
||||
counterSpans[i].innerHTML = counter;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addEvent(window, 'load', Actions.init);
|
||||
addEvent(window, 'load', Actions.init);
|
|
@ -210,6 +210,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
action_form = helpers.ActionForm
|
||||
actions_on_top = True
|
||||
actions_on_bottom = False
|
||||
actions_selection_counter = True
|
||||
|
||||
def __init__(self, model, admin_site):
|
||||
self.model = model
|
||||
|
@ -1024,7 +1025,13 @@ class ModelAdmin(BaseModelAdmin):
|
|||
else:
|
||||
action_form = None
|
||||
|
||||
if cl.result_count == 1:
|
||||
module_name = force_unicode(opts.verbose_name)
|
||||
else:
|
||||
module_name = force_unicode(opts.verbose_name_plural)
|
||||
|
||||
context = {
|
||||
'module_name': module_name,
|
||||
'title': cl.title,
|
||||
'is_popup': cl.is_popup,
|
||||
'cl': cl,
|
||||
|
@ -1035,6 +1042,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
'action_form': action_form,
|
||||
'actions_on_top': self.actions_on_top,
|
||||
'actions_on_bottom': self.actions_on_bottom,
|
||||
'actions_selection_counter': self.actions_selection_counter,
|
||||
}
|
||||
context.update(extra_context or {})
|
||||
context_instance = template.RequestContext(request, current_app=self.admin_site.name)
|
||||
|
|
|
@ -2,4 +2,9 @@
|
|||
<div class="actions">
|
||||
{% for field in action_form %}<label>{{ field.label }} {{ field }}</label>{% endfor %}
|
||||
<button type="submit" class="button" title="{% trans "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">{% trans "Go" %}</button>
|
||||
{% if actions_selection_counter %}
|
||||
<span class="action_counter">
|
||||
{% blocktrans with cl.result_count as total_count %}<span class="_acnt">0</span> of {{ total_count }} {{ module_name }} selected{% endblocktrans %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 38 KiB |
Binary file not shown.
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
@ -697,6 +697,12 @@ Controls where on the page the actions bar appears. By default, the admin
|
|||
changelist displays actions at the top of the page (``actions_on_top = True;
|
||||
actions_on_bottom = False``).
|
||||
|
||||
.. attribute:: ModelAdmin.actions_selection_counter
|
||||
|
||||
Controls whether a selection counter is display next to the action dropdown.
|
||||
By default, the admin changelist will display it
|
||||
(``actions_selection_counter = True``).
|
||||
|
||||
.. attribute:: ModelAdmin.change_list_template
|
||||
|
||||
Path to a custom template that will be used by the model objects "change list"
|
||||
|
|
|
@ -1209,6 +1209,13 @@ class AdminActionsTest(TestCase):
|
|||
self.assertContains(response, msg)
|
||||
self.failUnlessEqual(Subscriber.objects.count(), 2)
|
||||
|
||||
def test_selection_counter(self):
|
||||
"""
|
||||
Check if the selection counter is there.
|
||||
"""
|
||||
response = self.client.get('/test_admin/admin/admin_views/subscriber/')
|
||||
self.assertContains(response, '<span class="_acnt">0</span> of 2 subscribers selected')
|
||||
|
||||
|
||||
class TestCustomChangeList(TestCase):
|
||||
fixtures = ['admin-views-users.xml']
|
||||
|
|
Loading…
Reference in New Issue