Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #10615 - Added selection counter to admin change list. Thanks t…

…o Martin Mahner for the idea and initial patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12107 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit afa4c5ac6062581fdb809e0615c69350c25bd917 1 parent 33afa13
Jannis Leidel authored January 05, 2010
6  django/contrib/admin/media/css/changelists.css
@@ -228,6 +228,12 @@
228 228
     border-right: 1px solid #ddd;
229 229
 }
230 230
 
  231
+.action_counter{
  232
+    font-size: 11px;
  233
+    margin: 0 0.5em;
  234
+    display: none;
  235
+}
  236
+
231 237
 #changelist table input {
232 238
     margin: 0;
233 239
 }
32  django/contrib/admin/media/js/actions.js
... ...
@@ -1,10 +1,22 @@
1 1
 var Actions = {
2 2
     init: function() {
3  
-        var selectAll = document.getElementById('action-toggle');
  3
+        counterSpans = document.getElementsBySelector('span._acnt');
  4
+        counterContainer = document.getElementsBySelector('span.action_counter');
  5
+        actionCheckboxes = document.getElementsBySelector('tr input.action-select');
  6
+        selectAll = document.getElementById('action-toggle');
  7
+        for(var i = 0; i < counterContainer.length; i++) {
  8
+            counterContainer[i].style.display = 'inline';
  9
+        }
4 10
         if (selectAll) {
5 11
             selectAll.style.display = 'inline';
6 12
             addEvent(selectAll, 'click', function() {
7 13
                 Actions.checker(selectAll.checked);
  14
+                Actions.counter();
  15
+            });
  16
+        }
  17
+        for(var i = 0; i < actionCheckboxes.length; i++) {
  18
+            addEvent(actionCheckboxes[i], 'click', function() {
  19
+                Actions.counter();
8 20
             });
9 21
         }
10 22
         var changelistTable = document.getElementsBySelector('#changelist table')[0];
@@ -16,6 +28,7 @@ var Actions = {
16 28
                 if (target.className == 'action-select') {
17 29
                     var tr = target.parentNode.parentNode;
18 30
                     Actions.toggleRow(tr, target.checked);
  31
+                    Actions.checked();
19 32
                 }
20 33
             });
21 34
         }
@@ -27,13 +40,26 @@ var Actions = {
27 40
             tr.className = tr.className.replace(' selected', '');
28 41
         }  
29 42
     },
  43
+    checked: function() {
  44
+        selectAll.checked = false;
  45
+    },
30 46
     checker: function(checked) {
31  
-        var actionCheckboxes = document.getElementsBySelector('tr input.action-select');
32 47
         for(var i = 0; i < actionCheckboxes.length; i++) {
33 48
             actionCheckboxes[i].checked = checked;
34 49
             Actions.toggleRow(actionCheckboxes[i].parentNode.parentNode, checked);
35 50
         }
  51
+    },
  52
+    counter: function() {
  53
+        counter = 0;
  54
+        for(var i = 0; i < actionCheckboxes.length; i++) {
  55
+            if(actionCheckboxes[i].checked){
  56
+                counter++;
  57
+            }
  58
+        }
  59
+        for(var i = 0; i < counterSpans.length; i++) {
  60
+            counterSpans[i].innerHTML = counter;
  61
+        }
36 62
     }
37 63
 };
38 64
 
39  
-addEvent(window, 'load', Actions.init);
  65
+addEvent(window, 'load', Actions.init);
8  django/contrib/admin/options.py
@@ -210,6 +210,7 @@ class ModelAdmin(BaseModelAdmin):
210 210
     action_form = helpers.ActionForm
211 211
     actions_on_top = True
212 212
     actions_on_bottom = False
  213
+    actions_selection_counter = True
213 214
 
214 215
     def __init__(self, model, admin_site):
215 216
         self.model = model
@@ -1024,7 +1025,13 @@ def changelist_view(self, request, extra_context=None):
1024 1025
         else:
1025 1026
             action_form = None
1026 1027
 
  1028
+        if cl.result_count == 1:
  1029
+            module_name = force_unicode(opts.verbose_name)
  1030
+        else:
  1031
+            module_name = force_unicode(opts.verbose_name_plural)
  1032
+
1027 1033
         context = {
  1034
+            'module_name': module_name,
1028 1035
             'title': cl.title,
1029 1036
             'is_popup': cl.is_popup,
1030 1037
             'cl': cl,
@@ -1035,6 +1042,7 @@ def changelist_view(self, request, extra_context=None):
1035 1042
             'action_form': action_form,
1036 1043
             'actions_on_top': self.actions_on_top,
1037 1044
             'actions_on_bottom': self.actions_on_bottom,
  1045
+            'actions_selection_counter': self.actions_selection_counter,
1038 1046
         }
1039 1047
         context.update(extra_context or {})
1040 1048
         context_instance = template.RequestContext(request, current_app=self.admin_site.name)
5  django/contrib/admin/templates/admin/actions.html
@@ -2,4 +2,9 @@
2 2
 <div class="actions">
3 3
     {% for field in action_form %}<label>{{ field.label }} {{ field }}</label>{% endfor %}
4 4
     <button type="submit" class="button" title="{% trans "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">{% trans "Go" %}</button>
  5
+    {% if actions_selection_counter %}
  6
+    <span class="action_counter">
  7
+      {% blocktrans with cl.result_count as total_count %}<span class="_acnt">0</span> of {{ total_count }} {{ module_name }} selected{% endblocktrans %}
  8
+    </span>
  9
+    {% endif %}
5 10
 </div>
BIN  docs/ref/contrib/admin/_images/article_actions.png
BIN  docs/ref/contrib/admin/_images/article_actions_message.png
BIN  docs/ref/contrib/admin/_images/user_actions.png
6  docs/ref/contrib/admin/index.txt
@@ -697,6 +697,12 @@ Controls where on the page the actions bar appears. By default, the admin
697 697
 changelist displays actions at the top of the page (``actions_on_top = True;
698 698
 actions_on_bottom = False``).
699 699
 
  700
+.. attribute:: ModelAdmin.actions_selection_counter
  701
+
  702
+Controls whether a selection counter is display next to the action dropdown.
  703
+By default, the admin changelist will display it
  704
+(``actions_selection_counter = True``).
  705
+
700 706
 .. attribute:: ModelAdmin.change_list_template
701 707
 
702 708
 Path to a custom template that will be used by the model objects "change list"
7  tests/regressiontests/admin_views/tests.py
@@ -1209,6 +1209,13 @@ def test_user_message_on_no_action(self):
1209 1209
         self.assertContains(response, msg)
1210 1210
         self.failUnlessEqual(Subscriber.objects.count(), 2)
1211 1211
 
  1212
+    def test_selection_counter(self):
  1213
+        """
  1214
+        Check if the selection counter is there.
  1215
+        """
  1216
+        response = self.client.get('/test_admin/admin/admin_views/subscriber/')
  1217
+        self.assertContains(response, '<span class="_acnt">0</span> of 2 subscribers selected')
  1218
+
1212 1219
 
1213 1220
 class TestCustomChangeList(TestCase):
1214 1221
     fixtures = ['admin-views-users.xml']

0 notes on commit afa4c5a

Please sign in to comment.
Something went wrong with that request. Please try again.