Open kishalaykundu opened 4 years ago
I have this use case working lbasically like this:
<form method="POST" action="{% url 'app-name:url-name' slug=object.slug %}">
<div class="form-horizontal">
{% crispy form %}
</div>
{% crispy formset %}
</form>
I do basically the same thing again and again (e.g. the pattern above is repeated many times in my application).
The trick to making it work with InlineFormSet is to declare a form helper:
from crispy_forms.helper import FormHelper
class SomeFormSetHelper(FormHelper):
"""A crispy helper for the SomeInlineFormSet"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form_tag = False
self.disable_csrf = True
self.template = 'table_inline_formset.html'
self.layout = Layout(
Field('field1', hidden=True),
'field2',
Field('field3', css_class='repeat-date'),
Field('field4', css_class='repeat-user'),
'field5'
)
Then in the method construct_formset
or construct_inlines
, depending on which view you are using, you can associate the helper with the formset:
formset.helper = SomeFormSetHelper()
for form in formset:
# munge fields if needed, an example:
form.fields['DELETE'].widget.attrs['title'] = 'Delete on Save'
return formset
Looks like I build a custom table version of inline formset, table_inline_formset.html
to achieve what I wanted in a table view. I think the template below was about not showing the empty formset and then using jquery to duplicate it with a button - but my application is a little old now.
{% load crispy_forms_tags %}
{% load crispy_forms_utils %}
{% load crispy_forms_field %}
{% load crispy_forms_filters %}
{% specialspaceless %}
{% if formset_tag %}
<form {{ flat_attrs|safe }} method="{{ form_method }}" {% if formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
{% endif %}
{% if formset_method|lower == 'post' and not disable_csrf %}
{% csrf_token %}
{% endif %}
{% if formset.non_form_errors %}
{{ formset|as_crispy_errors }}
{% endif %}
<div>
{{ formset.management_form|crispy }}
</div>
<table{% if form_id %} id="{{ form_id }}_table"{% endif%} class="table table-striped table-condensed">
<thead>
{% if formset.readonly and not formset.queryset.exists %}
{% else %}
<tr>
{% for field in formset.empty_form %}
{% if field.label and not field.is_hidden %}
<th for="{{ field.auto_id }}" class="control-label {% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</th>
{% endif %}
{% endfor %}
</tr>
{% endif %}
</thead>
<tbody>
<tr class="hidden empty-form">
{% for field in formset.empty_form %}
{% include 'bootstrap3/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr>
{% for form in formset %}
{% if form_show_errors and not form.is_extra %}
{% include "bootstrap3/errors.html" %}
{% endif %}
<tr>
{% for field in form %}
{% include 'bootstrap3/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% include "bootstrap3/inputs.html" %}
{% if formset_tag %}</form>{% endif %}
{% endspecialspaceless %}
In case someone needs this, here is my solution:
class MyFormHelper(FormHelper):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
"field",
)
class PlaceMetaInline(InlineFormSetFactory):
...
def construct_formset(self):
formset = super().construct_formset()
formset.helper = forms.MyFormHelper().helper
return formset
# In template
{% for inline_form in inlines %}
{% crispy inline_form inline_form.helper %}
{% endfor %}
I am using 'extra_views' to create and update a model 'Patient' and its related model 'PatientAddress'. I am also using 'crispy_forms' to beautify the html form. CreateWithInlinesView works fine. The UpdateWithInlinesView however does not seem to play nice with crispy_forms. I have attached the requisite files, but I give a description of the problem below:
In 'update.html', I have the following lines:
DOES NOT WORK
WORKS:
The first form comes back to the update page whereas the second form works but is not at all aesthetically nice. I am not quite sure what to do with this or how to proceed from here. I apologize in advance if this is not the appropriate place to post about this.
code.zip