Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Improved UI for advanced sorting controls.

Now allows individual fields to be removed/toggled.

Refs #11868

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16320 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 74b16162902864c59c63fcb7936f604a738aecee 1 parent cb996cc
Luke Plant spookylukey authored
22 django/contrib/admin/media/css/base.css
View
@@ -351,7 +351,27 @@ table thead th.sorted a span.clear {
background-color: white;
border: 1px solid #ddd;
z-index: 2000; /* more than filters on right */
- padding-right: 10px;
+}
+
+#sorting-popup-div table {
+ border-right: 0px;
+ border-left: 0px;
+}
+
+#sorting-popup-div .reset {
+ text-align: center;
+}
+
+#sorting-popup-div .cancel {
+ font-size: 10px;
+ background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x;
+ border-top: 1px solid #ddd;
+ text-align: center;
+}
+
+#sorting-popup-div .cancel a {
+ width: 100%;
+ display: block;
}
/* ORDERABLE TABLES */
88 django/contrib/admin/templates/admin/change_list_results.html
View
@@ -12,7 +12,7 @@
<tr>
{% for header in result_headers %}
<th scope="col" {{ header.class_attrib }}>
- {% if header.sortable %}<a href="{{ header.url }}">{% endif %}
+ {% if header.sortable %}<a href="{{ header.url_primary }}">{% endif %}
<span class="text">{{ header.text|capfirst }}</span>
{% if header.sortable %}
{% if header.sort_pos > 0 %}<span class="sortpos">
@@ -37,47 +37,77 @@
{# Sorting popup: #}
<div style="display: none;" id="sorting-popup-div">
-<p>{% trans "Sorting by:" %}</p>
-<ol>
-{% for header in result_headers|dictsort:"sort_pos" %}
- {% if header.sort_pos > 0 %}
- {% if header.ascending %}
- <li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (ascending){% endblocktrans %}</li>
- {% else %}
- <li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (descending){% endblocktrans %}</li>
+<table>
+ <caption>
+ {% trans "Sorting by:" %}
+ </caption>
+ <tbody>
+ {% for header in result_headers|dictsort:"sort_pos" %}
+ {% if header.sort_pos > 0 %}
+ <tr>
+ <td>{{ header.sort_pos }}</td>
+ <td>{{ header.text|capfirst }}</td>
+ <td>{% if header.ascending %}{% trans "ascending" %}{% else %}{% trans "descending" %}{% endif %}</td>
+ <td><a href="{{ header.url_toggle }}">{% trans "toggle" %}</a></td>
+ <td><a href="{{ header.url_remove }}">{% trans "remove" %}</a></td>
+ </tr>
{% endif %}
- {% endif %}
-{% endfor %}
-</ol>
-<p><a href="{{ reset_sorting_url }}">{% trans "Reset sorting" %}</a></p>
+ {% endfor %}
+ </tbody>
+</table>
+<div class="reset"><a href="{{ reset_sorting_url }}">{% trans "Reset sorting" %}</a></div>
+<div class="cancel"><a href="javascript:void" id="sorting-popup-dismiss">{% trans "Cancel" %}</a></div>
</div>
<script type="text/javascript">
<!--
(function($) {
$(document).ready(function() {
var popup = $('#sorting-popup-div');
+ var img = $('#primary-sort-icon');
/* These next lines seems necessary to prime the popup: */
popup.offset({left:-1000, top:0});
popup.show();
var popupWidth = popup.width();
popup.hide();
- $('#primary-sort-icon').toggle(function(ev) {
- ev.preventDefault();
- var img = $(this);
- var pos = img.offset();
- pos.top += img.height();
- if (pos.left + popupWidth >
- $(window).width()) {
- pos.left -= popupWidth;
- }
- popup.show();
- popup.offset(pos);
- },
- function(ev) {
- ev.preventDefault();
- popup.hide();
- });
+ var visible = false;
+
+ var escHandler = function(ev) {
+ if (ev.which == 27) {
+ hidePopup();
+ ev.preventDefault();
+ }
+ };
+
+ var showPopup = function() {
+ var pos = img.offset();
+ pos.top += img.height();
+ if (pos.left + popupWidth >
+ $(window).width()) {
+ pos.left -= popupWidth;
+ }
+ popup.show();
+ popup.offset(pos);
+ visible = true;
+ $(document).bind('keyup', escHandler);
+ };
+
+ var hidePopup = function() {
+ popup.hide();
+ visible = false;
+ $(document).unbind('keyup', escHandler);
+ };
+
+ $('#primary-sort-icon').click(function(ev) {
+ ev.preventDefault();
+ if (visible) {
+ hidePopup();
+ } else {
+ showPopup();
+ }
+ });
+
+ $('#sorting-popup-dismiss').click(hidePopup);
});
})(django.jQuery);
//-->
21 django/contrib/admin/templatetags/admin_list.py
View
@@ -122,28 +122,37 @@ def result_headers(cl):
new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]
# build new ordering param
- o_list = []
+ o_list_primary = [] # URL for making this field the primary sort
+ o_list_remove = [] # URL for removing this field from sort
+ o_list_toggle = [] # URL for toggling order type for this field
make_qs_param = lambda t, n: ('-' if t == 'desc' else '') + str(n)
for j, ot in ordering_field_columns.items():
if j == i: # Same column
+ param = make_qs_param(new_order_type, j)
# We want clicking on this header to bring the ordering to the
# front
- o_list.insert(0, make_qs_param(new_order_type, j))
+ o_list_primary.insert(0, param)
+ o_list_toggle.append(param)
+ # o_list_remove - omit
else:
- o_list.append(make_qs_param(ot, j))
+ param = make_qs_param(ot, j)
+ o_list_primary.append(param)
+ o_list_toggle.append(param)
+ o_list_remove.append(param)
if i not in ordering_field_columns:
- o_list.insert(0, make_qs_param(new_order_type, i))
+ o_list_primary.insert(0, make_qs_param(new_order_type, i))
- o_list = '.'.join(o_list)
yield {
"text": text,
"sortable": True,
"ascending": order_type == "asc",
"sort_pos": sort_pos,
- "url": cl.get_query_string({ORDER_VAR: o_list}),
+ "url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),
+ "url_remove": cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}),
+ "url_toggle": cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}),
"class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '')
}
Please sign in to comment.
Something went wrong with that request. Please try again.