带有 Django Crispy Forms 的空表单集 CSS
empty formset CSS with Django Crispy Forms
我正在尝试使用 add-more
表单按钮在 Django 中呈现带有脆皮表单的表单集。但是我无法弄清楚如何将相同的 CSS 应用于原始表格的空表格。我成功的唯一方法是创建一个新的空表单,如 this solution,但这会添加另一个 <form>
标记,这是解决方案中未涵盖的问题。如何将 CSS 应用于动态添加的表单集?
下图是我点击添加更多成分后的预期结果<button>
:
forms.py
from .models import Recipe, RecipeIngredient
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Div, Layout, Field
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",
),
)
views.py:
def recipe_create_view(request):
form = RecipeForm(request.POST or None)
RecipeIngredientFormset = formset_factory(RecipeIngredientForm, prefix="ingredient")
formset = RecipeIngredientFormset(request.POST or None)
context = {
"form": form,
"formset": formset,
}
if request.method == "POST":
#print(request.POST)
if form.is_valid() and formset.is_valid():
parent = form.save(commit=False)
parent.user = request.user
parent.save()
#recipe ingredients
for form in formset:
child = form.save(commit=False)
if form.instance.name.strip() == '':
pass
else:
child.recipe = parent
child.save()
else:
form = RecipeForm(request.POST or None)
formset = RecipeIngredientFormset()
return render(request, "recipes/create.html", context)
create.html
{% load crispy_forms_tags %}
<form action='/recipes/create/' method="POST" >
<!-- MAIN RECIPE FORM-->
{% csrf_token %}
<div class='row'>
{% for recipe in form %}
<div class="col-6 col-md-3 py-2">
{{ recipe|as_crispy_field }}
</div>
{% endfor %}
<div>
<!--RECIPE INGREDIENTS - WHERE CSS ISSUE IS -->
{% if formset %}
<h3>Ingredients</h3>
{{ formset.management_form|crispy }}
<div id='ingredient-form-list'>
{% for ingredient in formset %}
<div class='ingredient-form'>
{% crispy ingredient %}
</div>
{% endfor %}
</div>
<div id='empty-form' class='hidden'>{% crispy formset.empty_form %}</div>
<button class="btn btn-success" id='add-more' type='button'>Add more ingredients</button>
{% endif %}
</div>
<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)
}
</script>
问题如下图所示,这会创建另一个表单,而不仅仅是添加字段:
如果我使用 {{ formset.empty_form|crispy }}
而不是 {% crispy formset.empty_form %}
脚本可以正常工作,但是 CSS 没有附加到表单。
必须结合使用这两种方法才能工作,下面是对问题代码的更改:
create.html
<div>
<!--RECIPE INGREDIENTS-->
{% if formset %}
<h3 class="mt-4 mb-3">Ingredients</h3>
{{ formset.management_form|crispy }}
<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 mt-4">
<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>
</div>
<button class="btn btn-success my-2" id='add-more' type='button'>Add more ingredients</button>
{% endif %}
</div>
<div>
我正在尝试使用 add-more
表单按钮在 Django 中呈现带有脆皮表单的表单集。但是我无法弄清楚如何将相同的 CSS 应用于原始表格的空表格。我成功的唯一方法是创建一个新的空表单,如 this solution,但这会添加另一个 <form>
标记,这是解决方案中未涵盖的问题。如何将 CSS 应用于动态添加的表单集?
下图是我点击添加更多成分后的预期结果<button>
:
forms.py
from .models import Recipe, RecipeIngredient
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Div, Layout, Field
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",
),
)
views.py:
def recipe_create_view(request):
form = RecipeForm(request.POST or None)
RecipeIngredientFormset = formset_factory(RecipeIngredientForm, prefix="ingredient")
formset = RecipeIngredientFormset(request.POST or None)
context = {
"form": form,
"formset": formset,
}
if request.method == "POST":
#print(request.POST)
if form.is_valid() and formset.is_valid():
parent = form.save(commit=False)
parent.user = request.user
parent.save()
#recipe ingredients
for form in formset:
child = form.save(commit=False)
if form.instance.name.strip() == '':
pass
else:
child.recipe = parent
child.save()
else:
form = RecipeForm(request.POST or None)
formset = RecipeIngredientFormset()
return render(request, "recipes/create.html", context)
create.html
{% load crispy_forms_tags %}
<form action='/recipes/create/' method="POST" >
<!-- MAIN RECIPE FORM-->
{% csrf_token %}
<div class='row'>
{% for recipe in form %}
<div class="col-6 col-md-3 py-2">
{{ recipe|as_crispy_field }}
</div>
{% endfor %}
<div>
<!--RECIPE INGREDIENTS - WHERE CSS ISSUE IS -->
{% if formset %}
<h3>Ingredients</h3>
{{ formset.management_form|crispy }}
<div id='ingredient-form-list'>
{% for ingredient in formset %}
<div class='ingredient-form'>
{% crispy ingredient %}
</div>
{% endfor %}
</div>
<div id='empty-form' class='hidden'>{% crispy formset.empty_form %}</div>
<button class="btn btn-success" id='add-more' type='button'>Add more ingredients</button>
{% endif %}
</div>
<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)
}
</script>
问题如下图所示,这会创建另一个表单,而不仅仅是添加字段:
如果我使用 {{ formset.empty_form|crispy }}
而不是 {% crispy formset.empty_form %}
脚本可以正常工作,但是 CSS 没有附加到表单。
必须结合使用这两种方法才能工作,下面是对问题代码的更改:
create.html
<div>
<!--RECIPE INGREDIENTS-->
{% if formset %}
<h3 class="mt-4 mb-3">Ingredients</h3>
{{ formset.management_form|crispy }}
<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 mt-4">
<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>
</div>
<button class="btn btn-success my-2" id='add-more' type='button'>Add more ingredients</button>
{% endif %}
</div>
<div>