Code

Ticket #11868: 11868_enhancements.diff

File 11868_enhancements.diff, 7.5 KB (added by lukeplant, 3 years ago)

Possible enhancements for review

Line 
1diff -r a66e98d03a49 django/contrib/admin/media/css/base.css
2--- a/django/contrib/admin/media/css/base.css   Thu Jun 02 19:50:48 2011 +0000
3+++ b/django/contrib/admin/media/css/base.css   Fri Jun 03 00:51:34 2011 +0100
4@@ -351,7 +351,27 @@
5     background-color: white;
6     border: 1px solid #ddd;
7     z-index: 2000; /* more than filters on right */
8-    padding-right: 10px;
9+}
10+
11+#sorting-popup-div table {
12+    border-right: 0px;
13+    border-left: 0px;
14+}
15+
16+#sorting-popup-div .reset {
17+    text-align: center;
18+}
19+
20+#sorting-popup-div .cancel {
21+    font-size: 10px;
22+    background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x;
23+    border-top: 1px solid #ddd;
24+    text-align: center;
25+}
26+
27+#sorting-popup-div .cancel a {
28+    width: 100%;
29+    display: block;
30 }
31 
32 /* ORDERABLE TABLES */
33diff -r a66e98d03a49 django/contrib/admin/templates/admin/change_list_results.html
34--- a/django/contrib/admin/templates/admin/change_list_results.html     Thu Jun 02 19:50:48 2011 +0000
35+++ b/django/contrib/admin/templates/admin/change_list_results.html     Fri Jun 03 00:51:34 2011 +0100
36@@ -12,7 +12,7 @@
37 <tr>
38 {% for header in result_headers %}
39 <th scope="col" {{ header.class_attrib }}>
40-  {% if header.sortable %}<a href="{{ header.url }}">{% endif %}
41+  {% if header.sortable %}<a href="{{ header.url_primary }}">{% endif %}
42   <span class="text">{{ header.text|capfirst }}</span>
43   {% if header.sortable %}
44     {% if header.sort_pos > 0 %}<span class="sortpos">
45@@ -37,47 +37,77 @@
46 
47 {# Sorting popup: #}
48 <div style="display: none;" id="sorting-popup-div">
49-<p>{% trans "Sorting by:" %}</p>
50-<ol>
51-{% for header in result_headers|dictsort:"sort_pos" %}
52-  {% if header.sort_pos > 0 %}
53-    {% if header.ascending %}
54-      <li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (ascending){% endblocktrans %}</li>
55-    {% else %}
56-      <li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (descending){% endblocktrans %}</li>
57+<table>
58+  <caption>
59+   {% trans "Sorting by:" %}
60+  </caption>
61+  <tbody>
62+  {% for header in result_headers|dictsort:"sort_pos" %}
63+    {% if header.sort_pos > 0 %}
64+    <tr>
65+      <td>{{ header.sort_pos }}</td>
66+      <td>{{ header.text|capfirst }}</td>
67+      <td>{% if header.ascending %}{% trans "ascending" %}{% else %}{% trans "descending" %}{% endif %}</td>
68+      <td><a href="{{ header.url_toggle }}">{% trans "toggle" %}</a></td>
69+      <td><a href="{{ header.url_remove }}">{% trans "remove" %}</a></td>
70+    </tr>
71     {% endif %}
72-  {% endif %}
73-{% endfor %}
74-</ol>
75-<p><a href="{{ reset_sorting_url }}">{% trans "Reset sorting" %}</a></p>
76+  {% endfor %}
77+  </tbody>
78+</table>
79+<div class="reset"><a href="{{ reset_sorting_url }}">{% trans "Reset sorting" %}</a></div>
80+<div class="cancel"><a href="javascript:void" id="sorting-popup-dismiss">{% trans "Cancel" %}</a></div>
81 </div>
82 <script type="text/javascript">
83 <!--
84 (function($) {
85     $(document).ready(function() {
86         var popup = $('#sorting-popup-div');
87+        var img = $('#primary-sort-icon');
88         /* These next lines seems necessary to prime the popup: */
89         popup.offset({left:-1000, top:0});
90         popup.show();
91         var popupWidth = popup.width();
92         popup.hide();
93 
94-        $('#primary-sort-icon').toggle(function(ev) {
95-                                          ev.preventDefault();
96-                                          var img = $(this);
97-                                          var pos = img.offset();
98-                                          pos.top += img.height();
99-                                          if (pos.left + popupWidth >
100-                                              $(window).width()) {
101-                                              pos.left -= popupWidth;
102-                                          }
103-                                          popup.show();
104-                                          popup.offset(pos);
105-                                      },
106-                                      function(ev) {
107-                                          ev.preventDefault();
108-                                          popup.hide();
109-                                      });
110+        var visible = false;
111+
112+        var escHandler = function(ev) {
113+            if (ev.which == 27) {
114+                hidePopup();
115+                ev.preventDefault();
116+            }
117+        };
118+
119+        var showPopup = function() {
120+            var pos = img.offset();
121+            pos.top += img.height();
122+            if (pos.left + popupWidth >
123+                $(window).width()) {
124+                pos.left -= popupWidth;
125+            }
126+            popup.show();
127+            popup.offset(pos);
128+            visible = true;
129+            $(document).bind('keyup', escHandler);
130+        };
131+
132+        var hidePopup = function() {
133+            popup.hide();
134+            visible = false;
135+            $(document).unbind('keyup', escHandler);
136+        };
137+
138+        $('#primary-sort-icon').click(function(ev) {
139+            ev.preventDefault();
140+            if (visible) {
141+                hidePopup();
142+            } else {
143+                showPopup();
144+            }
145+        });
146+
147+        $('#sorting-popup-dismiss').click(hidePopup);
148     });
149 })(django.jQuery);
150 //-->
151diff -r a66e98d03a49 django/contrib/admin/templatetags/admin_list.py
152--- a/django/contrib/admin/templatetags/admin_list.py   Thu Jun 02 19:50:48 2011 +0000
153+++ b/django/contrib/admin/templatetags/admin_list.py   Fri Jun 03 00:51:34 2011 +0100
154@@ -138,7 +138,9 @@
155             new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]
156 
157         # build new ordering param
158-        o_list = []
159+        o_list_primary = [] # URL for making this field the primary sort
160+        o_list_remove  = [] # URL for removing this field from sort
161+        o_list_toggle  = [] # URL for toggling order type for this field
162         make_qs_param = lambda t, n: ('-' if t == 'desc' else '') + str(n)
163 
164         for f, ot in ordering_fields.items():
165@@ -148,24 +150,30 @@
166                 continue
167 
168             if f == ordering_field_name:
169+                param = make_qs_param(new_order_type, colnum)
170                 # We want clicking on this header to bring the ordering to the
171-                # front
172-                o_list.insert(0, make_qs_param(new_order_type, colnum))
173+                # front, so use insert for o_list_primary
174+                o_list_primary.insert(0, param)
175+                o_list_toggle.append(param)
176+                # o_list_remove - omit
177             else:
178-                o_list.append(make_qs_param(ot, colnum))
179+                param = make_qs_param(ot, colnum)
180+                o_list_primary.append(param)
181+                o_list_toggle.append(param)
182+                o_list_remove.append(param)
183 
184         if ordering_field_name not in ordering_fields:
185             colnum = list_display_info[ordering_field_name]['index']
186-            o_list.insert(0, make_qs_param(new_order_type, colnum))
187-
188-        o_list = '.'.join(o_list)
189+            o_list_primary.insert(0, make_qs_param(new_order_type, colnum))
190 
191         yield {
192             "text": info['text'],
193             "sortable": True,
194             "ascending": order_type == "asc",
195             "sort_pos": sort_pos,
196-            "url": cl.get_query_string({ORDER_VAR: o_list}),
197+            "url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),
198+            "url_remove": cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}),
199+            "url_toggle": cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}),
200             "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '')
201         }
202