diff -r a66e98d03a49 django/contrib/admin/media/css/base.css
a
|
b
|
|
351 | 351 | background-color: white; |
352 | 352 | border: 1px solid #ddd; |
353 | 353 | z-index: 2000; /* more than filters on right */ |
354 | | padding-right: 10px; |
| 354 | } |
| 355 | |
| 356 | #sorting-popup-div table { |
| 357 | border-right: 0px; |
| 358 | border-left: 0px; |
| 359 | } |
| 360 | |
| 361 | #sorting-popup-div .reset { |
| 362 | text-align: center; |
| 363 | } |
| 364 | |
| 365 | #sorting-popup-div .cancel { |
| 366 | font-size: 10px; |
| 367 | background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; |
| 368 | border-top: 1px solid #ddd; |
| 369 | text-align: center; |
| 370 | } |
| 371 | |
| 372 | #sorting-popup-div .cancel a { |
| 373 | width: 100%; |
| 374 | display: block; |
355 | 375 | } |
356 | 376 | |
357 | 377 | /* ORDERABLE TABLES */ |
diff -r a66e98d03a49 django/contrib/admin/templates/admin/change_list_results.html
a
|
b
|
|
12 | 12 | <tr> |
13 | 13 | {% for header in result_headers %} |
14 | 14 | <th scope="col" {{ header.class_attrib }}> |
15 | | {% if header.sortable %}<a href="{{ header.url }}">{% endif %} |
| 15 | {% if header.sortable %}<a href="{{ header.url_primary }}">{% endif %} |
16 | 16 | <span class="text">{{ header.text|capfirst }}</span> |
17 | 17 | {% if header.sortable %} |
18 | 18 | {% if header.sort_pos > 0 %}<span class="sortpos"> |
… |
… |
|
37 | 37 | |
38 | 38 | {# Sorting popup: #} |
39 | 39 | <div style="display: none;" id="sorting-popup-div"> |
40 | | <p>{% trans "Sorting by:" %}</p> |
41 | | <ol> |
42 | | {% for header in result_headers|dictsort:"sort_pos" %} |
43 | | {% if header.sort_pos > 0 %} |
44 | | {% if header.ascending %} |
45 | | <li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (ascending){% endblocktrans %}</li> |
46 | | {% else %} |
47 | | <li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (descending){% endblocktrans %}</li> |
| 40 | <table> |
| 41 | <caption> |
| 42 | {% trans "Sorting by:" %} |
| 43 | </caption> |
| 44 | <tbody> |
| 45 | {% for header in result_headers|dictsort:"sort_pos" %} |
| 46 | {% if header.sort_pos > 0 %} |
| 47 | <tr> |
| 48 | <td>{{ header.sort_pos }}</td> |
| 49 | <td>{{ header.text|capfirst }}</td> |
| 50 | <td>{% if header.ascending %}{% trans "ascending" %}{% else %}{% trans "descending" %}{% endif %}</td> |
| 51 | <td><a href="{{ header.url_toggle }}">{% trans "toggle" %}</a></td> |
| 52 | <td><a href="{{ header.url_remove }}">{% trans "remove" %}</a></td> |
| 53 | </tr> |
48 | 54 | {% endif %} |
49 | | {% endif %} |
50 | | {% endfor %} |
51 | | </ol> |
52 | | <p><a href="{{ reset_sorting_url }}">{% trans "Reset sorting" %}</a></p> |
| 55 | {% endfor %} |
| 56 | </tbody> |
| 57 | </table> |
| 58 | <div class="reset"><a href="{{ reset_sorting_url }}">{% trans "Reset sorting" %}</a></div> |
| 59 | <div class="cancel"><a href="javascript:void" id="sorting-popup-dismiss">{% trans "Cancel" %}</a></div> |
53 | 60 | </div> |
54 | 61 | <script type="text/javascript"> |
55 | 62 | <!-- |
56 | 63 | (function($) { |
57 | 64 | $(document).ready(function() { |
58 | 65 | var popup = $('#sorting-popup-div'); |
| 66 | var img = $('#primary-sort-icon'); |
59 | 67 | /* These next lines seems necessary to prime the popup: */ |
60 | 68 | popup.offset({left:-1000, top:0}); |
61 | 69 | popup.show(); |
62 | 70 | var popupWidth = popup.width(); |
63 | 71 | popup.hide(); |
64 | 72 | |
65 | | $('#primary-sort-icon').toggle(function(ev) { |
66 | | ev.preventDefault(); |
67 | | var img = $(this); |
68 | | var pos = img.offset(); |
69 | | pos.top += img.height(); |
70 | | if (pos.left + popupWidth > |
71 | | $(window).width()) { |
72 | | pos.left -= popupWidth; |
73 | | } |
74 | | popup.show(); |
75 | | popup.offset(pos); |
76 | | }, |
77 | | function(ev) { |
78 | | ev.preventDefault(); |
79 | | popup.hide(); |
80 | | }); |
| 73 | var visible = false; |
| 74 | |
| 75 | var escHandler = function(ev) { |
| 76 | if (ev.which == 27) { |
| 77 | hidePopup(); |
| 78 | ev.preventDefault(); |
| 79 | } |
| 80 | }; |
| 81 | |
| 82 | var showPopup = function() { |
| 83 | var pos = img.offset(); |
| 84 | pos.top += img.height(); |
| 85 | if (pos.left + popupWidth > |
| 86 | $(window).width()) { |
| 87 | pos.left -= popupWidth; |
| 88 | } |
| 89 | popup.show(); |
| 90 | popup.offset(pos); |
| 91 | visible = true; |
| 92 | $(document).bind('keyup', escHandler); |
| 93 | }; |
| 94 | |
| 95 | var hidePopup = function() { |
| 96 | popup.hide(); |
| 97 | visible = false; |
| 98 | $(document).unbind('keyup', escHandler); |
| 99 | }; |
| 100 | |
| 101 | $('#primary-sort-icon').click(function(ev) { |
| 102 | ev.preventDefault(); |
| 103 | if (visible) { |
| 104 | hidePopup(); |
| 105 | } else { |
| 106 | showPopup(); |
| 107 | } |
| 108 | }); |
| 109 | |
| 110 | $('#sorting-popup-dismiss').click(hidePopup); |
81 | 111 | }); |
82 | 112 | })(django.jQuery); |
83 | 113 | //--> |
diff -r a66e98d03a49 django/contrib/admin/templatetags/admin_list.py
a
|
b
|
|
138 | 138 | new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type] |
139 | 139 | |
140 | 140 | # build new ordering param |
141 | | o_list = [] |
| 141 | o_list_primary = [] # URL for making this field the primary sort |
| 142 | o_list_remove = [] # URL for removing this field from sort |
| 143 | o_list_toggle = [] # URL for toggling order type for this field |
142 | 144 | make_qs_param = lambda t, n: ('-' if t == 'desc' else '') + str(n) |
143 | 145 | |
144 | 146 | for f, ot in ordering_fields.items(): |
… |
… |
|
148 | 150 | continue |
149 | 151 | |
150 | 152 | if f == ordering_field_name: |
| 153 | param = make_qs_param(new_order_type, colnum) |
151 | 154 | # We want clicking on this header to bring the ordering to the |
152 | | # front |
153 | | o_list.insert(0, make_qs_param(new_order_type, colnum)) |
| 155 | # front, so use insert for o_list_primary |
| 156 | o_list_primary.insert(0, param) |
| 157 | o_list_toggle.append(param) |
| 158 | # o_list_remove - omit |
154 | 159 | else: |
155 | | o_list.append(make_qs_param(ot, colnum)) |
| 160 | param = make_qs_param(ot, colnum) |
| 161 | o_list_primary.append(param) |
| 162 | o_list_toggle.append(param) |
| 163 | o_list_remove.append(param) |
156 | 164 | |
157 | 165 | if ordering_field_name not in ordering_fields: |
158 | 166 | colnum = list_display_info[ordering_field_name]['index'] |
159 | | o_list.insert(0, make_qs_param(new_order_type, colnum)) |
160 | | |
161 | | o_list = '.'.join(o_list) |
| 167 | o_list_primary.insert(0, make_qs_param(new_order_type, colnum)) |
162 | 168 | |
163 | 169 | yield { |
164 | 170 | "text": info['text'], |
165 | 171 | "sortable": True, |
166 | 172 | "ascending": order_type == "asc", |
167 | 173 | "sort_pos": sort_pos, |
168 | | "url": cl.get_query_string({ORDER_VAR: o_list}), |
| 174 | "url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}), |
| 175 | "url_remove": cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}), |
| 176 | "url_toggle": cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}), |
169 | 177 | "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '') |
170 | 178 | } |
171 | 179 | |