From 71f017b2a6677538f8c3578e33859d4586b5bea1 Mon Sep 17 00:00:00 2001 From: Julien Phalip Date: Wed, 31 Aug 2011 08:07:07 +0000 Subject: Fixed #16059 -- Improved the usability of the admin's vertical and horizontal "filter" widgets, in particular by providing a better visual representation of the buttons' enabled and disabled states, and by providing more elaborate, yet less cluttered, help texts. Note that this commit is an exception to the current tacit rule that javascript code changes should be avoided until a proper javascript testing framework for Django core is in place. This exception is commanded by the fact that it is to fix a recognized usability issue and that the patch has been (manually) extensively tested in IE6+, Chrome, Safari, Firefox and Opera. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16714 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/static/admin/css/widgets.css | 72 +++++++++++++++++---- .../admin/static/admin/img/selector-add.gif | Bin 606 -> 0 bytes .../admin/static/admin/img/selector-addall.gif | Bin 358 -> 0 bytes .../admin/static/admin/img/selector-icons.gif | Bin 0 -> 2771 bytes .../admin/static/admin/img/selector-remove.gif | Bin 398 -> 0 bytes .../admin/static/admin/img/selector-removeall.gif | Bin 355 -> 0 bytes .../static/admin/img/selector_stacked-add.gif | Bin 612 -> 0 bytes .../static/admin/img/selector_stacked-remove.gif | Bin 401 -> 0 bytes .../contrib/admin/static/admin/js/SelectFilter2.js | 65 +++++++++++++------ docs/releases/1.4.txt | 12 ++++ 10 files changed, 115 insertions(+), 34 deletions(-) delete mode 100644 django/contrib/admin/static/admin/img/selector-add.gif delete mode 100644 django/contrib/admin/static/admin/img/selector-addall.gif create mode 100644 django/contrib/admin/static/admin/img/selector-icons.gif delete mode 100644 django/contrib/admin/static/admin/img/selector-remove.gif delete mode 100644 django/contrib/admin/static/admin/img/selector-removeall.gif delete mode 100644 django/contrib/admin/static/admin/img/selector_stacked-add.gif delete mode 100644 django/contrib/admin/static/admin/img/selector_stacked-remove.gif diff --git a/django/contrib/admin/static/admin/css/widgets.css b/django/contrib/admin/static/admin/css/widgets.css index 4f4ea0a8f5..14e82c5a07 100644 --- a/django/contrib/admin/static/admin/css/widgets.css +++ b/django/contrib/admin/static/admin/css/widgets.css @@ -17,6 +17,10 @@ margin-bottom: 5px; } +.selector-chosen select { + border-top: none; +} + .selector-available h2, .selector-chosen h2 { border: 1px solid #ccc; } @@ -37,8 +41,9 @@ text-align: left; } -.selector .selector-chosen .selector-filter { - padding: 4px 5px; +.selector .selector-filter label { + width: 16px; + padding: 2px; } .selector .selector-available input { @@ -50,7 +55,7 @@ width: 22px; height: 50px; background: url(../img/chooser-bg.gif) top center no-repeat; - margin: 8em 3px 0 3px; + margin: 10em 5px 0 5px; padding: 0; } @@ -61,7 +66,7 @@ } .selector select { - margin-bottom: 5px; + margin-bottom: 10px; margin-top: 0; } @@ -74,38 +79,66 @@ } .selector-add { - background: url(../img/selector-add.gif) top center no-repeat; + background: url(../img/selector-icons.gif) 0 -161px no-repeat; + cursor: default; margin-bottom: 2px; } +.active.selector-add { + background: url(../img/selector-icons.gif) 0 -187px no-repeat; + cursor: pointer; +} + .selector-remove { - background: url(../img/selector-remove.gif) top center no-repeat; + background: url(../img/selector-icons.gif) 0 -109px no-repeat; + cursor: default; +} + +.active.selector-remove { + background: url(../img/selector-icons.gif) 0 -135px no-repeat; + cursor: pointer; } a.selector-chooseall, a.selector-clearall { - display: block; - width: 6em; + display: inline-block; text-align: left; margin-left: auto; margin-right: auto; font-weight: bold; color: #666; +} + +a.selector-chooseall { + padding: 3px 18px 3px 0; +} + +a.selector-clearall { padding: 3px 0 3px 18px; } -a.selector-chooseall:hover, a.selector-clearall:hover { +a.active.selector-chooseall:hover, a.active.selector-clearall:hover { color: #036; } a.selector-chooseall { - width: 7em; - background: url(../img/selector-addall.gif) left center no-repeat; + background: url(../img/selector-icons.gif) right -263px no-repeat; + cursor: default; +} + +a.active.selector-chooseall { + background: url(../img/selector-icons.gif) right -289px no-repeat; + cursor: pointer; } a.selector-clearall { - background: url(../img/selector-removeall.gif) left center no-repeat; + background: url(../img/selector-icons.gif) left -211px no-repeat; + cursor: default; } +a.active.selector-clearall { + background: url(../img/selector-icons.gif) left -237px no-repeat; + cursor: pointer; +} /* STACKED SELECTORS */ @@ -148,13 +181,24 @@ a.selector-clearall { } .stacked .selector-add { - background-image: url(../img/selector_stacked-add.gif); + background: url(../img/selector-icons.gif) 0 -57px no-repeat; + cursor: default; +} + +.stacked .active.selector-add { + background: url(../img/selector-icons.gif) 0 -83px no-repeat; + cursor: pointer; } .stacked .selector-remove { - background-image: url(../img/selector_stacked-remove.gif); + background: url(../img/selector-icons.gif) 0 -5px no-repeat; + cursor: default; } +.stacked .active.selector-remove { + background: url(../img/selector-icons.gif) 0 -31px no-repeat; + cursor: pointer; +} /* DATE AND TIME */ diff --git a/django/contrib/admin/static/admin/img/selector-add.gif b/django/contrib/admin/static/admin/img/selector-add.gif deleted file mode 100644 index 50132d1c43..0000000000 Binary files a/django/contrib/admin/static/admin/img/selector-add.gif and /dev/null differ diff --git a/django/contrib/admin/static/admin/img/selector-addall.gif b/django/contrib/admin/static/admin/img/selector-addall.gif deleted file mode 100644 index d6e7c639bb..0000000000 Binary files a/django/contrib/admin/static/admin/img/selector-addall.gif and /dev/null differ diff --git a/django/contrib/admin/static/admin/img/selector-icons.gif b/django/contrib/admin/static/admin/img/selector-icons.gif new file mode 100644 index 0000000000..8809c4fb9a Binary files /dev/null and b/django/contrib/admin/static/admin/img/selector-icons.gif differ diff --git a/django/contrib/admin/static/admin/img/selector-remove.gif b/django/contrib/admin/static/admin/img/selector-remove.gif deleted file mode 100644 index 2b9b0a2ac3..0000000000 Binary files a/django/contrib/admin/static/admin/img/selector-remove.gif and /dev/null differ diff --git a/django/contrib/admin/static/admin/img/selector-removeall.gif b/django/contrib/admin/static/admin/img/selector-removeall.gif deleted file mode 100644 index 5a4421926d..0000000000 Binary files a/django/contrib/admin/static/admin/img/selector-removeall.gif and /dev/null differ diff --git a/django/contrib/admin/static/admin/img/selector_stacked-add.gif b/django/contrib/admin/static/admin/img/selector_stacked-add.gif deleted file mode 100644 index 7426169652..0000000000 Binary files a/django/contrib/admin/static/admin/img/selector_stacked-add.gif and /dev/null differ diff --git a/django/contrib/admin/static/admin/img/selector_stacked-remove.gif b/django/contrib/admin/static/admin/img/selector_stacked-remove.gif deleted file mode 100644 index 60412cee19..0000000000 Binary files a/django/contrib/admin/static/admin/img/selector_stacked-remove.gif and /dev/null differ diff --git a/django/contrib/admin/static/admin/js/SelectFilter2.js b/django/contrib/admin/static/admin/js/SelectFilter2.js index b7bc9d5f8f..2eb67e8e1c 100644 --- a/django/contrib/admin/static/admin/js/SelectFilter2.js +++ b/django/contrib/admin/static/admin/js/SelectFilter2.js @@ -5,7 +5,7 @@ Different than SelectFilter because this is coupled to the admin framework. Requires core.js, SelectBox.js and addevent.js. */ - +(function($) { function findForm(node) { // returns the node of the form containing the given node if (node.tagName.toLowerCase() != 'form') { @@ -14,7 +14,7 @@ function findForm(node) { return node; } -var SelectFilter = { +window.SelectFilter = { init: function(field_id, field_name, is_stacked, admin_media_prefix) { if (field_id.match(/__prefix__/)){ // Don't intialize on empty forms. @@ -44,41 +44,42 @@ var SelectFilter = { //
var selector_available = quickElement('div', selector_div, ''); selector_available.className = 'selector-available'; - quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name])); - var filter_p = quickElement('p', selector_available, ''); + var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); + quickElement('img', title_available, '', 'src', admin_media_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may add some by selecting them below and then clicking the "Add" button.'), [field_name])); + + var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); filter_p.className = 'selector-filter'; - var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input", 'style', 'width:16px;padding:2px'); + var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); - var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/selector-search.gif'); - search_selector_img.alt = gettext("Filter"); + var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into the filter box to narrow down the list of available %s."), [field_name])); filter_p.appendChild(document.createTextNode(' ')); - var filter_input = quickElement('input', filter_p, '', 'type', 'text'); + var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); filter_input.id = field_id + '_input'; + selector_available.appendChild(from_box); - var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()'); + var choose_all = quickElement('a', selector_available, gettext('Add all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link'); choose_all.className = 'selector-chooseall'; //