Home > other >  Django Crispy Formsets CSS
Django Crispy Formsets CSS

Time:11-26

I am trying to utilize crispy forms & bootstrap with formsets but I can't seem to figure out the CSS styling. I need to style it in the backend as I want to allow the client to Django Formset

CodePudding user response:

You need to load crispy tags and also crispy the form fiel in the template.

When we render the form now using:

{% load crispy_forms_tags %}
{% crispy example_form %}

Or in your case

{{ ingredient|crispy }}

CodePudding user response:

Edit #4

The initial issue was due to how I was rendering the form in the create.html template. As seen in the documentation, a better way is to load it is using {% crispy ..... %}, as seen below for both the for loop and empty form. However, rendering the extra form as a {% crispy formset.empty_form %} was causing issues because it was generating a whole new <form>, so for the extra form I manage to render this manually with CSS in the template. This is probably by no means the best way to do this, but alas, it works.

See below for updated files:

forms.py

class RecipeIngredientForm(forms.ModelForm):
class Meta:
    model = RecipeIngredient
    fields = ['name', 'quantity', 'unit', 'description']
    labels = {
        'name': "Ingredient",
        "quantity:": "Ingredient Quantity",
        "unit": "Unit",
        "description:": "Ingredient Description"}
    

def __init__(self, *args, **kwargs):
    super(RecipeIngredientForm, self).__init__(*args, **kwargs)

    self.helper = FormHelper()
    self.helper.form_id = 'id-entryform'
    self.helper.form_class = 'form-inline'
    self.helper.layout = Layout(
        Div(
            Div(Field("name", placeholder="Chickpeas"), css_class='col-6 col-lg-4'),
            Div(Field("quantity", placeholder="2 x 400"), css_class='col-6 col-md-4'),
            Div(Field("unit", placeholder="grams"), css_class='col-5 col-md-4'),
            Div(Field("description", placeholder="No added salt tins"), css_class='col-12'),
        
        css_class="row",
       ),
       
    )

create.html

<!--RECIPE INGREDIENTS-->
                {% if formset %}
                    <h3>Ingredients</h3>
                    {{ formset.management_form|crispy }}
                    {% load crispy_forms_tags %}
                    <div id='ingredient-form-list'>
                        {% for ingredient in formset %}
                       
                                <div class='ingredient-form'>
                                    
                                    {% crispy ingredient %}
                                    
                                </div>
                        {% endfor %}
                    </div>

                    <div id='empty-form' class='hidden'>
                        <div class="row">
                            <div class="col-6">{{ formset.empty_form.name|as_crispy_field }}</div>
                            <div class="col-6">{{ formset.empty_form.quantity|as_crispy_field }}</div>
                            <div class="col-6">{{ formset.empty_form.unit|as_crispy_field }}</div>
                            <div class="col-6">{{ formset.empty_form.description|as_crispy_field }}</div>
                        </div>
                    </div>
                    <button class="btn btn-success" id='add-more' type='button'>Add more ingredients</button>
                {% endif %}
<script>
//ingredients add form
const addMoreBtn = document.getElementById('add-more')
const totalNewForms = document.getElementById('id_ingredient-TOTAL_FORMS')

addMoreBtn.addEventListener('click', add_new_form)
function add_new_form(event) {
    if (event) {
        event.preventDefault()
    }
    const currentIngredientForms = document.getElementsByClassName('ingredient-form')
    const currentFormCount = currentIngredientForms.length //   1
    const formCopyTarget = document.getElementById('ingredient-form-list')
    const copyEmptyFormEl = document.getElementById('empty-form').cloneNode(true)
    copyEmptyFormEl.setAttribute('class', 'ingredient-form')
    copyEmptyFormEl.setAttribute('id', `ingredient-${currentFormCount}`)
    const regex = new RegExp('__prefix__', 'g')
    copyEmptyFormEl.innerHTML = copyEmptyFormEl.innerHTML.replace(regex, currentFormCount)
    totalNewForms.setAttribute('value', currentFormCount   1)
    // now add new empty form element to our html form
    formCopyTarget.append(copyEmptyFormEl)
}
  • Related