I successfully managed to make a form where one can add new rows to a form consisting of two form sets.
The new fields appear and I can enter and submit the data. But the fields are shown as empthy after the first submit. If I reenter the data the values are passed correctly. So I added a revalidation at the end of the add-Script and the form passes. But no data is added to the model, so I think the data is in deed not passed in the first approche.
Thanks for your help!
the view:
def pruefplan(request):
class RequiredFormSet(BaseFormSet):
def __init__(self, *args, **kwargs):
super(RequiredFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.empty_permitted = False
PruefschrittAttributivFormset = formset_factory(
PruefschrittAttributivForm,
max_num=10,
formset=RequiredFormSet,
)
PruefschrittVariabelFormset = formset_factory(
PruefschrittVariabelForm,
max_num=10,
formset=RequiredFormSet,
)
if request.method == 'POST': # If the form has been submitted...
# A form bound to the POST data
pruefplan_form = PruefplanForm(request.POST)
# Create a formset from the submitted data
pruefschritt_attributiv_formset = PruefschrittAttributivFormset(
request.POST,
request.FILES,
prefix='attr',
)
pruefschritt_variable_formset = PruefschrittVariabelFormset(
request.POST,
request.FILES,
prefix='var',
)
if (
pruefplan_form.is_valid()
and
pruefschritt_attributiv_formset.is_valid()
and
pruefschritt_variable_formset.is_valid()
):
pruefplan = pruefplan_form.save()
for form in pruefschritt_attributiv_formset.forms:
attributiv_item = form.save(commit=False)
attributiv_item.pruefplan = pruefplan
attributiv_item.save()
for form in pruefschritt_variable_formset.forms:
variable_item = form.save(commit=False)
variable_item.pruefplan = pruefplan
variable_item.save()
return HttpResponseRedirect('') # Redirect to a 'success' page
else:
pruefplan_form = PruefplanForm()
pruefschritt_attributiv_formset = PruefschrittAttributivFormset(
prefix='attr')
pruefschritt_variable_formset = PruefschrittVariabelFormset(
prefix='var')
# For CSRF protection
# See http://ift.tt/1pYxB9I
pruefplan = Pruefplan.objects.all()
c = {'pruefplan': pruefplan,
'pruefplan_form': pruefplan_form,
'pruefplan_attributiv_formset': pruefschritt_attributiv_formset,
'pruefplan_variable_formset': pruefschritt_variable_formset,
}
c.update(csrf(request))
return render_to_response('qpruefung/pruefplan.html', c)
the template:
<div class="tab-pane fade" id="erfassung">
<link rel="stylesheet" href="{% static 'css/jquery-ui.css' %}">
<script src="{% static 'js/jquery-ui.js' %}"></script>
<div class=container style="width: 80%">
<script>
$(document).ready(function () {
// Code adapted from http://ift.tt/1AdHNi3
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+-)');
var replacement = prefix + '-' + ndx + '-';
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,
replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function addForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
// You can only submit a maximum of 10 todo items
if (formCount < 1000) {
// Clone a form (without event handlers) from the first form
var row = $(".item:first").clone(false).get(0);
// Insert it after the last form
$(row).removeAttr('id').hide().insertAfter(".item:last").slideDown(300);
// Remove the bits we don't want in the new row/form
// e.g. error messages
$(".errorlist", row).remove();
$(row).children().removeClass("error");
// Relabel or rename all the relevant bits
$(row).children().children().each(function () {
updateElementIndex(this, prefix, formCount);
$(this).val("");
});
// Add an event handler for the delete item/form link
$(row).find(".delete").click(function () {
return deleteForm(this, prefix);
});
// Update the total form count
$("#id_" + prefix + "-TOTAL_FORMS").val(formCount + 1);
window.location.href = "#erfassung"
} // End if
else {
alert("Sorry, you can only enter a maximum of ten items.");
}
return false;
}
function addvarForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
// You can only submit a maximum of 10 todo items
if (formCount < 1000) {
// Clone a form (without event handlers) from the first form
var row = $(".item_var:first").clone(false).get(0);
// Insert it after the last form
$(row).removeAttr('id').hide().insertAfter(".item_var:last").slideDown(300);
// Remove the bits we don't want in the new row/form
// e.g. error messages
$(".errorlist", row).remove();
$(row).children().removeClass("error");
// Relabel or rename all the relevant bits
$(row).children().children().each(function () {
updateElementIndex(this, prefix, formCount);
$(this).val("");
});
// Add an event handler for the delete item/form link
$(row).find(".delete").click(function () {
return deleteForm(this, prefix);
});
// Update the total form count
$("#id_" + prefix + "-TOTAL_FORMS").val(formCount + 1);
// Revalidate the fields
$('myForm').data('validator', null);
$.validator.unobtrusive.parse($('myForm'));
} // End if
else {
alert("Sorry, you can only enter a maximum of ten items.");
}
return false;
}
// Register the click event handlers
$("#add_attr").click(function () {
return addForm(this, "attr");
});
$("#add_var").click(function () {
return addvarForm(this, "var");
});
});
</script>
</head>
<body>
<h2>Prüfplan erstellen</h2>
<form id="myForm" action="" method="POST" class="bootstrap">{% csrf_token %}
<div class="section">
{{ pruefplan_form | crispy}}
</div>
<h2>Pruefschritte attributiv</h2>
{{ pruefplan_attributiv_formset.management_form }}
{% for form in pruefplan_attributiv_formset.forms %}
<div class="item">
{{ form | crispy }}
</div>
{% endfor %}
<p><a id="add_attr" href="#">Prüfpunkt hinzufügen</a></p>
<h2>Pruefschritte variabel</h2>
{{ pruefplan_variable_formset.management_form }}
{% for form in pruefplan_variable_formset.forms %}
<div class="item_var">
{{ form | crispy }}
</div>
{% endfor %}
<p><a id="add_var" href="#">Prüfpunkt hinzufügen</a></p>
<input type="submit" value=" Submit " />
</form>
</body>
</div>
Aucun commentaire:
Enregistrer un commentaire