|
1 | 1 | """Forms for core app.""" |
2 | 2 |
|
| 3 | +from dataclasses import dataclass |
| 4 | + |
3 | 5 | import structlog |
4 | 6 | from django import forms |
5 | 7 | from django.conf import settings |
@@ -163,6 +165,61 @@ def __init__(self, message, code=None, params=None, header=None, message_class=N |
163 | 165 | self.message_class = message_class |
164 | 166 |
|
165 | 167 |
|
| 168 | +@dataclass |
| 169 | +class RichChoice: |
| 170 | + """ |
| 171 | + Data class for rich content dropdowns. |
| 172 | +
|
| 173 | + Instead of just value and text, :py:class:`RichSelect` displays multiple |
| 174 | + attributes in each item content display. Choices can be passed as an array, |
| 175 | + however with the default :py:class:`django.forms.fields.ChoiceField` |
| 176 | + you should still pass in a tuple of ``(value, RichChoice(...))`` as the |
| 177 | + tuple values are used in field validation: |
| 178 | +
|
| 179 | + choices = [ |
| 180 | + RichChoice(name="Foo", value="foo", ...), |
| 181 | + RichChoice(name="Bar", value="bar", ...), |
| 182 | + ] |
| 183 | + field = forms.ChoiceField( |
| 184 | + ..., |
| 185 | + widget=RichSelect(), |
| 186 | + choices=[(choice.value, choice) for choice in choices], |
| 187 | + ) |
| 188 | + """ |
| 189 | + |
| 190 | + #: Choice verbose text display |
| 191 | + text: str |
| 192 | + #: Choice input value |
| 193 | + value: str |
| 194 | + #: Right floated content for dropdown item |
| 195 | + description: str |
| 196 | + #: Optional image URL for item |
| 197 | + image_url: str = None |
| 198 | + #: Optional image alt text |
| 199 | + image_alt: str = None |
| 200 | + #: Error string to display next to text |
| 201 | + error: str = None |
| 202 | + #: Is choice disabled? |
| 203 | + disabled: bool = False |
| 204 | + |
| 205 | + |
| 206 | +class RichSelect(forms.Select): |
| 207 | + """ |
| 208 | + Rich content dropdown field widget type used for complex content. |
| 209 | +
|
| 210 | + This class is mostly used for special casing in Crispy form templates, it |
| 211 | + doesn't do anything special. This widget type requires use of the |
| 212 | + :py:class:`RichChoice` data class. Usage might look something comparable to: |
| 213 | +
|
| 214 | + choice = RichChoice(...) |
| 215 | + field = forms.ChoiceField( |
| 216 | + ..., |
| 217 | + widget=RichSelect(), |
| 218 | + choices=[(choice.value, choice)] |
| 219 | + ) |
| 220 | + """ |
| 221 | + |
| 222 | + |
166 | 223 | class FacetField(forms.MultipleChoiceField): |
167 | 224 | """ |
168 | 225 | For filtering searches on a facet. |
|
0 commit comments