Проблема с отображением желаемого состояния проверки флажка с помощью bootstrap5 для формы модели django с m2m-полем и виджетом checkboxselectmultiple
У меня есть checkboxselectmultiple на поле m2m модели в ModelForm, которое является обязательным - это означает, что по крайней мере один из вариантов должен быть выбран. Я использую класс boostrap5 was-validated на моей форме:
<form method="POST" action="{{ request.path }}" {% if attempt_submit %}class="was-validated"{% endif %}>
Этот вопрос о том, как валидация отображается на моей форме с bootstrap5. Должна быть красная рамка и красный цвет, если проверка не прошла, зеленая рамка и галочка, если прошла. Однако, для моих флажков, если у меня нет ни одного выбранного (а все остальное на форме подтверждено), форма показывает каждый флажок зеленым, а не красным. Тем не менее, форма знает, что она недействительна, поскольку фокус страницы возвращается к области флажка, чтобы показать пользователю, что нужно исправить (и это не проходит form.is_valid() в views.py.
Почему эти ярлыки и поля все еще отображаются зелеными, и как я могу показать их красными, пока я не выберу один и он не станет действительным?
После этого поста я попробовал добавить
{% if form.sales_location.field.required %}required{% else %}form.sales_location.field.required=""{% endif %}
в чекбокс <input>, но тогда каждое поле является обязательным, и если я выбираю одно, остальные опции остаются красными - как будто каждая опция должна быть выбрана для проверки формы. Должен ли я сделать это в любом случае, а затем добавить что-то еще (JS?), чтобы отключить это?
Не уверен, какой именно код было бы полезно увидеть...
в models.py это поле:
sales_location = models.ManyToManyField(SalesLocation, verbose_name="Where do you sell your products? (select all that apply)" )
в файле forms.py
model = AssessmentProfile
fields = [
'sales_location',
...
]
widgets = {
'sales_location': forms.CheckboxSelectMultiple(attrs={
'class': 'form-check',}),
}
Я добавляю это, потому что я прочитал этот пост о том, чтобы убедиться, что я использую `ModelMultipleChoiceField' - но я предполагаю, что это уже происходит, потому что это модель формы.(?)
Возможно, самое важное, в шаблоне thisform.html, вот как я вручную добавляю этот элемент формы:
<div class="field-wrapper">
{{ form.sales_location.label_tag }}
<ul id="id_sales_location" class="form-check">
{% for pk, choice in form.sales_location.field.widget.choices %}
<li>
<input {% for location in location_qs %}{% if location == pk %}checked='checked'{% endif %}{% endfor %}
name="sales_location" class="form-check-input" type="checkbox" value="{{ pk }}" id="id_sales_location_{{forloop.counter0}}"
{% if already_submitted %}disabled="disabled"{% endif %}>
<label class="form-check-label" for="id_sales_location_{{forloop.counter0}}">
{{ choice }}
</label>
</li>
{% endfor %}
</ul>
</div>
Кроме того, я пробовал обновить css, чтобы вручную форматировать красный цвет, но думаю, что это не решает корень проблемы, плюс, я все равно не смог сделать это успешно
Спасибо, что посмотрели и за любые предложения.
В конце концов, я использовал javascript для решения этой проблемы.
Я обновил шаблон формы
<div class="field-wrapper">
{{ form.sales_location.label_tag }}
<ul id="id_sales_location" class="form-check">
{% for pk, choice in form.sales_location.field.widget.choices %}
<li>
<input {% for location in location_qs %}{% if location == pk %}checked='checked'{% endif %}{% endfor %}
name="sales_location" class="form-check-input" type="checkbox" value="{{ pk }}" id="id_sales_location_{{forloop.counter0}}"
{% if not form.sales_location.field.required %} {% else %} required {% endif %}
{% if already_submitted %}disabled="disabled"{% endif %}>
<label class="form-check-label" for="id_sales_location_{{forloop.counter0}}">
{{ choice }}
</label>
</li>
{% endfor %}
</ul>
</div>
добавить required к вводу, если флажок является обязательным. Это позволяет всем чекбоксам отображаться красным цветом при проверке, если поле пустое.
Затем я добавил этот javascript, чтобы удалить 'required', если он отмечен.
<script>
// Select all checkboxes using querySelectorAll.
var checkboxes = document.querySelectorAll("input[type=checkbox][name=sales_location]");
checkboxes.forEach(function(checkbox) {
checkbox.addEventListener('change', function() {
for (var cb of checkboxes) {
cb.removeAttribute('required');
}
})
});
</script>
Если поле не является обязательным, ничего не меняется. Но если оно является обязательным, то атрибут required на <input> исчезает и все флажки отображаются зелеными, чего я и хотел.
Это не идеально, потому что если флажки снимаются, они не меняют цвет на красный. Таким образом, я делаю грязное предположение, что если кто-то установил флажок, он не вернется, не снимет его и не попытается отправить. В этом случае проверка будет отображаться зеленым (и без галочки), пока Submit не будет нажата снова, но затем она приведет их обратно к этому полю, которое снова станет красным. Если вы знаете, как улучшить мой код, добавив другой случай для функции изменения (только если поле является обязательным), пожалуйста, не стесняйтесь добавить это. Будьте здоровы.