Skip to content

Commit 0df94b6

Browse files
committed
Split conditional fields docs to make it clearer that using conditional_fields_to_show_as_required() is not required.
1 parent d4de95e commit 0df94b6

File tree

1 file changed

+72
-35
lines changed

1 file changed

+72
-35
lines changed

README.md

Lines changed: 72 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -245,18 +245,14 @@ form.helper.layout.extend([
245245
])
246246
```
247247

248-
### Conditionally-required fields
248+
### Conditionally show/hide fields
249249

250250
`tbxforms` can show/hide parts of the `layout` depending on a given value. For
251-
example, you could show (and require) an email address field only when the user
251+
example, you could show an email address field only when the user
252252
chooses to sign up to a newsletter (examples below).
253253

254254
You can apply this logic to `field`, `div`, and `fieldset` elements.
255255

256-
Note: any field names included within the
257-
`conditional_fields_to_show_as_required()` method will appear on the frontend
258-
as required, though will technically be `required=False`.
259-
260256
**Field example:**
261257

262258
```python
@@ -296,35 +292,6 @@ class ExampleForm(TbxFormsMixin, forms.Form):
296292
),
297293
)
298294

299-
@staticmethod
300-
def conditional_fields_to_show_as_required() -> [str]:
301-
# Non-required fields that should show as required to the user.
302-
return [
303-
"email",
304-
]
305-
306-
def clean(self):
307-
cleaned_data = super().clean()
308-
newsletter_signup = cleaned_data.get("newsletter_signup")
309-
email = cleaned_data.get("email")
310-
311-
# Fields included within `conditional_fields_to_show_as_required()` will
312-
# be shown as required but not enforced - i.e. they will not have the
313-
# HTML5 `required` attribute set.
314-
# Thus we need to write our own check to enforce the value exists.
315-
if newsletter_signup == "yes" and not email:
316-
raise ValidationError(
317-
{
318-
"email": "This field is required.",
319-
}
320-
)
321-
# The tbxforms JS will attempt to clear any redundant data upon submission,
322-
# though it is recommended to also handle this in your clean() method.
323-
elif newsletter_signup == "no" and email:
324-
del cleaned_data['email']
325-
326-
return cleaned_data
327-
328295
```
329296

330297
**Container example:**
@@ -349,6 +316,76 @@ Layout(
349316
)
350317
```
351318

319+
#### Show conditional fields as required
320+
321+
Conditional fields must be optional (`required=False`) as they are not always
322+
visible, but it can be useful to show them as required to the user.
323+
324+
To do this, use the `conditional_fields_to_show_as_required()` method:
325+
326+
```python
327+
from django import forms
328+
from django.core.exceptions import ValidationError
329+
from tbxforms.choices import Choice
330+
from tbxforms.forms import TbxFormsMixin
331+
from tbxforms.layout import Field, Layout
332+
333+
class ExampleForm(TbxFormsMixin, forms.Form):
334+
NEWSLETTER_CHOICES = (
335+
Choice("yes", "Yes please", hint="Receive occasional email newsletters."),
336+
Choice("no", "No thanks"),
337+
)
338+
339+
newsletter_signup = forms.ChoiceField(
340+
choices=NEWSLETTER_CHOICES
341+
)
342+
343+
email = forms.EmailField(
344+
widget=forms.EmailInput(required=False)
345+
)
346+
347+
def __init__(self, *args, **kwargs):
348+
super().__init__(*args, **kwargs)
349+
self.helper.layout = Layout(
350+
# Add our newsletter sign-up field.
351+
Field.text("newsletter_signup"),
352+
353+
# Add our email field and define the conditional logic.
354+
Field.text(
355+
"email",
356+
data_conditional={
357+
"field_name": "newsletter_signup", # Field to inspect.
358+
"values": ["yes"], # Value(s) to cause this field to show.
359+
},
360+
),
361+
)
362+
363+
@staticmethod
364+
def conditional_fields_to_show_as_required() -> [str]:
365+
# Non-required fields that should show as required to the user.
366+
return [
367+
"email",
368+
]
369+
370+
def clean(self):
371+
cleaned_data = super().clean()
372+
newsletter_signup = cleaned_data.get("newsletter_signup")
373+
email = cleaned_data.get("email")
374+
375+
# Fields included within `conditional_fields_to_show_as_required()` will
376+
# be shown as required but not marked as required. Therefore, we need to
377+
# write our own check to enforce the value exists.
378+
if newsletter_signup == "yes" and not email:
379+
raise ValidationError(
380+
{
381+
"email": "This field is required.",
382+
}
383+
)
384+
385+
return cleaned_data
386+
387+
```
388+
352389
## Customising behaviour
353390

354391
### Highlight required fields instead of optional ones

0 commit comments

Comments
 (0)