question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support Grouped Choice Sets in CheckboxSelectMultiple

See original GitHub issue
  • Package version: 1.6.1
  • Django version: 1.9 (/all)
  • Python version: 2.7 (/all)

Description:

After Django 1.7, the choice widgets all support nested choices (which render as OPTGROUP tags in the HTML for select widgets, and as nested lists for the checkboxselect widgets). See this django issue for more discussion. In crispy_forms, the default multiple select option works as expected, but the CheckBoxSelectMultiple option breaks, causing the choice to be rendered as an escaped python __repr__.

Screenshot Example

screen shot 2017-02-08 at 4 03 24 pm

Example Django Crispy Forms code

(Used to generate the screenshot above)

from django import forms
from django.forms.widgets import CheckboxChoiceInput
from crispy_forms.layout import *
from crispy_forms.helper import *
from django.template import Template, Context

class MyForm(forms.Form):
    checkboxselectmultiple = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
        choices=(
            ('group1', (
                ('choice1', 'choice1'),
                ('choice2', 'choice2'),
            )),
            ('group2', (
                ('choice1', 'choice1'),
                ('choice2', 'choice2'),
            )),
        )
    )
    multiple = forms.MultipleChoiceField(
        choices=(
            ('group1', (
                ('choice1', 'choice1'),
                ('choice2', 'choice2'),
            )),
            ('group2', (
                ('choice1', 'choice1'),
                ('choice2', 'choice2'),
            )),
        )
    )

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Field('checkboxselectmultiple'),
            Field('multiple'),
        )



template_string = '''\
{% load crispy_forms_tags %}
<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    </head>
    <body>
        <h1>Crispy</h1>
        {% crispy form 'bootstrap3' %}
        <h1>Default</h1>
        {{ form }}
    </body>
</html>
'''

with open('/tmp/foo.html', 'w') as f:
    f.write(Template(template_string).render(context=Context({'form': MyForm()})))
import os; os.system('open /tmp/foo.html')

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:6

github_iconTop GitHub Comments

2reactions
SFr682kcommented, Jan 4, 2021

EDIT 2021-01-04: Fixed implementation of the optgroups template tag for compatibility with non-string choice values


I’ve found a possible solution using the (undocumented) ChoiceWidget.optgroups(name, value, attrs=None) function (see https://docs.djangoproject.com/en/2.2/_modules/django/forms/widgets/):

  1. Write a custom template tag to call the function:
@register.filter
def optgroups(field):
    values = tuple(str(val) for val in field.value()) if isinstance(field.value(), (list, tuple)) else (str(field.value()),)
    attrs = field.field.widget.attrs or {}

    return field.field.widget.optgroups(field.html_name, values, attrs)
  1. Adapt the for loop in fields/checkboxselectmultiple.html (e.g. for the bootstrap4 template pack):
{% for group, options, index in field|optgroups %}
  <!-- TODO: Proper formatting of the group label -->
  {% if group %}{{ group }}{% endif %}
  {% for o in options %}
    <div class="{% if use_custom_control %}custom-control custom-checkbox {% if inline_class %}custom-control-inline{% endif %}{% else %}form-check {% if inline_class %}custom-control-inline{% endif %}{% endif %}">
      <input type="checkbox" id="id_{{ o.name }}_{{ o.index }}"
             class="{% if use_custom_control %}custom-control-input{% else %}form-check-input{% endif %} {% if field.errors %}is-invalid{% endif %}"
             {% if o.selected %}checked="checked"{% endif %} name="{{ o.name }}" value="{{ o.value }}"
             {% if field.field.disabled %}disabled="true"{% endif %} {{ o.attrs|flatatt }}>
        <label class="{% if use_custom_control %}custom-control-label{% else %}form-check-label{% endif %}" for="id_{{ o.name }}_{{ o.index }}">
          {{ o.label }}
        </label>
        {% if field.errors and forloop.parentloop.last and forloop.last and not inline_class %}
          {% include 'bootstrap4/layout/field_errors_block.html' %}
        {% endif %}
      </div>
    </div>
  {% endfor %}
{% endfor %}
  1. Adapt fields/radioselect.html (similar to 2.)
2reactions
lucaswimancommented, Feb 9, 2017

Do you happen to be itching to take it on?

Sure. I’ll try to submit a PR for this if I get time in the next few weeks. It’s fairly straightforward to fix by overriding the checkboxselectmultiple.html, so it’s not an urgent fix.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Django form choices groupby with CheckboxSelectMultiple ...
I have set up a choice field in a django form similar to another SO question. However, I would like to make it...
Read more >
Bountysource
Support Grouped Choice Sets in CheckboxSelectMultiple. ... Help and Information. Frequently Asked Questions · Bugs and Feature Requests · Fees ...
Read more >
Using CheckboxSelectMultiple - Google Groups
What I would like to do is use a CheckboxSelectMultiple for this field. ... How can I set this up so that I...
Read more >
Widgets - Django documentation
CheckboxSelectMultiple, choices=FAVORITE_COLORS_CHOICES, ). See the Built-in widgets for more information about which widgets are available and which ...
Read more >
ModelMultipleChoiceField CheckboxSelectMultiple Select a ...
That choice is not one of the available choices-django. ... that i should override the __init__ in forms, but I'm new at Django,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found