Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -588,6 +588,7 @@ answer newbie questions, and generally made Django that much better: Rachel Willmer <http://www.willmer.com/kb/> Radek Švarz <http://www.svarz.cz/translate/> Rajesh Dhawan <rajesh.dhawan@gmail.com> Ramez Ashraf <ramezashraf@gmail.com> Ramiro Morales <ramiro@rmorales.net> Ram Rachum <ram@rachum.com> Randy Barlow <randy@electronsweatshop.com> Loading django/contrib/admin/static/admin/js/inlines.js +2 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ if (options.removed) { options.removed(row); } $(document).trigger('formset:removed', [row, options.prefix]); // Update the TOTAL_FORMS form count. var forms = $("." + options.formCssClass); $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); Loading @@ -120,6 +121,7 @@ if (options.added) { options.added(row); } $(document).trigger('formset:added', [row, options.prefix]); }); } return this; Loading django/contrib/admin/static/admin/js/inlines.min.js +9 −9 Original line number Diff line number Diff line (function(b){b.fn.formset=function(c){var a=b.extend({},b.fn.formset.defaults,c),f=b(this);c=f.parent();var k=function(a,e,l){var d=new RegExp("("+e+"-(\\d+|__prefix__))");e=e+"-"+l;b(a).prop("for")&&b(a).prop("for",b(a).prop("for").replace(d,e));a.id&&(a.id=a.id.replace(d,e));a.name&&(a.name=a.name.replace(d,e))},h=b("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(h.val(),10),e=b("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),d=""===e.val()||0<e.val()-h.val(); f.each(function(e){b(this).not("."+a.emptyCssClass).addClass(a.formCssClass)});if(f.length&&d){var m;"TR"===f.prop("tagName")?(f=this.eq(-1).children().length,c.append('<tr class="'+a.addCssClass+'"><td colspan="'+f+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),m=c.find("tr:last a")):(f.filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),m=f.filter(":last").next().find("a"));m.click(function(d){d.preventDefault();d=b("#"+a.prefix+ "-empty");var g=d.clone(!0);g.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);g.is("tr")?g.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):g.is("ul")||g.is("ol")?g.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):g.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></span>");g.find("*").each(function(){k(this, a.prefix,h.val())});g.insertBefore(b(d));b(h).val(parseInt(h.val(),10)+1);l+=1;""!==e.val()&&0>=e.val()-h.val()&&m.parent().hide();g.find("a."+a.deleteCssClass).click(function(d){d.preventDefault();g.remove();--l;a.removed&&a.removed(g);d=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(d.length);(""===e.val()||0<e.val()-d.length)&&m.parent().show();var c,f,h=function(){k(this,a.prefix,c)};c=0;for(f=d.length;c<f;c++)k(b(d).get(c),a.prefix,c),b(d.get(c)).find("*").each(h)});a.added&&a.added(g)})}return this}; b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null};b.fn.tabularFormset=function(c){var a=b(this),f=function(l){b(a.selector).not(".add-row").removeClass("row1 row2").filter(":even").addClass("row1").end().filter(":odd").addClass("row2")},k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a,e){var b=e.name.split("-"); SelectFilter.init(e.id,b[b.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var d=b.name.split("-");SelectFilter.init(b.id,d[d.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var e=b(this).find("input, select, textarea"),d=e.data("dependency_list")||[],c=[];b.each(d,function(b,e){c.push("#"+a.find(".field-"+e).find("input, select, textarea").attr("id"))});c.length&&e.prepopulate(c,e.attr("maxlength"))})};a.formset({prefix:c.prefix,addText:c.addText,formCssClass:"dynamic-"+ c.prefix,deleteCssClass:"inline-deletelink",deleteText:c.deleteText,emptyCssClass:"empty-form",removed:f,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();f(a)}});return a};b.fn.stackedFormset=function(c){var a=b(this),f=function(c){b(a.selector).find(".inline_label").each(function(a){a+=1;b(this).html(b(this).html().replace(/(#\d+)/g,"#"+a))})},k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a, b){var d=b.name.split("-");SelectFilter.init(b.id,d[d.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var d=b.name.split("-");SelectFilter.init(b.id,d[d.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var c=b(this).find("input, select, textarea"),d=c.data("dependency_list")||[],f=[];b.each(d,function(b,c){f.push("#"+a.find(".form-row .field-"+c).find("input, select, textarea").attr("id"))});f.length&&c.prepopulate(f,c.attr("maxlength"))})};a.formset({prefix:c.prefix, addText:c.addText,formCssClass:"dynamic-"+c.prefix,deleteCssClass:"inline-deletelink",deleteText:c.deleteText,emptyCssClass:"empty-form",removed:f,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();f(a)}});return a}})(django.jQuery); (function(b){b.fn.formset=function(d){var a=b.extend({},b.fn.formset.defaults,d),e=b(this);d=e.parent();var k=function(a,f,l){var c=new RegExp("("+f+"-(\\d+|__prefix__))");f=f+"-"+l;b(a).prop("for")&&b(a).prop("for",b(a).prop("for").replace(c,f));a.id&&(a.id=a.id.replace(c,f));a.name&&(a.name=a.name.replace(c,f))},h=b("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(h.val(),10),f=b("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),c=""===f.val()||0<f.val()-h.val(); e.each(function(f){b(this).not("."+a.emptyCssClass).addClass(a.formCssClass)});if(e.length&&c){var m;"TR"===e.prop("tagName")?(e=this.eq(-1).children().length,d.append('<tr class="'+a.addCssClass+'"><td colspan="'+e+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),m=d.find("tr:last a")):(e.filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),m=e.filter(":last").next().find("a"));m.click(function(c){c.preventDefault();c=b("#"+a.prefix+ "-empty");var g=c.clone(!0);g.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);g.is("tr")?g.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):g.is("ul")||g.is("ol")?g.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):g.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></span>");g.find("*").each(function(){k(this, a.prefix,h.val())});g.insertBefore(b(c));b(h).val(parseInt(h.val(),10)+1);l+=1;""!==f.val()&&0>=f.val()-h.val()&&m.parent().hide();g.find("a."+a.deleteCssClass).click(function(c){c.preventDefault();g.remove();--l;a.removed&&a.removed(g);b(document).trigger("formset:removed",[g,a.prefix]);c=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(c.length);(""===f.val()||0<f.val()-c.length)&&m.parent().show();var d,e,h=function(){k(this,a.prefix,d)};d=0;for(e=c.length;d<e;d++)k(b(c).get(d),a.prefix, d),b(c.get(d)).find("*").each(h)});a.added&&a.added(g);b(document).trigger("formset:added",[g,a.prefix])})}return this};b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null};b.fn.tabularFormset=function(d){var a=b(this),e=function(l){b(a.selector).not(".add-row").removeClass("row1 row2").filter(":even").addClass("row1").end().filter(":odd").addClass("row2")}, k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var f=b(this).find("input, select, textarea"),c=f.data("dependency_list")||[],d=[];b.each(c,function(b,c){d.push("#"+a.find(".field-"+c).find("input, select, textarea").attr("id"))}); d.length&&f.prepopulate(d,f.attr("maxlength"))})};a.formset({prefix:d.prefix,addText:d.addText,formCssClass:"dynamic-"+d.prefix,deleteCssClass:"inline-deletelink",deleteText:d.deleteText,emptyCssClass:"empty-form",removed:e,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();e(a)}});return a};b.fn.stackedFormset=function(d){var a=b(this),e=function(d){b(a.selector).find(".inline_label").each(function(a){a+=1;b(this).html(b(this).html().replace(/(#\d+)/g, "#"+a))})},k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var d=b(this).find("input, select, textarea"),c=d.data("dependency_list")||[],e=[];b.each(c,function(b,c){e.push("#"+a.find(".form-row .field-"+c).find("input, select, textarea").attr("id"))}); e.length&&d.prepopulate(e,d.attr("maxlength"))})};a.formset({prefix:d.prefix,addText:d.addText,formCssClass:"dynamic-"+d.prefix,deleteCssClass:"inline-deletelink",deleteText:d.deleteText,emptyCssClass:"empty-form",removed:e,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();e(a)}});return a}})(django.jQuery); docs/ref/contrib/admin/index.txt +3 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ Other topics actions admindocs javascript .. seealso:: Loading Loading @@ -1882,6 +1883,8 @@ The :doc:`staticfiles app </ref/contrib/staticfiles>` prepends ``None``) to any asset paths. The same rules apply as :ref:`regular asset definitions on forms <form-asset-paths>`. .. _contrib-admin-jquery: jQuery ~~~~~~ Loading docs/ref/contrib/admin/javascript.txt 0 → 100644 +75 −0 Original line number Diff line number Diff line ====================================== JavaScript customizations in the admin ====================================== .. _admin-javascript-inline-form-events: Inline form events ================== .. versionadded:: 1.9 You may want to execute some JavaScript when an inline form is added or removed in the admin change form. The ``formset:added`` and ``formset:removed`` jQuery events allow this. The event handler is passed three arguments: * ``event`` is the ``jQuery`` event. * ``$row`` is the newly added (or removed) row. * ``formsetName`` is the formset the row belongs to. The event is fired using the :ref:`django.jQuery namespace <contrib-admin-jquery>`. In your custom ``change_form.html`` template, extend the ``admin_change_form_document_ready`` block and add the event listener code: .. code-block:: html+django {% extends 'admin/change_form.html' %} {% block admin_change_form_document_ready %} {{ block.super }} <script type="text/javascript"> (function($) { $(document).on('formset:added', function(event, $row, formsetName) { if (formsetName == 'author_set') { // Do something } }); $(document).on('formset:removed', function(event, $row, formsetName) { // Row removed }); })(django.jQuery); </script> {% endblock %} Two points to keep in mind: * The JavaScript code must go in a template block if you are inheriting ``admin/change_form.html`` or it won't be rendered in the final HTML. * ``{{ block.super }}`` is added because Django's ``admin_change_form_document_ready`` block contains JavaScript code to handle various operations in the change form and we need that to be rendered too. Sometimes you'll need to work with ``jQuery`` plugins that are not registered in the ``django.jQuery`` namespace. To do that, simply change how the code listens for events. Instead of wrapping the listener in the ``django.jQuery`` namespace, just listen to the event triggered from there. For example: .. code-block:: html+django {% extends 'admin/change_form.html' %} {% block admin_change_form_document_ready %} {{ block.super }} <script type="text/javascript"> django.jQuery(document).on('formset:added', function(event, $row, formsetName) { // Row added }); django.jQuery(document).on('formset:removed', function(event, $row, formsetName) { // Row removed }); </script> {% endblock %} Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -588,6 +588,7 @@ answer newbie questions, and generally made Django that much better: Rachel Willmer <http://www.willmer.com/kb/> Radek Švarz <http://www.svarz.cz/translate/> Rajesh Dhawan <rajesh.dhawan@gmail.com> Ramez Ashraf <ramezashraf@gmail.com> Ramiro Morales <ramiro@rmorales.net> Ram Rachum <ram@rachum.com> Randy Barlow <randy@electronsweatshop.com> Loading
django/contrib/admin/static/admin/js/inlines.js +2 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ if (options.removed) { options.removed(row); } $(document).trigger('formset:removed', [row, options.prefix]); // Update the TOTAL_FORMS form count. var forms = $("." + options.formCssClass); $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); Loading @@ -120,6 +121,7 @@ if (options.added) { options.added(row); } $(document).trigger('formset:added', [row, options.prefix]); }); } return this; Loading
django/contrib/admin/static/admin/js/inlines.min.js +9 −9 Original line number Diff line number Diff line (function(b){b.fn.formset=function(c){var a=b.extend({},b.fn.formset.defaults,c),f=b(this);c=f.parent();var k=function(a,e,l){var d=new RegExp("("+e+"-(\\d+|__prefix__))");e=e+"-"+l;b(a).prop("for")&&b(a).prop("for",b(a).prop("for").replace(d,e));a.id&&(a.id=a.id.replace(d,e));a.name&&(a.name=a.name.replace(d,e))},h=b("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(h.val(),10),e=b("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),d=""===e.val()||0<e.val()-h.val(); f.each(function(e){b(this).not("."+a.emptyCssClass).addClass(a.formCssClass)});if(f.length&&d){var m;"TR"===f.prop("tagName")?(f=this.eq(-1).children().length,c.append('<tr class="'+a.addCssClass+'"><td colspan="'+f+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),m=c.find("tr:last a")):(f.filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),m=f.filter(":last").next().find("a"));m.click(function(d){d.preventDefault();d=b("#"+a.prefix+ "-empty");var g=d.clone(!0);g.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);g.is("tr")?g.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):g.is("ul")||g.is("ol")?g.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):g.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></span>");g.find("*").each(function(){k(this, a.prefix,h.val())});g.insertBefore(b(d));b(h).val(parseInt(h.val(),10)+1);l+=1;""!==e.val()&&0>=e.val()-h.val()&&m.parent().hide();g.find("a."+a.deleteCssClass).click(function(d){d.preventDefault();g.remove();--l;a.removed&&a.removed(g);d=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(d.length);(""===e.val()||0<e.val()-d.length)&&m.parent().show();var c,f,h=function(){k(this,a.prefix,c)};c=0;for(f=d.length;c<f;c++)k(b(d).get(c),a.prefix,c),b(d.get(c)).find("*").each(h)});a.added&&a.added(g)})}return this}; b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null};b.fn.tabularFormset=function(c){var a=b(this),f=function(l){b(a.selector).not(".add-row").removeClass("row1 row2").filter(":even").addClass("row1").end().filter(":odd").addClass("row2")},k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a,e){var b=e.name.split("-"); SelectFilter.init(e.id,b[b.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var d=b.name.split("-");SelectFilter.init(b.id,d[d.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var e=b(this).find("input, select, textarea"),d=e.data("dependency_list")||[],c=[];b.each(d,function(b,e){c.push("#"+a.find(".field-"+e).find("input, select, textarea").attr("id"))});c.length&&e.prepopulate(c,e.attr("maxlength"))})};a.formset({prefix:c.prefix,addText:c.addText,formCssClass:"dynamic-"+ c.prefix,deleteCssClass:"inline-deletelink",deleteText:c.deleteText,emptyCssClass:"empty-form",removed:f,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();f(a)}});return a};b.fn.stackedFormset=function(c){var a=b(this),f=function(c){b(a.selector).find(".inline_label").each(function(a){a+=1;b(this).html(b(this).html().replace(/(#\d+)/g,"#"+a))})},k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a, b){var d=b.name.split("-");SelectFilter.init(b.id,d[d.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var d=b.name.split("-");SelectFilter.init(b.id,d[d.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var c=b(this).find("input, select, textarea"),d=c.data("dependency_list")||[],f=[];b.each(d,function(b,c){f.push("#"+a.find(".form-row .field-"+c).find("input, select, textarea").attr("id"))});f.length&&c.prepopulate(f,c.attr("maxlength"))})};a.formset({prefix:c.prefix, addText:c.addText,formCssClass:"dynamic-"+c.prefix,deleteCssClass:"inline-deletelink",deleteText:c.deleteText,emptyCssClass:"empty-form",removed:f,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();f(a)}});return a}})(django.jQuery); (function(b){b.fn.formset=function(d){var a=b.extend({},b.fn.formset.defaults,d),e=b(this);d=e.parent();var k=function(a,f,l){var c=new RegExp("("+f+"-(\\d+|__prefix__))");f=f+"-"+l;b(a).prop("for")&&b(a).prop("for",b(a).prop("for").replace(c,f));a.id&&(a.id=a.id.replace(c,f));a.name&&(a.name=a.name.replace(c,f))},h=b("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(h.val(),10),f=b("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),c=""===f.val()||0<f.val()-h.val(); e.each(function(f){b(this).not("."+a.emptyCssClass).addClass(a.formCssClass)});if(e.length&&c){var m;"TR"===e.prop("tagName")?(e=this.eq(-1).children().length,d.append('<tr class="'+a.addCssClass+'"><td colspan="'+e+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),m=d.find("tr:last a")):(e.filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),m=e.filter(":last").next().find("a"));m.click(function(c){c.preventDefault();c=b("#"+a.prefix+ "-empty");var g=c.clone(!0);g.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);g.is("tr")?g.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):g.is("ul")||g.is("ol")?g.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):g.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></span>");g.find("*").each(function(){k(this, a.prefix,h.val())});g.insertBefore(b(c));b(h).val(parseInt(h.val(),10)+1);l+=1;""!==f.val()&&0>=f.val()-h.val()&&m.parent().hide();g.find("a."+a.deleteCssClass).click(function(c){c.preventDefault();g.remove();--l;a.removed&&a.removed(g);b(document).trigger("formset:removed",[g,a.prefix]);c=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(c.length);(""===f.val()||0<f.val()-c.length)&&m.parent().show();var d,e,h=function(){k(this,a.prefix,d)};d=0;for(e=c.length;d<e;d++)k(b(c).get(d),a.prefix, d),b(c.get(d)).find("*").each(h)});a.added&&a.added(g);b(document).trigger("formset:added",[g,a.prefix])})}return this};b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null};b.fn.tabularFormset=function(d){var a=b(this),e=function(l){b(a.selector).not(".add-row").removeClass("row1 row2").filter(":even").addClass("row1").end().filter(":odd").addClass("row2")}, k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var f=b(this).find("input, select, textarea"),c=f.data("dependency_list")||[],d=[];b.each(c,function(b,c){d.push("#"+a.find(".field-"+c).find("input, select, textarea").attr("id"))}); d.length&&f.prepopulate(d,f.attr("maxlength"))})};a.formset({prefix:d.prefix,addText:d.addText,formCssClass:"dynamic-"+d.prefix,deleteCssClass:"inline-deletelink",deleteText:d.deleteText,emptyCssClass:"empty-form",removed:e,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();e(a)}});return a};b.fn.stackedFormset=function(d){var a=b(this),e=function(d){b(a.selector).find(".inline_label").each(function(a){a+=1;b(this).html(b(this).html().replace(/(#\d+)/g, "#"+a))})},k=function(){"undefined"!==typeof SelectFilter&&(b(".selectfilter").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!1)}),b(".selectfilterstacked").each(function(a,b){var c=b.name.split("-");SelectFilter.init(b.id,c[c.length-1],!0)}))},h=function(a){a.find(".prepopulated_field").each(function(){var d=b(this).find("input, select, textarea"),c=d.data("dependency_list")||[],e=[];b.each(c,function(b,c){e.push("#"+a.find(".form-row .field-"+c).find("input, select, textarea").attr("id"))}); e.length&&d.prepopulate(e,d.attr("maxlength"))})};a.formset({prefix:d.prefix,addText:d.addText,formCssClass:"dynamic-"+d.prefix,deleteCssClass:"inline-deletelink",deleteText:d.deleteText,emptyCssClass:"empty-form",removed:e,added:function(a){h(a);"undefined"!==typeof DateTimeShortcuts&&(b(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();e(a)}});return a}})(django.jQuery);
docs/ref/contrib/admin/index.txt +3 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ Other topics actions admindocs javascript .. seealso:: Loading Loading @@ -1882,6 +1883,8 @@ The :doc:`staticfiles app </ref/contrib/staticfiles>` prepends ``None``) to any asset paths. The same rules apply as :ref:`regular asset definitions on forms <form-asset-paths>`. .. _contrib-admin-jquery: jQuery ~~~~~~ Loading
docs/ref/contrib/admin/javascript.txt 0 → 100644 +75 −0 Original line number Diff line number Diff line ====================================== JavaScript customizations in the admin ====================================== .. _admin-javascript-inline-form-events: Inline form events ================== .. versionadded:: 1.9 You may want to execute some JavaScript when an inline form is added or removed in the admin change form. The ``formset:added`` and ``formset:removed`` jQuery events allow this. The event handler is passed three arguments: * ``event`` is the ``jQuery`` event. * ``$row`` is the newly added (or removed) row. * ``formsetName`` is the formset the row belongs to. The event is fired using the :ref:`django.jQuery namespace <contrib-admin-jquery>`. In your custom ``change_form.html`` template, extend the ``admin_change_form_document_ready`` block and add the event listener code: .. code-block:: html+django {% extends 'admin/change_form.html' %} {% block admin_change_form_document_ready %} {{ block.super }} <script type="text/javascript"> (function($) { $(document).on('formset:added', function(event, $row, formsetName) { if (formsetName == 'author_set') { // Do something } }); $(document).on('formset:removed', function(event, $row, formsetName) { // Row removed }); })(django.jQuery); </script> {% endblock %} Two points to keep in mind: * The JavaScript code must go in a template block if you are inheriting ``admin/change_form.html`` or it won't be rendered in the final HTML. * ``{{ block.super }}`` is added because Django's ``admin_change_form_document_ready`` block contains JavaScript code to handle various operations in the change form and we need that to be rendered too. Sometimes you'll need to work with ``jQuery`` plugins that are not registered in the ``django.jQuery`` namespace. To do that, simply change how the code listens for events. Instead of wrapping the listener in the ``django.jQuery`` namespace, just listen to the event triggered from there. For example: .. code-block:: html+django {% extends 'admin/change_form.html' %} {% block admin_change_form_document_ready %} {{ block.super }} <script type="text/javascript"> django.jQuery(document).on('formset:added', function(event, $row, formsetName) { // Row added }); django.jQuery(document).on('formset:removed', function(event, $row, formsetName) { // Row removed }); </script> {% endblock %}