Skip to content

Commit

Permalink
Fix bugs when different inlines share the same default prefix
Browse files Browse the repository at this point in the history
fixes #60
  • Loading branch information
fdintino committed Oct 17, 2016
1 parent 24d58ae commit 254fe15
Show file tree
Hide file tree
Showing 20 changed files with 344 additions and 76 deletions.
4 changes: 4 additions & 0 deletions nested_admin/nested.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ def _create_formsets(self, request, obj, change):

formsets = []
inline_instances = []
prefixes = {}

for formset, inline_instance in zip(orig_formsets, orig_inline_instances):
if not hasattr(formset, 'nesting_depth'):
Expand Down Expand Up @@ -172,6 +173,9 @@ def _create_formsets(self, request, obj, change):
form_obj = None
InlineFormSet = nested.get_formset(request, form_obj)
prefix = '%s-%s' % (form_prefix, InlineFormSet.get_default_prefix())
prefixes[prefix] = prefixes.get(prefix, 0) + 1
if prefixes[prefix] != 1:
prefix = "%s-%s" % (prefix, prefixes[prefix])

formset_params = {
'instance': form_obj,
Expand Down
34 changes: 15 additions & 19 deletions nested_admin/static/nested_admin/dist/nested_admin.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion nested_admin/static/nested_admin/dist/nested_admin.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions nested_admin/static/nested_admin/dist/nested_admin.min.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DjangoFormset {
this.$inline.find(this.opts.addButtonSelector).parents('.djn-add-item').hide();
}
for (var i = 0; i < totalForms; i++) {
this._initializeForm('#' + this.prefix + i);
this._initializeForm('#' + this.prefix + '-' + i);
}
}
_initializeForm(form) {
Expand Down Expand Up @@ -219,7 +219,7 @@ class DjangoFormset {

$form.removeClass(this.opts.emptyClass);
$form.addClass('djn-item');
$form.attr('id', $form.attr('id').replace('-empty', index));
$form.attr('id', $form.attr('id').replace('-empty', '-' + index));

if (isNested) {
$form.append(DJNesting.createContainerElement());
Expand Down Expand Up @@ -308,8 +308,8 @@ class DjangoFormset {
}
var oldIndex = $form.djangoFormIndex();
var oldFormPrefixRegex = new RegExp('([\\#_]|^)'
+ regexQuote(this.prefix + '-' + oldIndex));
$form.attr('id', this.prefix + index);
+ regexQuote(this.prefix + '-' + oldIndex) + '(?!\-\d)');
$form.attr('id', this.prefix + '-' + index);
DJNesting.updateFormAttributes($form, oldFormPrefixRegex, '$1' + this.prefix + '-' + index);

// Update prefixes on nested DjangoFormset objects
Expand All @@ -329,15 +329,15 @@ class DjangoFormset {
var initialFormCount = this.mgmtVal('INITIAL_FORMS'),
totalFormCount = this.mgmtVal('TOTAL_FORMS'),
gapIndex = initialFormCount,
$existingForm = $('#' + this.prefix + gapIndex);
$existingForm = $('#' + this.prefix + '-' + gapIndex);

if (!$existingForm.length) {
return;
}

var oldFormPrefixRegex = new RegExp('([\\#_]|^)'
+ regexQuote(this.prefix) + '-' + gapIndex);
$existingForm.attr('id', this.prefix + totalFormCount);
+ regexQuote(this.prefix) + '-' + gapIndex + '(?!\-\d)');
$existingForm.attr('id', this.prefix + '-' + totalFormCount);
DJNesting.updateFormAttributes($existingForm, oldFormPrefixRegex, '$1' + this.prefix + '-' + totalFormCount);

// Update prefixes on nested DjangoFormset objects
Expand Down Expand Up @@ -408,10 +408,9 @@ class DjangoFormset {
}

// Replace the ids for the splice form
var oldFormPrefixRegex = new RegExp('([\\#_]|^)'
+ regexQuote($form.attr('id').replace(/([^\-\d])(\d+)$/, '$1-$2')));
var oldFormPrefixRegex = new RegExp('([\\#_]|^)' + regexQuote($form.attr('id')) + '(?!\-\d)');
newIndex = (isInitial) ? initialFormCount : totalFormCount;
$form.attr('id', newFormsetPrefix + newIndex);
$form.attr('id', newFormsetPrefix + '-' + newIndex);
DJNesting.updateFormAttributes($form, oldFormPrefixRegex, '$1' + newFormsetPrefix + '-' + newIndex);

// Update prefixes on nested DjangoFormset objects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ $.fn.djangoPrefixIndex = function() {
}

if (id && !prefix && $this.is('.djn-item') && id.match(/\d+$/)) {
[cacheKey, prefix, index] = id.match(/(.*?[^\-\d])(\d+)$/) || [null, null, null];
[cacheKey, prefix, index] = id.match(/(.*?)\-(\d+)$/) || [null, null, null];
}

if (!prefix) {
$form = $this.closest('.djn-inline-form');
if ($form.length) {
[cacheKey, prefix, index] = $form.attr('id').match(/(.*?[^\-\d])(\d+)$/)
[cacheKey, prefix, index] = $form.attr('id').match(/(.*?)\-(\d+)$/)
|| [null, null, null];
} else {
$group = $this.closest('.djn-group');
Expand Down Expand Up @@ -80,9 +80,9 @@ $.fn.djangoFormsetPrefix = function() {

var filterDjangoFormsetForms = function(form, $group, formsetPrefix) {
var formId = form.getAttribute('id'),
formIndex = formId.substr(formsetPrefix.length);
formIndex = formId.substr(formsetPrefix.length + 1);

// Check if form id matches /{prefix}\d+/
// Check if form id matches /{prefix}-\d+/
if (formId.indexOf(formsetPrefix) !== 0) { return false; }
return (!formIndex.match(/\D/));
};
Expand Down
4 changes: 2 additions & 2 deletions nested_admin/static/nested_admin/src/nested-admin/sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function updatePositions(prefix, skipDeleted) {
// The field name on the fieldset which is a ForeignKey to the parent model
groupFkName = groupData.formsetFkName,
parentPkVal,
[, parentPrefix, index] = prefix.match(/^(.*)\-(\d+)-[^\-]+$/) || [],
[, parentPrefix, index] = prefix.match(/^(.*)\-(\d+)-[^\-]+(?:\-\d+)?$/) || [],
sortableOptions = groupData.sortableOptions,
sortableExcludes = (sortableOptions || {}).sortableExcludes || [];

Expand All @@ -34,7 +34,7 @@ export function updatePositions(prefix, skipDeleted) {
if (!this.id || this.id.substr(-6) == '-empty') {
return true; // Same as continue
}
var regex = new RegExp('^(?:id_)?' + regexQuote(prefix) + '\\d+$');
var regex = new RegExp('^(?:id_)?' + regexQuote(prefix) + '\\-\\d+$');

if (!this.id.match(regex)) {
return true;
Expand Down
4 changes: 0 additions & 4 deletions nested_admin/static/nested_admin/src/nested-admin/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ DJNesting.updateFormAttributes = function($elem, search, replace, selector) {
$node.attr(attrName, attrVal.replace(search, replace));
}
});

if ($node.attr('id') && $node.is('.djn-item')) {
$node.attr('id', $node.attr('id').replace(/([^\-\d])\-(\d+)$/, '$1$2'));
}
});
// update prepopulate ids for function initPrepopulatedFields
$elem.find('.prepopulated_field').each(function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ <h2 class="djn-collapse-handler grp-collapse-handler">
{% if inline_admin_form.pk_field.field %}
data-is-initial="{% if inline_admin_form.pk_field.field.value %}true{% else %}false{% endif %}"
{% endif %}
id="{{ inline_admin_formset.formset.prefix }}{% if forloop.last %}-empty{% else %}{{ inline_admin_form.form|form_index }}{% endif %}">
id="{{ inline_admin_formset.formset.prefix }}-{% if forloop.last %}empty{% else %}{{ inline_admin_form.form|form_index }}{% endif %}">
<h3 class="djn-collapse-handler grp-collapse-handler{% if not inline_opts.sortable_options or not inline_opts.sortable_options.disabled %} djn-drag-handler{% endif %}">
<div class="djn-collapse-handler-verbose-name">{{ inline_admin_formset.opts.verbose_name }}&nbsp;&nbsp;</div>{% if inline_admin_form.original %}{{ inline_admin_form.original|striptags|safe }}{% endif %}
</h3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h2 class="djn-collapse-handler grp-collapse-handler">
{% if inline_admin_form.pk_field.field %}
data-is-initial="{% if inline_admin_form.pk_field.field.value %}true{% else %}false{% endif %}"
{% endif %}
id="{{ inline_admin_formset.formset.prefix }}{% if forloop.last %}-empty{% else %}{%if is_nested %}{% endif %}{{ inline_admin_form.form|form_index }}{% endif %}">
id="{{ inline_admin_formset.formset.prefix }}-{% if forloop.last %}empty{% else %}{%if is_nested %}{% endif %}{{ inline_admin_form.form|form_index }}{% endif %}">

{% if inline_admin_form.form.non_field_errors %}
<tr class="grp-tr"><td class="grp-td djn-td" colspan="{{ inline_admin_form|cell_count }}">
Expand Down
2 changes: 1 addition & 1 deletion nested_admin/templates/nesting/admin/inlines/stacked.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h2>
{% if inline_admin_form.pk_field.field %}
data-is-initial="{% if inline_admin_form.pk_field.field.value %}true{% else %}false{% endif %}"
{% endif %}
id="{{ inline_admin_formset.formset.prefix }}{% if forloop.last %}-empty{% else %}{{ inline_admin_form.form|form_index }}{% endif %}">
id="{{ inline_admin_formset.formset.prefix }}-{% if forloop.last %}empty{% else %}{{ inline_admin_form.form|form_index }}{% endif %}">

<h3 class="{% if not inline_opts.sortable_options or not inline_opts.sortable_options.disabled %} djn-drag-handler{% endif %}">
<b>{{ inline_admin_formset.opts.verbose_name|capfirst }}:</b>&nbsp;<span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} <a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="inlinechangelink">{% trans "Change" %}</a>{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion nested_admin/templates/nesting/admin/inlines/tabular.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h2>
{% if inline_admin_form.pk_field.field %}
data-is-initial="{% if inline_admin_form.pk_field.field.value %}true{% else %}false{% endif %}"
{% endif %}
id="{{ inline_admin_formset.formset.prefix }}{% if forloop.last %}-empty{% else %}{%if is_nested %}{% endif %}{{ inline_admin_form.form|form_index }}{% endif %}">
id="{{ inline_admin_formset.formset.prefix }}-{% if forloop.last %}empty{% else %}{%if is_nested %}{% endif %}{{ inline_admin_form.form|form_index }}{% endif %}">

{% if inline_admin_form.form.non_field_errors %}
<tr><td class="djn-td" colspan="{{ inline_admin_form|cell_count }}">
Expand Down
Loading

0 comments on commit 254fe15

Please sign in to comment.