@@ -245,18 +245,14 @@ form.helper.layout.extend([
245
245
])
246
246
```
247
247
248
- ### Conditionally-required fields
248
+ ### Conditionally show/hide fields
249
249
250
250
` 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
252
252
chooses to sign up to a newsletter (examples below).
253
253
254
254
You can apply this logic to ` field ` , ` div ` , and ` fieldset ` elements.
255
255
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
-
260
256
** Field example:**
261
257
262
258
``` python
@@ -296,35 +292,6 @@ class ExampleForm(TbxFormsMixin, forms.Form):
296
292
),
297
293
)
298
294
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
-
328
295
```
329
296
330
297
** Container example:**
@@ -349,6 +316,76 @@ Layout(
349
316
)
350
317
```
351
318
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
+
352
389
## Customising behaviour
353
390
354
391
### Highlight required fields instead of optional ones
0 commit comments