diff --git a/django/contrib/admin/media/js/admin/DateTimeShortcuts.js b/django/contrib/admin/media/js/admin/DateTimeShortcuts.js index fbaa599c7a..d840f78729 100644 --- a/django/contrib/admin/media/js/admin/DateTimeShortcuts.js +++ b/django/contrib/admin/media/js/admin/DateTimeShortcuts.js @@ -120,6 +120,7 @@ var DateTimeShortcuts = { }, handleClockQuicklink: function(num, val) { DateTimeShortcuts.clockInputs[num].value = val; + DateTimeShortcuts.clockInputs[num].focus(); DateTimeShortcuts.dismissClock(num); }, // Add calendar widget to a given field. @@ -247,12 +248,21 @@ var DateTimeShortcuts = { format = format.replace('\n', '\\n'); format = format.replace('\t', '\\t'); format = format.replace("'", "\\'"); - return "function(y, m, d) { DateTimeShortcuts.calendarInputs["+num+"].value = new Date(y, m-1, d).strftime('"+format+"');document.getElementById(DateTimeShortcuts.calendarDivName1+"+num+").style.display='none';}"; + return ["function(y, m, d) { DateTimeShortcuts.calendarInputs[", + num, + "].value = new Date(y, m-1, d).strftime('", + format, + "');DateTimeShortcuts.calendarInputs[", + num, + "].focus();document.getElementById(DateTimeShortcuts.calendarDivName1+", + num, + ").style.display='none';}"].join(''); }, handleCalendarQuickLink: function(num, offset) { var d = new Date(); d.setDate(d.getDate() + offset) DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); + DateTimeShortcuts.calendarInputs[num].focus(); DateTimeShortcuts.dismissCalendar(num); }, cancelEventPropagation: function(e) { diff --git a/django/contrib/admin/media/js/inlines.js b/django/contrib/admin/media/js/inlines.js index 55118dfc4b..9decaae444 100644 --- a/django/contrib/admin/media/js/inlines.js +++ b/django/contrib/admin/media/js/inlines.js @@ -55,24 +55,41 @@ var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS"); var nextIndex = parseInt(totalForms.val()); var template = $("#" + options.prefix + "-empty"); - var row = template.clone(true).get(0); - $(row).removeClass(options.emptyCssClass).removeAttr("id").insertBefore($(template)); - $(row).html($(row).html().replace(/__prefix__/g, nextIndex)); - $(row).addClass(options.formCssClass).attr("id", options.prefix + (nextIndex + 1)); - if ($(row).is("TR")) { + var row = template.clone(true); + row.removeClass(options.emptyCssClass) + .addClass(options.formCssClass) + .attr("id", options.prefix + nextIndex) + .insertBefore($(template)); + row.find("*") + .filter(function() { + var el = $(this); + return el.attr("id") && el.attr("id").search(/__prefix__/) >= 0; + }).each(function() { + var el = $(this); + el.attr("id", el.attr("id").replace(/__prefix__/g, nextIndex)); + }) + .end() + .filter(function() { + var el = $(this); + return el.attr("name") && el.attr("name").search(/__prefix__/) >= 0; + }).each(function() { + var el = $(this); + el.attr("name", el.attr("name").replace(/__prefix__/g, nextIndex)); + }); + if (row.is("tr")) { // If the forms are laid out in table rows, insert // the remove button into the last table cell: - $(row).children(":last").append('
' + options.deleteText + "
"); - } else if ($(row).is("UL") || $(row).is("OL")) { + row.children(":last").append('
' + options.deleteText + "
"); + } else if (row.is("ul") || row.is("ol")) { // If they're laid out as an ordered/unordered list, // insert an
  • after the last list item: - $(row).append('
  • ' + options.deleteText + "
  • "); + row.append('
  • ' + options.deleteText + "
  • "); } else { // Otherwise, just insert the remove button as the // last child element of the form's container: - $(row).children(":first").append('' + options.deleteText + ""); + row.children(":first").append('' + options.deleteText + ""); } - $(row).find("input,select,textarea,label,a").each(function() { + row.find("input,select,textarea,label,a").each(function() { updateElementIndex(this, options.prefix, totalForms.val()); }); // Update number of total forms @@ -82,7 +99,7 @@ addButton.parent().hide(); } // The delete button of each row triggers a bunch of other things - $(row).find("a." + options.deleteCssClass).click(function() { + row.find("a." + options.deleteCssClass).click(function() { // Remove the parent form containing this button: var row = $(this).parents("." + options.formCssClass); row.remove(); @@ -109,7 +126,7 @@ }); // If a post-add callback was supplied, call it with the added form: if (options.added) { - options.added($(row)); + options.added(row); } return false; }); diff --git a/django/contrib/admin/media/js/inlines.min.js b/django/contrib/admin/media/js/inlines.min.js index 29e048df54..891cc3fca5 100644 --- a/django/contrib/admin/media/js/inlines.min.js +++ b/django/contrib/admin/media/js/inlines.min.js @@ -1,5 +1,6 @@ -(function(a){a.fn.formset=function(f){var b=a.extend({},a.fn.formset.defaults,f),l=function(d,e,j){var c=new RegExp("("+e+"-\\d+)");e=e+"-"+j;a(d).attr("for")&&a(d).attr("for",a(d).attr("for").replace(c,e));if(d.id)d.id=d.id.replace(c,e);if(d.name)d.name=d.name.replace(c,e)};f=a("#id_"+b.prefix+"-TOTAL_FORMS").attr("autocomplete","off");var h=a("#id_"+b.prefix+"-MAX_NUM_FORMS").attr("autocomplete","off");f=h.val()==""||h.val()-f.val()>0;a(this).each(function(){a(this).not("."+b.emptyCssClass).addClass(b.formCssClass)}); -if(a(this).length&&f){var i;if(a(this).attr("tagName")=="TR"){f=this.eq(0).children().length;a(this).parent().append(''+b.addText+"");i=a(this).parent().find("tr:last a")}else{a(this).filter(":last").after('
    '+b.addText+"
    ");i=a(this).filter(":last").next().find("a")}i.click(function(){var d=a("#id_"+b.prefix+"-TOTAL_FORMS"),e=parseInt(d.val()), -j=a("#"+b.prefix+"-empty"),c=j.clone(true).get(0);a(c).removeClass(b.emptyCssClass).removeAttr("id").insertBefore(a(j));a(c).html(a(c).html().replace(/__prefix__/g,e));a(c).addClass(b.formCssClass).attr("id",b.prefix+(e+1));if(a(c).is("TR"))a(c).children(":last").append('
    '+b.deleteText+"
    ");else a(c).is("UL")||a(c).is("OL")?a(c).append('
  • '+b.deleteText+"
  • "): -a(c).children(":first").append(''+b.deleteText+"");a(c).find("input,select,textarea,label,a").each(function(){l(this,b.prefix,d.val())});a(d).val(e+1);h.val()!=""&&h.val()<=d.val()&&i.parent().hide();a(c).find("a."+b.deleteCssClass).click(function(){var g=a(this).parents("."+b.formCssClass);g.remove();b.removed&&b.removed(g);g=a("."+b.formCssClass);a("#id_"+b.prefix+"-TOTAL_FORMS").val(g.length);if(h.val()==""||h.val()>=g.length)i.parent().show(); -for(var k=0,m=g.length;k0;a(this).each(function(){a(this).not("."+b.emptyCssClass).addClass(b.formCssClass)}); +if(a(this).length&&g){var i;if(a(this).attr("tagName")=="TR"){g=this.eq(0).children().length;a(this).parent().append(''+b.addText+"");i=a(this).parent().find("tr:last a")}else{a(this).filter(":last").after('
    '+b.addText+"
    ");i=a(this).filter(":last").next().find("a")}i.click(function(){var e=a("#id_"+b.prefix+"-TOTAL_FORMS"),f=parseInt(e.val()), +j=a("#"+b.prefix+"-empty"),d=j.clone(true);d.removeClass(b.emptyCssClass).addClass(b.formCssClass).attr("id",b.prefix+f).insertBefore(a(j));d.find("*").filter(function(){var c=a(this);return c.attr("id")&&c.attr("id").search(/__prefix__/)>=0}).each(function(){var c=a(this);c.attr("id",c.attr("id").replace(/__prefix__/g,f))}).end().filter(function(){var c=a(this);return c.attr("name")&&c.attr("name").search(/__prefix__/)>=0}).each(function(){var c=a(this);c.attr("name",c.attr("name").replace(/__prefix__/g, +f))});if(d.is("tr"))d.children(":last").append('
    '+b.deleteText+"
    ");else d.is("ul")||d.is("ol")?d.append('
  • '+b.deleteText+"
  • "):d.children(":first").append(''+b.deleteText+"");d.find("input,select,textarea,label,a").each(function(){l(this,b.prefix,e.val())});a(e).val(f+1);h.val()!=""&& +h.val()<=e.val()&&i.parent().hide();d.find("a."+b.deleteCssClass).click(function(){var c=a(this).parents("."+b.formCssClass);c.remove();b.removed&&b.removed(c);c=a("."+b.formCssClass);a("#id_"+b.prefix+"-TOTAL_FORMS").val(c.length);if(h.val()==""||h.val()>=c.length)i.parent().show();for(var k=0,m=c.length;k 0) { + values.push($(this).val()); + } + }); + field.val(URLify(values.join(' '), maxLength)); + }; + + dependencies.keyup(populate).change(populate).focus(populate); + }); + }; +})(jQuery.noConflict()); diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 6f66893c26..ae90bce067 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -274,6 +274,7 @@ class ModelAdmin(BaseModelAdmin): js.extend(['js/jquery.min.js', 'js/actions.min.js']) if self.prepopulated_fields: js.append('js/urlify.js') + js.append('js/prepopulate.js') if self.opts.get_ordered_objects(): js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js']) @@ -1201,6 +1202,7 @@ class InlineModelAdmin(BaseModelAdmin): js = ['js/jquery.min.js', 'js/inlines.min.js'] if self.prepopulated_fields: js.append('js/urlify.js') + js.append('js/prepopulate.js') if self.filter_vertical or self.filter_horizontal: js.extend(['js/SelectBox.js' , 'js/SelectFilter2.js']) return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js]) diff --git a/django/contrib/admin/templates/admin/edit_inline/stacked.html b/django/contrib/admin/templates/admin/edit_inline/stacked.html index fb112a0166..6eb4492e49 100644 --- a/django/contrib/admin/templates/admin/edit_inline/stacked.html +++ b/django/contrib/admin/templates/admin/edit_inline/stacked.html @@ -48,6 +48,17 @@ }) } } + var initPrepopulatedFields = function(row) { + row.find('.prepopulated_field').each(function() { + var field = $(this); + var input = field.find('input, select, textarea'); + var dependency_list = input.data('dependency_list') || []; + var dependencies = row.find(dependency_list.join(',')).find('input, select, textarea'); + if (dependencies.length) { + input.prepopulate(dependencies, input.attr('maxlength')); + } + }); + } $(rows).formset({ prefix: "{{ inline_admin_formset.formset.prefix }}", addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}", @@ -57,6 +68,7 @@ emptyCssClass: "empty-form", removed: updateInlineLabel, added: (function(row) { + initPrepopulatedFields(row); reinitDateTimeShortCuts(); updateSelectFilter(); updateInlineLabel(row); diff --git a/django/contrib/admin/templates/admin/edit_inline/tabular.html b/django/contrib/admin/templates/admin/edit_inline/tabular.html index dc9552f454..48be38db5d 100644 --- a/django/contrib/admin/templates/admin/edit_inline/tabular.html +++ b/django/contrib/admin/templates/admin/edit_inline/tabular.html @@ -94,6 +94,17 @@ }) } } + var initPrepopulatedFields = function(row) { + row.find('.prepopulated_field').each(function() { + var field = $(this); + var input = field.find('input, select, textarea'); + var dependency_list = input.data('dependency_list') || []; + var dependencies = row.find(dependency_list.join(',')).find('input, select, textarea'); + if (dependencies.length) { + input.prepopulate(dependencies, input.attr('maxlength')); + } + }); + } $(rows).formset({ prefix: "{{ inline_admin_formset.formset.prefix }}", addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}", @@ -103,6 +114,7 @@ emptyCssClass: "empty-form", removed: alternatingRows, added: (function(row) { + initPrepopulatedFields(row); reinitDateTimeShortCuts(); updateSelectFilter(); alternatingRows(row); diff --git a/django/contrib/admin/templates/admin/prepopulated_fields_js.html b/django/contrib/admin/templates/admin/prepopulated_fields_js.html index e1cdb9614e..f0eb471dfb 100644 --- a/django/contrib/admin/templates/admin/prepopulated_fields_js.html +++ b/django/contrib/admin/templates/admin/prepopulated_fields_js.html @@ -1,11 +1,23 @@