TL;DR
Consider the case where you use a checkbox to conditionally set another form element to be required or not, depending on the state of the checkbox; then:
- The red "required" asterisk is properly added/removed from the form element, depending on whether the checkbox is ticked/unticked BUT this seems to only be "cosmetic", because in actuality...
- If the form element is set to be required via
'#required' => TRUE
, then the form validation will kick in, no matter if the required attribute was removed via#states
(by unticking the checkbox) - If the form element is set to NOT be required via
'#required' => FALSE
, then the form validation will NOT kick in, no matter if the required attribute was added via#states
(by ticking the checkbox)
Describe your issue or idea
Every time that we need to conditionally present a required field in a form, we are forced to either write specific validation functions for that form, or simply settle with making these fields optional, or both. Reason: the way this currently works is that any required field that is hidden via #states
is still validated (although not used).
Bad UX: Take #2731 for example. The user enables a feature by ticking a checkbox, which reveals more fields via #states
. There is no indication that any field is required, but when the form is submitted, there is a validation error. The user now needs to go through the form again in order to fill in any required fields.
Bad DX: The way we have coded that part of the form is that we have left a mandatory field as optional. We have then added custom validation upon submit. Had we made the field required, it would go through the validation process and throw errors even when not used (when hidden via #states
). While filing a PR for #2731, I discovered a workaround where the field can still be rendered as required using #states
, but in order to not throw validation errors, we have to still use the custom validation function.
More bad DX: also while filing a PR for #2731, I discovered that when it comes to machine_name
type of fields, the workaround where the field can still be rendered as required by using #states
no longer works (validation errors get triggered). In order to not throw validation errors for #states
-hidden machine names, you also have to also set '#required' => FALSE
. So the code looks like this:
'#states' => array(
'required' => array(
'input[name="checkbox"]' => array('checked' => TRUE),
),
),
// This line is still required in order to not throw form validation errors
// when the checkbox is not ticked.
'#required' => FALSE,
Even more bad DX: this silly required/not-required code above only works half way. It only handles rendering the field as required (red asterisk). In order to have proper validation (only when the checkbox is ticked), you still need to use a custom validation function.
Steps to reproduce (if reporting a bug)
See #2731 for an actual use case. That issue will most likely be addressed sooner than this one here. In that case, try the following...
- Create a simple form with a checkbox and a text field.
- Have the text field be required.
- Also have the text field hidden via
#states
based on whether the checkbox is ticked or not. - Have the checkbox be ticked off by default (so that the required text field is hidden).
- Submit the form.
Actual behavior (if reporting a bug)
There is a validation error, telling you that the text field (which is hidden) is required.
Expected behavior (if reporting a bug)
There should be no validation errors if the required field is hidden via #states
. Validation errors should only be triggered when the field is visible.
Recent comments
BTW, this is still a problem in the D7 version (despite what that issue said), so I'm not sure this is possible. I'll have to look more closely into it.
How to order a view by its aggregated value
Hmm... I was able to reproduce this issue when I thought it would work. Wuold you mind opening an issue in the queue?
How to order a view by its aggregated value
Hi Robert. I'm looking at D7 issues about this - apparently this is possible since 10 years ago, which means the functionality is there, but there may be some issues with the way your view is...
How to order a view by its aggregated value