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; background-color: white;
border: 1px solid #ddd; border: 1px solid #ddd;
z-index: 2000; /* more than filters on right */ 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 */ /* ORDERABLE TABLES */

View File

@ -12,7 +12,7 @@
<tr> <tr>
{% for header in result_headers %} {% for header in result_headers %}
<th scope="col" {{ header.class_attrib }}> <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> <span class="text">{{ header.text|capfirst }}</span>
{% if header.sortable %} {% if header.sortable %}
{% if header.sort_pos > 0 %}<span class="sortpos"> {% if header.sort_pos > 0 %}<span class="sortpos">
@ -37,47 +37,77 @@
{# Sorting popup: #} {# Sorting popup: #}
<div style="display: none;" id="sorting-popup-div"> <div style="display: none;" id="sorting-popup-div">
<p>{% trans "Sorting by:" %}</p> <table>
<ol> <caption>
{% for header in result_headers|dictsort:"sort_pos" %} {% trans "Sorting by:" %}
{% if header.sort_pos > 0 %} </caption>
{% if header.ascending %} <tbody>
<li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (ascending){% endblocktrans %}</li> {% for header in result_headers|dictsort:"sort_pos" %}
{% else %} {% if header.sort_pos > 0 %}
<li>{% blocktrans with fieldname=header.text %}{{ fieldname }} (descending){% endblocktrans %}</li> <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 %}
{% endif %} {% endfor %}
{% endfor %} </tbody>
</ol> </table>
<p><a href="{{ reset_sorting_url }}">{% trans "Reset sorting" %}</a></p> <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> </div>
<script type="text/javascript"> <script type="text/javascript">
<!-- <!--
(function($) { (function($) {
$(document).ready(function() { $(document).ready(function() {
var popup = $('#sorting-popup-div'); var popup = $('#sorting-popup-div');
var img = $('#primary-sort-icon');
/* These next lines seems necessary to prime the popup: */ /* These next lines seems necessary to prime the popup: */
popup.offset({left:-1000, top:0}); popup.offset({left:-1000, top:0});
popup.show(); popup.show();
var popupWidth = popup.width(); var popupWidth = popup.width();
popup.hide(); popup.hide();
$('#primary-sort-icon').toggle(function(ev) { var visible = false;
ev.preventDefault();
var img = $(this); var escHandler = function(ev) {
var pos = img.offset(); if (ev.which == 27) {
pos.top += img.height(); hidePopup();
if (pos.left + popupWidth > ev.preventDefault();
$(window).width()) { }
pos.left -= popupWidth; };
}
popup.show(); var showPopup = function() {
popup.offset(pos); var pos = img.offset();
}, pos.top += img.height();
function(ev) { if (pos.left + popupWidth >
ev.preventDefault(); $(window).width()) {
popup.hide(); 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); })(django.jQuery);
//--> //-->

View File

@ -122,28 +122,37 @@ def result_headers(cl):
new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type] new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]
# build new ordering param # 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) make_qs_param = lambda t, n: ('-' if t == 'desc' else '') + str(n)
for j, ot in ordering_field_columns.items(): for j, ot in ordering_field_columns.items():
if j == i: # Same column 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 # We want clicking on this header to bring the ordering to the
# front # 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: 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: 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 { yield {
"text": text, "text": text,
"sortable": True, "sortable": True,
"ascending": order_type == "asc", "ascending": order_type == "asc",
"sort_pos": sort_pos, "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 '') "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '')
} }