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
This commit is contained in:
Luke Plant 2011-06-03 11:54:39 +00:00
parent cb996cce05
commit 74b1616290
3 changed files with 95 additions and 36 deletions

View File

@ -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 File

@ -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 File

@ -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 '')
}