Ticket #19235: admin_actions_as_buttons.diff

File admin_actions_as_buttons.diff, 17.0 KB (added by Marijonas, 12 years ago)

First version of the patch -- documentation is not updated.

  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index 19c212d..565e79c 100644
    a b class ModelAdmin(BaseModelAdmin):  
    339339    actions_on_top = True
    340340    actions_on_bottom = False
    341341    actions_selection_counter = True
     342    actions_template = 'admin/actions_as_buttons.html'
    342343
    343344    def __init__(self, model, admin_site):
    344345        self.model = model
    class ModelAdmin(BaseModelAdmin):  
    925926        # There can be multiple action forms on the page (at the top
    926927        # and bottom of the change list, for example). Get the action
    927928        # whose button was pushed.
     929        # The request will not contain 'index' field if button layout is used.
    928930        try:
    929931            action_index = int(request.POST.get('index', 0))
    930932        except ValueError:
    class ModelAdmin(BaseModelAdmin):  
    12021204            return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
    12031205
    12041206        # If the request was POSTed, this might be a bulk action or a bulk
    1205         # edit. Try to look up an action or confirmation first, but if this
    1206         # isn't an action the POST will fall through to the bulk edit check,
    1207         # below.
    1208         action_failed = False
    1209         selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
    1210 
    1211         # Actions with no confirmation
    1212         if (actions and request.method == 'POST' and
    1213                 'index' in request.POST and '_save' not in request.POST):
    1214             if selected:
    1215                 response = self.response_action(request, queryset=cl.get_query_set(request))
    1216                 if response:
    1217                     return response
    1218                 else:
    1219                     action_failed = True
    1220             else:
    1221                 msg = _("Items must be selected in order to perform "
    1222                         "actions on them. No items have been changed.")
    1223                 self.message_user(request, msg)
    1224                 action_failed = True
    1225 
    1226         # Actions with confirmation
    1227         if (actions and request.method == 'POST' and
    1228                 helpers.ACTION_CHECKBOX_NAME in request.POST and
    1229                 'index' not in request.POST and '_save' not in request.POST):
    1230             if selected:
    1231                 response = self.response_action(request, queryset=cl.get_query_set(request))
    1232                 if response:
    1233                     return response
    1234                 else:
    1235                     action_failed = True
     1207        # edit. It is a bulk edit if '_save' is in request.POST and it is a
     1208        # bulk action if '_save' is not in request.POST.
     1209
     1210        if actions and request.method == 'POST' and '_save' not in request.POST:
     1211            response = self.response_action(request, queryset=cl.get_query_set(request))
     1212            if response:
     1213                return response
    12361214
    12371215        # If we're allowing changelist editing, we need to construct a formset
    12381216        # for the changelist given all the fields to be edited. Then we'll
    class ModelAdmin(BaseModelAdmin):  
    12401218        formset = cl.formset = None
    12411219
    12421220        # Handle POSTed bulk-edit data.
    1243         if (request.method == "POST" and cl.list_editable and
    1244                 '_save' in request.POST and not action_failed):
     1221        if request.method == 'POST' and cl.list_editable and '_save' in request.POST:
    12451222            FormSet = self.get_changelist_formset(request)
    12461223            formset = cl.formset = FormSet(request.POST, request.FILES, queryset=cl.result_list)
    12471224            if formset.is_valid():
  • django/contrib/admin/static/admin/js/actions.js

    diff --git a/django/contrib/admin/static/admin/js/actions.js b/django/contrib/admin/static/admin/js/actions.js
    index 8494970..c5ad2d7 100644
    a b  
    104104                $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
    105105                        list_editable_changed = true;
    106106                });
    107                 $('form#changelist-form button[name="index"]').click(function(event) {
     107                /* button[name="index"] is for select layout and button[name="action"] is for button layout */
     108                $('form#changelist-form button[name="index"], form#changelist-form button[name="action"]').click(function(event) {
    108109                        if (list_editable_changed) {
    109110                                return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
    110111                        }
     
    117118                                }
    118119                        });
    119120                        if (action_changed) {
     121                                /* action_changed will always be false in button layout. Confirmations will only be shown in select layout. */
    120122                                if (list_editable_changed) {
    121123                                        return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
    122124                                } else {
  • django/contrib/admin/static/admin/js/actions.min.js

    diff --git a/django/contrib/admin/static/admin/js/actions.min.js b/django/contrib/admin/static/admin/js/actions.min.js
    index 6b1947c..4caaa65 100644
    a b  
    1 (function(a){a.fn.actions=function(n){var b=a.extend({},a.fn.actions.defaults,n),e=a(this),g=false,k=function(c){c?i():j();a(e).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)},f=function(){var c=a(e).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},true));a(b.allToggle).attr("checked",function(){if(c==e.length){value=true;i()}else{value=false;l()}return value})},i=
    2 function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},m=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},j=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},l=function(){j();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();
    3 a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);f();a(b.acrossInput).val()==1&&m()});a(b.allToggle).show().click(function(){k(a(this).attr("checked"));f()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);m()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",false);l();k(0);f()});lastChecked=null;a(e).click(function(c){if(!c)c=window.event;var d=c.target?
    4 c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&c.shiftKey===true){var h=false;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(e).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))h=h?false:true;h&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);lastChecked=d;f()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){g=
    5 true});a('form#changelist-form button[name="index"]').click(function(){if(g)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var c=false;a("div.actions select option:selected").each(function(){if(a(this).val())c=true});if(c)return g?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):
    6 confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
     1(function(a){a.fn.actions=function(m){var b=a.extend({},a.fn.actions.defaults,m),f=a(this),e=!1,j=function(c){c?h():i();a(f).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)},g=function(){var c=a(f).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).attr("checked",function(){c==f.length?(value=!0,h()):(value=!1,k());return value})},h=function(){a(b.acrossClears).hide();
     2a(b.acrossQuestions).show();a(b.allContainer).hide()},l=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},i=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},k=function(){i();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);
     3g();1==a(b.acrossInput).val()&&l()});a(b.allToggle).show().click(function(){j(a(this).attr("checked"));g()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);l()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",!1);k();j(0);g()});lastChecked=null;a(f).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(lastChecked).attr("checked",
     4d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(f).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);lastChecked=d;g()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"], form#changelist-form button[name="action"]').click(function(){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});
     5a('form#changelist-form input[name="_save"]').click(function(){var b=!1;a("div.actions select option:selected").each(function(){a(this).val()&&(b=!0)});if(b)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};
     6a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
  • deleted file 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
    deleted file mode 100644
    index aaaa245..0000000
    + -  
    1 {% load i18n %}
    2 <div class="actions">
    3     {% for field in action_form %}{% if field.label %}<label>{{ field.label }} {% endif %}{{ field }}{% if field.label %}</label>{% endif %}{% endfor %}
    4     <button type="submit" class="button" title="{% trans "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">{% trans "Go" %}</button>
    5     {% if actions_selection_counter %}
    6         <script type="text/javascript">var _actions_icnt="{{ cl.result_list|length|default:"0" }}";</script>
    7         <span class="action-counter">{{ selection_note }}</span>
    8         {% if cl.result_count != cl.result_list|length %}
    9         <span class="all">{{ selection_note_all }}</span>
    10         <span class="question">
    11             <a href="javascript:;" title="{% trans "Click here to select the objects across all pages" %}">{% blocktrans with cl.result_count as total_count %}Select all {{ total_count }} {{ module_name }}{% endblocktrans %}</a>
    12         </span>
    13         <span class="clear"><a href="javascript:;">{% trans "Clear selection" %}</a></span>
    14         {% endif %}
    15     {% endif %}
    16 </div>
  • new file django/contrib/admin/templates/admin/actions_as_buttons.html

    diff --git a/django/contrib/admin/templates/admin/actions_as_buttons.html b/django/contrib/admin/templates/admin/actions_as_buttons.html
    new file mode 100644
    index 0000000..174510d
    - +  
     1{% load i18n %}
     2<div class="actions">
     3    {{ action_form.select_across }}
     4    {% for choice in action_form.fields.action.choices %}
     5        {% if choice.0 %}
     6        <button type="submit" class="button" name="action" value="{{ choice.0 }}">{{ choice.1 }}</button>
     7        {% endif %}
     8    {% endfor %}
     9    {% if actions_selection_counter %}
     10        <script type="text/javascript">var _actions_icnt="{{ cl.result_list|length|default:"0" }}";</script>
     11        <span class="nowrap">
     12            <span class="action-counter">{{ selection_note }}</span>
     13            {% if cl.result_count != cl.result_list|length %}
     14            <span class="all">{{ selection_note_all }}</span>
     15            <span class="question">
     16                <a href="javascript:;" title="{% trans "Click here to select the objects across all pages" %}">{% blocktrans with cl.result_count as total_count %}Select all {{ total_count }} {{ module_name }}{% endblocktrans %}</a>
     17            </span>
     18            <span class="clear"><a href="javascript:;">{% trans "Clear selection" %}</a></span>
     19        </span>
     20        {% endif %}
     21    {% endif %}
     22</div>
  • new file django/contrib/admin/templates/admin/actions_as_select.html

    diff --git a/django/contrib/admin/templates/admin/actions_as_select.html b/django/contrib/admin/templates/admin/actions_as_select.html
    new file mode 100644
    index 0000000..aaaa245
    - +  
     1{% load i18n %}
     2<div class="actions">
     3    {% for field in action_form %}{% if field.label %}<label>{{ field.label }} {% endif %}{{ field }}{% if field.label %}</label>{% endif %}{% endfor %}
     4    <button type="submit" class="button" title="{% trans "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">{% trans "Go" %}</button>
     5    {% if actions_selection_counter %}
     6        <script type="text/javascript">var _actions_icnt="{{ cl.result_list|length|default:"0" }}";</script>
     7        <span class="action-counter">{{ selection_note }}</span>
     8        {% if cl.result_count != cl.result_list|length %}
     9        <span class="all">{{ selection_note_all }}</span>
     10        <span class="question">
     11            <a href="javascript:;" title="{% trans "Click here to select the objects across all pages" %}">{% blocktrans with cl.result_count as total_count %}Select all {{ total_count }} {{ module_name }}{% endblocktrans %}</a>
     12        </span>
     13        <span class="clear"><a href="javascript:;">{% trans "Clear selection" %}</a></span>
     14        {% endif %}
     15    {% endif %}
     16</div>
  • django/contrib/admin/templates/admin/change_list.html

    diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html
    index c72b663..b310381 100644
    a b  
    8787      {% endif %}
    8888
    8989      {% block result_list %}
    90           {% if action_form and actions_on_top and cl.full_result_count %}{% admin_actions %}{% endif %}
     90          {% if action_form and actions_on_top and cl.full_result_count %}{% admin_actions cl.model_admin %}{% endif %}
    9191          {% result_list cl %}
    92           {% if action_form and actions_on_bottom and cl.full_result_count %}{% admin_actions %}{% endif %}
     92          {% if action_form and actions_on_bottom and cl.full_result_count %}{% admin_actions cl.model_admin %}{% endif %}
    9393      {% endblock %}
    9494      {% block pagination %}{% pagination cl %}{% endblock %}
    9595      </form>
  • django/contrib/admin/templatetags/admin_list.py

    diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
    index ce435de..2148fcf 100644
    a b def admin_list_filter(cl, spec):  
    378378        'spec': spec,
    379379    }))
    380380
    381 @register.inclusion_tag('admin/actions.html', takes_context=True)
    382 def admin_actions(context):
     381@register.simple_tag(takes_context=True)
     382def admin_actions(context, model_admin):
    383383    """
    384384    Track the number of times the action field has been rendered on the page,
    385385    so we know which value to use.
    386386    """
    387387    context['action_index'] = context.get('action_index', -1) + 1
    388     return context
     388    return get_template(model_admin.actions_template).render(context)
Back to Top