Ticket #12282: admin-selectacross.3.diff

File admin-selectacross.3.diff, 10.1 KB (added by jezdez, 5 years ago)

Even better now. Only needs through testing with the usual suspects (IE etc)

  • django/contrib/admin/helpers.py

    diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
    index d047d89..29b777f 100644
    a b ACTION_CHECKBOX_NAME = '_selected_action' 
    1717
    1818class ActionForm(forms.Form):
    1919    action = forms.ChoiceField(label=_('Action:'))
     20    select_across = forms.BooleanField(label='', required=False, initial=0,
     21        widget=forms.HiddenInput({'class': 'select-across'}))
    2022
    2123checkbox = forms.CheckboxInput({'class': 'action-select'}, lambda value: False)
    2224
  • django/contrib/admin/media/css/changelists.css

    diff --git a/django/contrib/admin/media/css/changelists.css b/django/contrib/admin/media/css/changelists.css
    index a9d7543..99ff8bc 100644
    a b  
    228228    border-right: 1px solid #ddd;
    229229}
    230230
    231 .action_counter{
    232     font-size: 11px;
    233     margin: 0 0.5em;
    234     display: none;
    235 }
    236 
    237231#changelist table input {
    238232    margin: 0;
    239233}
     
    250244    background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
    251245}
    252246
     247#changelist .actions.selected {
     248    background: #fffccf;
     249    border-top: 1px solid #fffee8;
     250    border-bottom: 1px solid #edecd6;
     251}
     252
     253#changelist .actions span.all,
     254#changelist .actions span.action-counter,
     255#changelist .actions span.clear,
     256#changelist .actions span.question {
     257    font-size: 11px;
     258    margin: 0 0.5em;
     259    display: none;
     260}
     261
    253262#changelist .actions:last-child {
    254263    border-bottom: none;
    255264}
  • django/contrib/admin/media/js/actions.js

    diff --git a/django/contrib/admin/media/js/actions.js b/django/contrib/admin/media/js/actions.js
    index 658f015..c50bdf5 100644
    a b  
    11var Actions = {
    22    init: function() {
    33        counterSpans = document.getElementsBySelector('span._acnt');
    4         counterContainer = document.getElementsBySelector('span.action_counter');
     4        counterContainer = document.getElementsBySelector('span.action-counter');
     5        allContainer = document.getElementsBySelector('div.actions span.all');
     6        actionContainer = document.getElementsBySelector('div.actions');
    57        actionCheckboxes = document.getElementsBySelector('tr input.action-select');
     8        acrossInputs = document.getElementsBySelector('div.actions input.select-across');
     9        acrossQuestions = document.getElementsBySelector('div.actions span.question');
     10        acrossClears = document.getElementsBySelector('div.actions span.clear');
     11        acrossQuestionLinks = document.getElementsBySelector('div.actions span.question a');
     12        acrossClearsLinks = document.getElementsBySelector('div.actions span.clear a');
     13
     14        Actions.setDisplay(counterContainer, 'inline');
    615        selectAll = document.getElementById('action-toggle');
    7         lastChecked = null;
    8         for(var i = 0; i < counterContainer.length; i++) {
    9             counterContainer[i].style.display = 'inline';
    10         }
    1116        if (selectAll) {
    12             selectAll.style.display = 'inline';
     17            Actions.setDisplay([selectAll], 'inline');
    1318            addEvent(selectAll, 'click', function() {
    1419                Actions.checker(selectAll.checked);
    1520                Actions.counter();
    1621            });
     22            for(var i = 0; i < acrossQuestionLinks.length; i++) {
     23                addEvent(acrossQuestionLinks[i], 'click', function() {
     24                    Actions.setAcrossInputs(1);
     25                    Actions.showClear()
     26                    return false;
     27                });
     28            }
     29            for(var i = 0; i < acrossClearsLinks.length; i++) {
     30                addEvent(acrossClearsLinks[i], 'click', function() {
     31                    selectAll.checked = false;
     32                    Actions.clearAcross();
     33                    Actions.checker(0);
     34                    Actions.counter();
     35                    return false;
     36                });
     37            }
    1738        }
     39        lastChecked = null;
    1840        for(var i = 0; i < actionCheckboxes.length; i++) {
    1941            addEvent(actionCheckboxes[i], 'click', function(e) {
    2042                if (!e) { var e = window.event; }
    var Actions = { 
    5779            tr.className = tr.className.replace(' selected', '');
    5880        } 
    5981    },
    60     checked: function() {
    61         selectAll.checked = false;
     82    setAcrossInputs: function(checked) {
     83        for(var i = 0; i < acrossInputs.length; i++) {
     84            acrossInputs[i].value = checked;
     85        }
    6286    },
    6387    checker: function(checked) {
     88        if (checked) {
     89            Actions.showQuestion()
     90        } else {
     91            Actions.reset();
     92        }
    6493        for(var i = 0; i < actionCheckboxes.length; i++) {
    6594            actionCheckboxes[i].checked = checked;
    6695            Actions.toggleRow(actionCheckboxes[i].parentNode.parentNode, checked);
    6796        }
    6897    },
     98    setDisplay: function(elements, value) {
     99        for(var i = 0; i < elements.length; i++) {
     100            elements[i].style.display = value;
     101        }
     102    },
     103    showQuestion: function() {
     104        Actions.setDisplay(acrossQuestions, 'inline');
     105        Actions.setDisplay(acrossClears, 'none');
     106        Actions.setDisplay(allContainer, 'none');
     107    },
     108    showClear: function() {
     109        Actions.setDisplay(acrossQuestions, 'none');
     110        Actions.setDisplay(acrossClears, 'inline');
     111        Actions.setDisplay(counterContainer, 'none');
     112        Actions.setDisplay(allContainer, 'inline');
     113        for(var i = 0; i < actionContainer.length; i++) {
     114            Actions.toggleRow(actionContainer[i], true)
     115        }
     116    },
     117    reset: function() {
     118        Actions.setDisplay(allContainer, 'none')
     119        Actions.setDisplay(acrossQuestions, 'none');
     120        Actions.setDisplay(acrossClears, 'none');
     121        Actions.setDisplay(counterContainer, 'inline');
     122    },
     123    clearAcross: function() {
     124        Actions.reset()
     125        Actions.setAcrossInputs(0);
     126        for(var i = 0; i < actionContainer.length; i++) {
     127            Actions.toggleRow(actionContainer[i], false)
     128        }
     129    },
    69130    counter: function() {
    70131        counter = 0;
    71132        for(var i = 0; i < actionCheckboxes.length; i++) {
    var Actions = { 
    76137        for(var i = 0; i < counterSpans.length; i++) {
    77138            counterSpans[i].innerHTML = counter;
    78139        }
    79         selectAll.checked = (counter == actionCheckboxes.length);
     140        if (counter == actionCheckboxes.length) {
     141            selectAll.checked = true;
     142            Actions.showQuestion()
     143        } else {
     144            selectAll.checked = false;
     145            Actions.clearAcross()
     146        }
    80147    }
    81148};
    82149
  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index 6dc707e..f3aa8b7 100644
    a b class ModelAdmin(BaseModelAdmin): 
    719719        # If the form's valid we can handle the action.
    720720        if action_form.is_valid():
    721721            action = action_form.cleaned_data['action']
     722            select_across = action_form.cleaned_data['select_across']
    722723            func, name, description = self.get_actions(request)[action]
    723724
    724725            # Get the list of selected PKs. If nothing's selected, we can't
    725             # perform an action on it, so bail.
     726            # perform an action on it, so bail. Except we want to perform
     727            # the action explicitely on all objects.
    726728            selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
    727             if not selected:
     729            if not selected and not select_across:
    728730                # Reminder that something needs to be selected or nothing will happen
    729731                msg = _("Items must be selected in order to perform actions on them. No items have been changed.")
    730732                self.message_user(request, msg)
    731733                return None
    732734
    733             response = func(self, request, queryset.filter(pk__in=selected))
     735            if not select_across:
     736                # Perform the action only on the selected objects
     737                queryset = queryset.filter(pk__in=selected)
     738
     739            response = func(self, request, queryset)
    734740
    735741            # Actions may return an HttpResponse, which will be used as the
    736742            # response from the POST. If not, we'll be a good little HTTP
  • django/contrib/admin/templates/admin/actions.html

    diff --git a/django/contrib/admin/templates/admin/actions.html b/django/contrib/admin/templates/admin/actions.html
    index 6d96616..11f5e71 100644
    a b  
    11{% load i18n %}
    22<div class="actions">
    3     {% for field in action_form %}<label>{{ field.label }} {{ field }}</label>{% endfor %}
     3    {% for field in action_form %}{% if field.label %}<label>{{ field.label }} {% endif %}{{ field }}{% if field.label %}</label>{% endif %}{% endfor %}
    44    <button type="submit" class="button" title="{% trans "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">{% trans "Go" %}</button>
    55    {% if actions_selection_counter %}
    6     <span class="action_counter">
    7       {% blocktrans with cl.result_count as total_count %}<span class="_acnt">0</span> of {{ total_count }} {{ module_name }} selected{% endblocktrans %}
    8     </span>
     6        <span class="action-counter">
     7            {% blocktrans with cl.result_count as total_count %}
     8            <span class="_acnt">0</span> of {{ total_count }} {{ module_name }} selected
     9            {% endblocktrans %}
     10        </span>
     11        {% if cl.result_count != cl.result_list|length %}
     12        <span class="all">
     13            {% blocktrans with cl.result_count as total_count %}
     14            All {{ total_count }} {{ module_name }} selected
     15            {% endblocktrans %}
     16        </span>
     17        <span class="question">
     18            <a href="javascript:;" title="{% trans "Click here to select all objects across all pages" %}">
     19                {% blocktrans with cl.result_count as total_count %}
     20                    Select all {{ total_count }} {{ module_name }}
     21                {% endblocktrans %}
     22            </a>
     23        </span>
     24        <span class="clear"><a href="javascript:;">{% trans "Clear selection" %}</a></span>
     25        {% endif %}
    926    {% endif %}
    1027</div>
     28
Back to Top