Loading django/contrib/admin/helpers.py +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ ACTION_CHECKBOX_NAME = '_selected_action' class ActionForm(forms.Form): action = forms.ChoiceField(label=_('Action:')) select_across = forms.BooleanField(label='', required=False, initial=0, widget=forms.HiddenInput({'class': 'select-across'})) checkbox = forms.CheckboxInput({'class': 'action-select'}, lambda value: False) Loading django/contrib/admin/media/css/changelists.css +15 −6 Original line number Diff line number Diff line Loading @@ -228,12 +228,6 @@ border-right: 1px solid #ddd; } .action_counter{ font-size: 11px; margin: 0 0.5em; display: none; } #changelist table input { margin: 0; } Loading @@ -250,6 +244,21 @@ background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; } #changelist .actions.selected { background: #fffccf; border-top: 1px solid #fffee8; border-bottom: 1px solid #edecd6; } #changelist .actions span.all, #changelist .actions span.action-counter, #changelist .actions span.clear, #changelist .actions span.question { font-size: 11px; margin: 0 0.5em; display: none; } #changelist .actions:last-child { border-bottom: none; } Loading django/contrib/admin/media/js/actions.js +111 −83 Original line number Diff line number Diff line var Actions = { init: function() { counterSpans = document.getElementsBySelector('span._acnt'); counterContainer = document.getElementsBySelector('span.action_counter'); actionCheckboxes = document.getElementsBySelector('tr input.action-select'); selectAll = document.getElementById('action-toggle'); lastChecked = null; for(var i = 0; i < counterContainer.length; i++) { counterContainer[i].style.display = 'inline'; } if (selectAll) { selectAll.style.display = 'inline'; addEvent(selectAll, 'click', function() { Actions.checker(selectAll.checked); Actions.counter(); }); (function($) { $.fn.actions = function(opts) { var options = $.extend({}, $.fn.actions.defaults, opts); var actionCheckboxes = $(this); checker = function(checked) { if (checked) { showQuestion(); } else { reset(); } for(var i = 0; i < actionCheckboxes.length; i++) { addEvent(actionCheckboxes[i], 'click', function(e) { if (!e) { var e = window.event; } var target = e.target ? e.target : e.srcElement; if (lastChecked && lastChecked != target && e.shiftKey == true) { var inrange = false; lastChecked.checked = target.checked; Actions.toggleRow(lastChecked.parentNode.parentNode, target.checked); for (var i = 0; i < actionCheckboxes.length; i++) { if (actionCheckboxes[i] == lastChecked || actionCheckboxes[i] == target) { inrange = (inrange) ? false : true; $(actionCheckboxes).attr("checked", checked) .parent().parent().toggleClass(options.selectedClass, checked); } if (inrange) { actionCheckboxes[i].checked = target.checked; Actions.toggleRow(actionCheckboxes[i].parentNode.parentNode, target.checked); updateCounter = function() { var count = $(actionCheckboxes).filter(":checked").length; $("span._acnt").html(count); $(options.allToggle).attr("checked", function() { if (count == actionCheckboxes.length) { value = true; showQuestion(); } else { value = false; clearAcross(); } return value }); } showQuestion = function() { $(options.acrossClears).hide(); $(options.acrossQuestions).show(); $(options.allContainer).hide(); } lastChecked = target; Actions.counter(); }); showClear = function() { $(options.acrossClears).show(); $(options.acrossQuestions).hide(); $(options.actionContainer).toggleClass(options.selectedClass); $(options.allContainer).show(); $(options.counterContainer).hide(); } var changelistTable = document.getElementsBySelector('#changelist table')[0]; if (changelistTable) { addEvent(changelistTable, 'click', function(e) { if (!e) { var e = window.event; } var target = e.target ? e.target : e.srcElement; if (target.nodeType == 3) { target = target.parentNode; } if (target.className == 'action-select') { var tr = target.parentNode.parentNode; Actions.toggleRow(tr, target.checked); reset = function() { $(options.acrossClears).hide(); $(options.acrossQuestions).hide(); $(options.allContainer).hide(); $(options.counterContainer).show(); } }); clearAcross = function() { reset(); $(options.acrossInput).val(0); $(options.actionContainer).removeClass(options.selectedClass); } }, toggleRow: function(tr, checked) { if (checked && tr.className.indexOf('selected') == -1) { tr.className += ' selected'; } else if (!checked) { tr.className = tr.className.replace(' selected', ''); // Show counter by default $(options.counterContainer).show(); // Check state of checkboxes and reinit state if needed $(this).filter(":checked").each(function(i) { $(this).parent().parent().toggleClass(options.selectedClass); updateCounter(); if ($(options.acrossInput).val() == 1) { showClear(); } }, checked: function() { selectAll.checked = false; }, checker: function(checked) { for(var i = 0; i < actionCheckboxes.length; i++) { actionCheckboxes[i].checked = checked; Actions.toggleRow(actionCheckboxes[i].parentNode.parentNode, checked); }); $(options.allToggle).show().click(function() { checker($(this).attr("checked")); updateCounter(); }); $("div.actions span.question a").click(function(event) { event.preventDefault(); $(options.acrossInput).val(1); showClear(); }); $("div.actions span.clear a").click(function(event) { event.preventDefault(); $(options.allToggle).attr("checked", false); clearAcross(); checker(0); updateCounter(); }); lastChecked = null; $(actionCheckboxes).click(function(event) { if (!event) { var event = window.event; } var target = event.target ? event.target : event.srcElement; if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey == true) { var inrange = false; $(lastChecked).attr("checked", target.checked) .parent().parent().toggleClass(options.selectedClass, target.checked); $(actionCheckboxes).each(function() { if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) { inrange = (inrange) ? false : true; } }, counter: function() { counter = 0; for(var i = 0; i < actionCheckboxes.length; i++) { if(actionCheckboxes[i].checked){ counter++; if (inrange) { $(this).attr("checked", target.checked) .parent().parent().toggleClass(options.selectedClass, target.checked); } }); } for(var i = 0; i < counterSpans.length; i++) { counterSpans[i].innerHTML = counter; $(target).parent().parent().toggleClass(options.selectedClass, target.checked); lastChecked = target; updateCounter(); }); } selectAll.checked = (counter == actionCheckboxes.length); /* Setup plugin defaults */ $.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" } }; addEvent(window, 'load', Actions.init); No newline at end of file })(jQuery); django/contrib/admin/media/js/actions.min.js 0 → 100644 +1 −0 Original line number Diff line number Diff line (function(a){a.fn.actions=function(d){var c=a.extend({},a.fn.actions.defaults,d);var b=a(this);checker=function(e){if(e){showQuestion()}else{reset()}a(b).attr("checked",e).parent().parent().toggleClass(c.selectedClass,e)};updateCounter=function(){var e=a(b).filter(":checked").length;a("span._acnt").html(e);a(c.allToggle).attr("checked",function(){if(e==b.length){value=true;showQuestion()}else{value=false;clearAcross()}return value})};showQuestion=function(){a(c.acrossClears).hide();a(c.acrossQuestions).show();a(c.allContainer).hide()};showClear=function(){a(c.acrossClears).show();a(c.acrossQuestions).hide();a(c.actionContainer).toggleClass(c.selectedClass);a(c.allContainer).show();a(c.counterContainer).hide()};reset=function(){a(c.acrossClears).hide();a(c.acrossQuestions).hide();a(c.allContainer).hide();a(c.counterContainer).show()};clearAcross=function(){reset();a(c.acrossInput).val(0);a(c.actionContainer).removeClass(c.selectedClass)};a(c.counterContainer).show();a(this).filter(":checked").each(function(e){a(this).parent().parent().toggleClass(c.selectedClass);updateCounter();if(a(c.acrossInput).val()==1){showClear()}});a(c.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(e){e.preventDefault();a(c.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(e){e.preventDefault();a(c.allToggle).attr("checked",false);clearAcross();checker(0);updateCounter()});lastChecked=null;a(b).click(function(f){if(!f){var f=window.event}var g=f.target?f.target:f.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(g)&&f.shiftKey==true){var e=false;a(lastChecked).attr("checked",g.checked).parent().parent().toggleClass(c.selectedClass,g.checked);a(b).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(g)){e=(e)?false:true}if(e){a(this).attr("checked",g.checked).parent().parent().toggleClass(c.selectedClass,g.checked)}})}a(g).parent().parent().toggleClass(c.selectedClass,g.checked);lastChecked=g;updateCounter()})};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"}})(jQuery); No newline at end of file django/contrib/admin/options.py +10 −4 Original line number Diff line number Diff line Loading @@ -268,7 +268,7 @@ class ModelAdmin(BaseModelAdmin): js = ['js/core.js', 'js/admin/RelatedObjectLookups.js'] if self.actions is not None: js.extend(['js/getElementsBySelector.js', 'js/actions.js']) js.extend(['js/jquery.min.js', 'js/actions.min.js']) if self.prepopulated_fields: js.append('js/urlify.js') if self.opts.get_ordered_objects(): Loading Loading @@ -724,18 +724,24 @@ class ModelAdmin(BaseModelAdmin): # If the form's valid we can handle the action. if action_form.is_valid(): action = action_form.cleaned_data['action'] select_across = action_form.cleaned_data['select_across'] func, name, description = self.get_actions(request)[action] # Get the list of selected PKs. If nothing's selected, we can't # perform an action on it, so bail. # perform an action on it, so bail. Except we want to perform # the action explicitely on all objects. selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME) if not selected: if not selected and not select_across: # Reminder that something needs to be selected or nothing will happen msg = _("Items must be selected in order to perform actions on them. No items have been changed.") self.message_user(request, msg) return None response = func(self, request, queryset.filter(pk__in=selected)) if not select_across: # Perform the action only on the selected objects queryset = queryset.filter(pk__in=selected) response = func(self, request, queryset) # Actions may return an HttpResponse, which will be used as the # response from the POST. If not, we'll be a good little HTTP Loading Loading
django/contrib/admin/helpers.py +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ ACTION_CHECKBOX_NAME = '_selected_action' class ActionForm(forms.Form): action = forms.ChoiceField(label=_('Action:')) select_across = forms.BooleanField(label='', required=False, initial=0, widget=forms.HiddenInput({'class': 'select-across'})) checkbox = forms.CheckboxInput({'class': 'action-select'}, lambda value: False) Loading
django/contrib/admin/media/css/changelists.css +15 −6 Original line number Diff line number Diff line Loading @@ -228,12 +228,6 @@ border-right: 1px solid #ddd; } .action_counter{ font-size: 11px; margin: 0 0.5em; display: none; } #changelist table input { margin: 0; } Loading @@ -250,6 +244,21 @@ background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; } #changelist .actions.selected { background: #fffccf; border-top: 1px solid #fffee8; border-bottom: 1px solid #edecd6; } #changelist .actions span.all, #changelist .actions span.action-counter, #changelist .actions span.clear, #changelist .actions span.question { font-size: 11px; margin: 0 0.5em; display: none; } #changelist .actions:last-child { border-bottom: none; } Loading
django/contrib/admin/media/js/actions.js +111 −83 Original line number Diff line number Diff line var Actions = { init: function() { counterSpans = document.getElementsBySelector('span._acnt'); counterContainer = document.getElementsBySelector('span.action_counter'); actionCheckboxes = document.getElementsBySelector('tr input.action-select'); selectAll = document.getElementById('action-toggle'); lastChecked = null; for(var i = 0; i < counterContainer.length; i++) { counterContainer[i].style.display = 'inline'; } if (selectAll) { selectAll.style.display = 'inline'; addEvent(selectAll, 'click', function() { Actions.checker(selectAll.checked); Actions.counter(); }); (function($) { $.fn.actions = function(opts) { var options = $.extend({}, $.fn.actions.defaults, opts); var actionCheckboxes = $(this); checker = function(checked) { if (checked) { showQuestion(); } else { reset(); } for(var i = 0; i < actionCheckboxes.length; i++) { addEvent(actionCheckboxes[i], 'click', function(e) { if (!e) { var e = window.event; } var target = e.target ? e.target : e.srcElement; if (lastChecked && lastChecked != target && e.shiftKey == true) { var inrange = false; lastChecked.checked = target.checked; Actions.toggleRow(lastChecked.parentNode.parentNode, target.checked); for (var i = 0; i < actionCheckboxes.length; i++) { if (actionCheckboxes[i] == lastChecked || actionCheckboxes[i] == target) { inrange = (inrange) ? false : true; $(actionCheckboxes).attr("checked", checked) .parent().parent().toggleClass(options.selectedClass, checked); } if (inrange) { actionCheckboxes[i].checked = target.checked; Actions.toggleRow(actionCheckboxes[i].parentNode.parentNode, target.checked); updateCounter = function() { var count = $(actionCheckboxes).filter(":checked").length; $("span._acnt").html(count); $(options.allToggle).attr("checked", function() { if (count == actionCheckboxes.length) { value = true; showQuestion(); } else { value = false; clearAcross(); } return value }); } showQuestion = function() { $(options.acrossClears).hide(); $(options.acrossQuestions).show(); $(options.allContainer).hide(); } lastChecked = target; Actions.counter(); }); showClear = function() { $(options.acrossClears).show(); $(options.acrossQuestions).hide(); $(options.actionContainer).toggleClass(options.selectedClass); $(options.allContainer).show(); $(options.counterContainer).hide(); } var changelistTable = document.getElementsBySelector('#changelist table')[0]; if (changelistTable) { addEvent(changelistTable, 'click', function(e) { if (!e) { var e = window.event; } var target = e.target ? e.target : e.srcElement; if (target.nodeType == 3) { target = target.parentNode; } if (target.className == 'action-select') { var tr = target.parentNode.parentNode; Actions.toggleRow(tr, target.checked); reset = function() { $(options.acrossClears).hide(); $(options.acrossQuestions).hide(); $(options.allContainer).hide(); $(options.counterContainer).show(); } }); clearAcross = function() { reset(); $(options.acrossInput).val(0); $(options.actionContainer).removeClass(options.selectedClass); } }, toggleRow: function(tr, checked) { if (checked && tr.className.indexOf('selected') == -1) { tr.className += ' selected'; } else if (!checked) { tr.className = tr.className.replace(' selected', ''); // Show counter by default $(options.counterContainer).show(); // Check state of checkboxes and reinit state if needed $(this).filter(":checked").each(function(i) { $(this).parent().parent().toggleClass(options.selectedClass); updateCounter(); if ($(options.acrossInput).val() == 1) { showClear(); } }, checked: function() { selectAll.checked = false; }, checker: function(checked) { for(var i = 0; i < actionCheckboxes.length; i++) { actionCheckboxes[i].checked = checked; Actions.toggleRow(actionCheckboxes[i].parentNode.parentNode, checked); }); $(options.allToggle).show().click(function() { checker($(this).attr("checked")); updateCounter(); }); $("div.actions span.question a").click(function(event) { event.preventDefault(); $(options.acrossInput).val(1); showClear(); }); $("div.actions span.clear a").click(function(event) { event.preventDefault(); $(options.allToggle).attr("checked", false); clearAcross(); checker(0); updateCounter(); }); lastChecked = null; $(actionCheckboxes).click(function(event) { if (!event) { var event = window.event; } var target = event.target ? event.target : event.srcElement; if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey == true) { var inrange = false; $(lastChecked).attr("checked", target.checked) .parent().parent().toggleClass(options.selectedClass, target.checked); $(actionCheckboxes).each(function() { if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) { inrange = (inrange) ? false : true; } }, counter: function() { counter = 0; for(var i = 0; i < actionCheckboxes.length; i++) { if(actionCheckboxes[i].checked){ counter++; if (inrange) { $(this).attr("checked", target.checked) .parent().parent().toggleClass(options.selectedClass, target.checked); } }); } for(var i = 0; i < counterSpans.length; i++) { counterSpans[i].innerHTML = counter; $(target).parent().parent().toggleClass(options.selectedClass, target.checked); lastChecked = target; updateCounter(); }); } selectAll.checked = (counter == actionCheckboxes.length); /* Setup plugin defaults */ $.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" } }; addEvent(window, 'load', Actions.init); No newline at end of file })(jQuery);
django/contrib/admin/media/js/actions.min.js 0 → 100644 +1 −0 Original line number Diff line number Diff line (function(a){a.fn.actions=function(d){var c=a.extend({},a.fn.actions.defaults,d);var b=a(this);checker=function(e){if(e){showQuestion()}else{reset()}a(b).attr("checked",e).parent().parent().toggleClass(c.selectedClass,e)};updateCounter=function(){var e=a(b).filter(":checked").length;a("span._acnt").html(e);a(c.allToggle).attr("checked",function(){if(e==b.length){value=true;showQuestion()}else{value=false;clearAcross()}return value})};showQuestion=function(){a(c.acrossClears).hide();a(c.acrossQuestions).show();a(c.allContainer).hide()};showClear=function(){a(c.acrossClears).show();a(c.acrossQuestions).hide();a(c.actionContainer).toggleClass(c.selectedClass);a(c.allContainer).show();a(c.counterContainer).hide()};reset=function(){a(c.acrossClears).hide();a(c.acrossQuestions).hide();a(c.allContainer).hide();a(c.counterContainer).show()};clearAcross=function(){reset();a(c.acrossInput).val(0);a(c.actionContainer).removeClass(c.selectedClass)};a(c.counterContainer).show();a(this).filter(":checked").each(function(e){a(this).parent().parent().toggleClass(c.selectedClass);updateCounter();if(a(c.acrossInput).val()==1){showClear()}});a(c.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(e){e.preventDefault();a(c.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(e){e.preventDefault();a(c.allToggle).attr("checked",false);clearAcross();checker(0);updateCounter()});lastChecked=null;a(b).click(function(f){if(!f){var f=window.event}var g=f.target?f.target:f.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(g)&&f.shiftKey==true){var e=false;a(lastChecked).attr("checked",g.checked).parent().parent().toggleClass(c.selectedClass,g.checked);a(b).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(g)){e=(e)?false:true}if(e){a(this).attr("checked",g.checked).parent().parent().toggleClass(c.selectedClass,g.checked)}})}a(g).parent().parent().toggleClass(c.selectedClass,g.checked);lastChecked=g;updateCounter()})};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"}})(jQuery); No newline at end of file
django/contrib/admin/options.py +10 −4 Original line number Diff line number Diff line Loading @@ -268,7 +268,7 @@ class ModelAdmin(BaseModelAdmin): js = ['js/core.js', 'js/admin/RelatedObjectLookups.js'] if self.actions is not None: js.extend(['js/getElementsBySelector.js', 'js/actions.js']) js.extend(['js/jquery.min.js', 'js/actions.min.js']) if self.prepopulated_fields: js.append('js/urlify.js') if self.opts.get_ordered_objects(): Loading Loading @@ -724,18 +724,24 @@ class ModelAdmin(BaseModelAdmin): # If the form's valid we can handle the action. if action_form.is_valid(): action = action_form.cleaned_data['action'] select_across = action_form.cleaned_data['select_across'] func, name, description = self.get_actions(request)[action] # Get the list of selected PKs. If nothing's selected, we can't # perform an action on it, so bail. # perform an action on it, so bail. Except we want to perform # the action explicitely on all objects. selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME) if not selected: if not selected and not select_across: # Reminder that something needs to be selected or nothing will happen msg = _("Items must be selected in order to perform actions on them. No items have been changed.") self.message_user(request, msg) return None response = func(self, request, queryset.filter(pk__in=selected)) if not select_across: # Perform the action only on the selected objects queryset = queryset.filter(pk__in=selected) response = func(self, request, queryset) # Actions may return an HttpResponse, which will be used as the # response from the POST. If not, we'll be a good little HTTP Loading