From 7ca6007bd2cfb69e88704e8e9a6de17866581b0a Mon Sep 17 00:00:00 2001 From: David Sanders Date: Tue, 28 Jun 2016 12:19:53 -0700 Subject: [PATCH] Fixed #26811 -- Added addButton option to admin inlines JavaScript. --- .../contrib/admin/static/admin/js/inlines.js | 33 +++++++++++-------- .../admin/static/admin/js/inlines.min.js | 18 +++++----- js_tests/admin/inlines.test.js | 18 ++++++++++ 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/django/contrib/admin/static/admin/js/inlines.js b/django/contrib/admin/static/admin/js/inlines.js index a284d76c3c..4e9bb77e9c 100644 --- a/django/contrib/admin/static/admin/js/inlines.js +++ b/django/contrib/admin/static/admin/js/inlines.js @@ -44,17 +44,19 @@ $(this).not("." + options.emptyCssClass).addClass(options.formCssClass); }); if ($this.length && showAddButton) { - var addButton; - if ($this.prop("tagName") === "TR") { - // If forms are laid out as table rows, insert the - // "add" button in a new table row: - var numCols = this.eq(-1).children().length; - $parent.append('' + options.addText + ""); - addButton = $parent.find("tr:last a"); - } else { - // Otherwise, insert it immediately after the last form: - $this.filter(":last").after('
' + options.addText + "
"); - addButton = $this.filter(":last").next().find("a"); + var addButton = options.addButton; + if (addButton === null) { + if ($this.prop("tagName") === "TR") { + // If forms are laid out as table rows, insert the + // "add" button in a new table row: + var numCols = this.eq(-1).children().length; + $parent.append('' + options.addText + ""); + addButton = $parent.find("tr:last a"); + } else { + // Otherwise, insert it immediately after the last form: + $this.filter(":last").after('
' + options.addText + "
"); + addButton = $this.filter(":last").next().find("a"); + } } addButton.click(function(e) { e.preventDefault(); @@ -137,7 +139,8 @@ emptyCssClass: "empty-row", // CSS class applied to the empty row formCssClass: "dynamic-form", // CSS class applied to each form in a formset added: null, // Function called each time a new form is added - removed: null // Function called each time a form is deleted + removed: null, // Function called each time a form is deleted + addButton: null // Existing add button to use }; @@ -201,7 +204,8 @@ reinitDateTimeShortCuts(); updateSelectFilter(); alternatingRows(row); - } + }, + addButton: options.addButton }); return $rows; @@ -267,7 +271,8 @@ reinitDateTimeShortCuts(); updateSelectFilter(); updateInlineLabel(row); - } + }, + addButton: options.addButton }); return $rows; diff --git a/django/contrib/admin/static/admin/js/inlines.min.js b/django/contrib/admin/static/admin/js/inlines.min.js index 7e5228d7ad..1968ac2ae4 100644 --- a/django/contrib/admin/static/admin/js/inlines.min.js +++ b/django/contrib/admin/static/admin/js/inlines.min.js @@ -1,10 +1,10 @@ (function(c){c.fn.formset=function(b){var a=c.extend({},c.fn.formset.defaults,b),d=c(this);b=d.parent();var k=function(a,g,l){var b=new RegExp("("+g+"-(\\d+|__prefix__))");g=g+"-"+l;c(a).prop("for")&&c(a).prop("for",c(a).prop("for").replace(b,g));a.id&&(a.id=a.id.replace(b,g));a.name&&(a.name=a.name.replace(b,g))},e=c("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(e.val(),10),g=c("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),h=""===g.val()||0'+a.addText+""),m=b.find("tr:last a")):(d.filter(":last").after('"),m=d.filter(":last").next().find("a"));m.click(function(b){b.preventDefault();b=c("#"+a.prefix+"-empty");var f=b.clone(!0);f.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id", -a.prefix+"-"+l);f.is("tr")?f.children(":last").append('
'+a.deleteText+"
"):f.is("ul")||f.is("ol")?f.append('
  • '+a.deleteText+"
  • "):f.children(":first").append(''+a.deleteText+"");f.find("*").each(function(){k(this,a.prefix,e.val())});f.insertBefore(c(b));c(e).val(parseInt(e.val(),10)+1);l+=1;""!==g.val()&&0>=g.val()-e.val()&&m.parent().hide(); -f.find("a."+a.deleteCssClass).click(function(b){b.preventDefault();f.remove();--l;a.removed&&a.removed(f);c(document).trigger("formset:removed",[f,a.prefix]);b=c("."+a.formCssClass);c("#id_"+a.prefix+"-TOTAL_FORMS").val(b.length);(""===g.val()||0'+a.addText+""),m=b.find("tr:last a")):(d.filter(":last").after('"),m=d.filter(":last").next().find("a")));m.click(function(b){b.preventDefault();b=c("#"+a.prefix+"-empty"); +var f=b.clone(!0);f.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);f.is("tr")?f.children(":last").append('
    '+a.deleteText+"
    "):f.is("ul")||f.is("ol")?f.append('
  • '+a.deleteText+"
  • "):f.children(":first").append(''+a.deleteText+"");f.find("*").each(function(){k(this,a.prefix,e.val())});f.insertBefore(c(b)); +c(e).val(parseInt(e.val(),10)+1);l+=1;""!==g.val()&&0>=g.val()-e.val()&&m.parent().hide();f.find("a."+a.deleteCssClass).click(function(b){b.preventDefault();f.remove();--l;a.removed&&a.removed(f);c(document).trigger("formset:removed",[f,a.prefix]);b=c("."+a.formCssClass);c("#id_"+a.prefix+"-TOTAL_FORMS").val(b.length);(""===g.val()||0'); + var addButton = this.table.find('.add-button'); + this.inlineRow.tabularFormset({ + prefix: 'first', + deleteText: 'Remove', + addButton: addButton + }); + assert.equal(this.table.find('.add-row a').length, 0); + addButton.click(); + assert.ok(this.table.find('#first-1').hasClass('row2')); +});