Comments (11)
From [email protected] on April 18, 2011 20:43:11
Just to add after reading some of the issues. I have found that removing the first row (similar to issue: 3) will not fail but no data from the inlineformsets will be added at all.
from django-dynamic-formset.
From [email protected] on April 18, 2011 20:48:11
Just to note that to add to the strangeness there are no validation errors in the form if I do what I mentioned in comment 1.
from django-dynamic-formset.
From stan.madueke on April 18, 2011 22:32:23
What version of Django are you using? Also, if you could put together a small test project (if it's not too much trouble :), it'd help me get to this faster.
Status: Accepted
Owner: stan.madueke
from django-dynamic-formset.
From [email protected] on April 18, 2011 23:16:08
I'm using Django 1.2.1
I will attempt to put a project together. As the issue is in a much larger project.
from django-dynamic-formset.
From [email protected] on April 19, 2011 05:45:34
I have made this quick example. The admin interface is active so you can look at data.
If you add some data some data and remove the first one the data will not add.
I have been unable (though I need to experiment more) to replicate the problem I am having specifically. I only just got this together and I will continue testing.
Attachment: dynFormError.tar.gz
from django-dynamic-formset.
From [email protected] on May 02, 2011 00:40:12
Did you have a look at the example I made?
from django-dynamic-formset.
From stan.madueke on May 03, 2011 17:01:26
I set up the example (on Django 1.3), but I haven't been able to reproduce the issues you reported. Could you try again against trunk, and see if the issues are still there?
from django-dynamic-formset.
From stan.madueke on May 03, 2011 17:02:41
(I meant against django-dynamic-formset trunk, not Django trunk :-)
from django-dynamic-formset.
From [email protected] on June 20, 2011 16:15:27
Sorry for the late reply. I'm just back on this project.
So I'm using trunk and it works correctly. Though compared to the example my project needs to use 'formCssClass' on one of the formsets. I cannot figure out why this is the case.
Thanks.
from django-dynamic-formset.
From [email protected] on January 24, 2012 11:22:01
you need formCssClass with multiple formsets because line ~66 when getting the items to update on delete does this:
var forms = $('.' + options.formCssClass).not('.formset-custom-template');
Then renumbers and renames all found forms.
without that, if you delete any of the forms to create "new" items, it will wreak havoc on your names, and lead to a multiple value error.
from django-dynamic-formset.
I am using two forms, while adding the jquery formset is working properly but while deleting it is taking two forms of row values. Please help me to solve this problem.
Html code
<div class="panel-body panel-body-diminfo"><table class="test" id="test1">
<tr>
<td><label style="text-align:left;">Length</label></td>
<td><label style="text-align:left;">Breadth</label> </td>
<td><label style="text-align:left;"><center>Area Square Feet</center></label></td>
</tr>
{% for link_editform in edit_form %}
<tr class="link-dimformset" name="reloadjs" value="Reload JavaScript" >
<td onClick="LoadMyJs('/static/bootstrap/dist/js/dimen.js')">{{ link_editform.dimensionX.errors }}{{ link_editform.dimensionX }}</td>
<td onClick="LoadMyJs('/static/bootstrap/dist/js/dimen.js')">{{ link_editform.dimensionY.errors }}{{ link_editform.dimensionY }}</td>
<td onClick="LoadMyJs('/static/bootstrap/dist/js/dimen.js')">{{ link_editform.sqft.errors }}{{ link_editform.sqft }}</td>
</tr>
{% endfor %}</table>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 col-sm-12">
<div class="panel panel-primary">
<div class="panel-heading">Installment Breakup</div>
<div class="panel-body panel-body-inst"><table>
{% for link_instform in link_installmentset %}
<tr class="link-installformset" >
<td > <p >{{ link_instform.installment }}</p> </td>
<td><p>{{ link_instform.breakup_percent }}</p></td>
<td><a>%</a></td>
</tr>
{% endfor %}
</table> </div>
</div></div>
</div>
jqueryformset.js
;(function($) {
$.fn.formset = function(opts)
{
var options =
flatExtraClasses = options.extraClasses.join(' '),
totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS'),
maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS'),
minForms = $('#id_' + options.prefix + '-MIN_NUM_FORMS'),
childElementSelector = 'input,select,textarea,label,div',
$$ = $(this),
applyExtraClasses = function(row, ndx) {
if (options.extraClasses) {
row.removeClass(flatExtraClasses);
row.addClass(options.extraClasses[ndx % options.extraClasses.length]);
}
},
updateElementIndex = function(elem, prefix, ndx) {
var idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'),
replacement = prefix + '-' + ndx + '-';
if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));
if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));
if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));
},
hasChildElements = function(row) {
return row.find(childElementSelector).length > 0;
},
showAddButton = function() {
return maxForms.length == 0 || // For Django versions pre 1.2
(maxForms.val() == '' || (maxForms.val() - totalForms.val() > 0));
},
/**
* Indicates whether delete link(s) can be displayed - when total forms > min forms
*/
showDeleteLinks = function() {
return minForms.length == 0 || // For Django versions pre 1.7
(minForms.val() == '' || (totalForms.val() - minForms.val() > 0));
},
insertDeleteLink = function(row) {
var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.'),
addCssSelector = $.trim(options.addCssClass).replace(/\s+/g, '.');
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('<a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + '<img src="/static/delete.png" >' + '</a>');
}
else if (row.is('UL') || row.is('OL')) {
// If they're laid out as an ordered/unordered list,
// insert an <li> after the last list item:
row.append('<li><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + '<img src="/static/delete.png">' +'</a></li>');
} else {
// Otherwise, just insert the remove button as the
// last child element of the form's container:
row.append('<a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + '<img src="/static/delete.png">' +'</a>');
}
// Check if we're under the minimum number of forms - not to display delete link at rendering
if (!showDeleteLinks()){
row.find('a.' + delCssSelector).hide();
}
row.find('a.' + delCssSelector).click(function() {
var row = $(this).parents('.' + options.formCssClass),
del = row.find('input:hidden[id $= "-DELETE"]'),
buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'),
forms;
if (del.length) {
// We're dealing with an inline formset.
// Rather than remove this form from the DOM, we'll mark it as deleted
// and hide it, then let Django handle the deleting:
del.val('on');
row.hide();
forms = $('.' + options.formCssClass).not(':hidden');
} else {
alert(totalForms.val());
row.remove();
// Update the TOTAL_FORMS count:
forms = $('.' + options.formCssClass).not('.formset-custom-template');
totalForms.val(forms.length);
}
for (var i=0, formCount=forms.length; i<formCount; i++) {
// Apply `extraClasses` to form rows so they're nicely alternating:
applyExtraClasses(forms.eq(i), i);
if (!del.length) {
// Also update names and IDs for all child controls (if this isn't
// a delete-able inline formset) so they remain in sequence:
forms.eq(i).find(childElementSelector).each(function() {
updateElementIndex($(this), options.prefix, i);
});
}
}
// Check if we've reached the minimum number of forms - hide all delete link(s)
if (!showDeleteLinks()){
$('a.' + delCssSelector).each(function(){$(this).hide();});
}
// Check if we need to show the add button:
if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show();
// If a post-delete callback was provided, call it with the deleted form:
if (options.removed) options.removed(row);
return false;
});
};
$$.each(function(i) {
var row = $(this),
del = row.find('input:checkbox[id $= "-DELETE"]');
if (del.length) {
// If you specify "can_delete = True" when creating an inline formset,
// Django adds a checkbox to each form in the formset.
// Replace the default checkbox with a hidden field:
if (del.is(':checked')) {
// If an inline formset containing deleted forms fails validation, make sure
// we keep the forms hidden (thanks for the bug report and suggested fix Mike)
del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" value="on" />');
row.hide();
} else {
del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" />');
}
// Hide any labels associated with the DELETE checkbox:
$('label[for="' + del.attr('id') + '"]').hide();
del.remove();
}
if (hasChildElements(row)) {
row.addClass(options.formCssClass);
if (row.is(':visible')) {
insertDeleteLink(row);
applyExtraClasses(row, i);
}
}
});
if ($$.length) {
var hideAddButton = !showAddButton(),
addButton, template;
if (options.formTemplate) {
// If a form template was specified, we'll clone it to generate new form instances:
template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);
template.removeAttr('id').addClass(options.formCssClass + ' formset-custom-template');
template.find(childElementSelector).each(function() {
updateElementIndex($(this), options.prefix, '__prefix__');
});
insertDeleteLink(template);
} else {
// Otherwise, use the last form in the formset; this works much better if you've got
// extra (>= 1) forms (thnaks to justhamade for pointing this out):
template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');
template.find('input:hidden[id $= "-DELETE"]').remove();
// Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
template.find(childElementSelector).not(options.keepFieldValues).each(function() {
var elem = $(this);
// If this is a checkbox or radiobutton, uncheck it.
// This fixes Issue 1, reported by Wilson.Andrew.J:
if (elem.is('input:checkbox') || elem.is('input:radio')) {
elem.attr('checked', false);
} else {
elem.val('');
}
});
}
// FIXME: Perhaps using $.data would be a better idea?
options.formTemplate = template;
if ($$.is('TR')) {
// If forms are laid out as table rows, insert the
// "add" button in a new table row:
var numCols = $$.eq(0).children().length, // This is a bit of an assumption :|
buttonRow = $('<tr><td colspan="' + numCols + '"><a class="' + options.addCssClass + '" href="javascript:void(0)">' + '<button type="button" class="btn btn-warning btn-xs" style="margin-left:-25px;" >Add</button>' + '</a></tr>')
.addClass(options.formCssClass + '-add');
$$.parent().append(buttonRow);
if (hideAddButton) buttonRow.hide();
addButton = buttonRow.find('a');
} else {
// Otherwise, insert it immediately after the last form:
$$.filter(':last').after('<a class="' + options.addCssClass + '" href="javascript:void(0)">' + options.addText + '</a>');
addButton = $$.filter(':last').next();
if (hideAddButton) addButton.hide();
}
addButton.click(function() {
var formCount = parseInt(totalForms.val()),
row = options.formTemplate.clone(true).removeClass('formset-custom-template'),
buttonRow = $($(this).parents('tr.' + options.formCssClass + '-add').get(0) || this)
delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.');
applyExtraClasses(row, formCount);
row.insertBefore(buttonRow).show();
row.find(childElementSelector).each(function() {
updateElementIndex($(this), options.prefix, formCount);
});
totalForms.val(formCount + 1);
// Check if we're above the minimum allowed number of forms -> show all delete link(s)
if (showDeleteLinks()){
$('a.' + delCssSelector).each(function(){$(this).show();});
}
// Check if we've exceeded the maximum allowed number of forms:
if (!showAddButton()) buttonRow.hide();
// If a post-add callback was supplied, call it with the added form:
if (options.added) options.added(row);
return false;
});
}
return $$;
};
/* Setup plugin defaults */
$.fn.formset.defaults = {
prefix: 'form', // The form prefix for your django formset
formTemplate: null, // The jQuery selection cloned to generate new form instances
addText: 'add another', // Text for the add link
deleteText: 'remove', // Text for the delete link
addCssClass: 'add-row', // CSS class applied to the add link
deleteCssClass: 'delete-row', // CSS class applied to the delete link
formCssClass: 'dynamic-form', // CSS class applied to each form in a formset
extraClasses: [], // Additional CSS classes, which will be applied to each form in turn
keepFieldValues: '', // jQuery selector for fields whose values should be kept when the form is cloned
added: null, // Function called each time a new form is added
removed: null // Function called each time a form is deleted
};
})(jQuery);
assigning add and delete operations
$(function() {
$('.link-dimformset').formset({
addText: 'Add dimension',
deleteText: 'Rem',
prefix: "dim",
})
});
$(function() {
$('.link-installformset').formset({
addText: 'Add Installment',
deleteText: 'Rem',
prefix: "ins",
})
});
from django-dynamic-formset.
Related Issues (20)
- delete link doesn't show and formCount is NaN HOT 4
- Uncaught ReferenceError: deleteButtonHTML is not defined
- No remove button and add won't add form HOT 3
- Simlutaneous deletion and creation not working HOT 8
- I have installed django_dynamic_formsets but it says the module not installed dynamic_formsets. I'm using windows 10 with python version 3.8.5.
- Limit minimum and maximum of formsets
- Nested formsets HOT 1
- Demo package download link is down
- Is it possible to include html inside addText or deleteText? HOT 4
- nothing
- deleteContainerClass does not seem to be working
- Only rows specified in 'extra' are saved and rows above 'extra' do not have default values
- deleteContainerClass not working properly HOT 1
- how to use onKeyup for django formset input fields
- delete button shows up only once in django formset that is created with queryset to edit
- Clicking on add row in update mode displays foreign keys even if label is none. HOT 1
- Input field id show NaN instead of increased number even with prefix set HOT 6
- does not seem to work with file fields HOT 1
- Deleting instance not working when hideLastAddForm is true HOT 1
- Unsetting and resetting the current formset
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-dynamic-formset.