Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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
@spookylukey spookylukey authored
View
22 django/contrib/admin/media/css/base.css
@@ -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 */
View
88 django/contrib/admin/templates/admin/change_list_results.html
@@ -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);
//-->
View
21 django/contrib/admin/templatetags/admin_list.py
@@ -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.