Drupal 7 provides a form API for constructing both simple and dynamic forms. Dynamic forms display their fields based on user interactions with the form – such as selecting an option from a select list. There are really two ways to make a dynamic form:
- by using the #ajax property to rebuild the form, with new or modified fields, as a result of user interaction; or
- by using the #states property to hide or unhide fields as a result of user interaction.
However, there is a problem. If I modify the 'Language' field in my example, making it a required field (line 4), the form's logic will fail.
Why? Because all form elements are validated when a form is submitted – even the invisible ones. Invisible fields will always be empty because the user cannot see them, and by default, if an empty required field is submitted it will fail validation. This puts the user in a situation where they get an error message, every time they try to submit the form, about a field that doesn't appear on the form.
There are several proposed solutions to solving this problem, but, as far as I know, only one that works fully. Let's start by looking at the others first.
Limit the validation errors
Before I outline this approach, I must concede that it doesn't appear to work; however, some propose this solution as the logical way to solve the problem. Two properties are key to this approach: #limit_validation_errors and #element_validate.
#element_validate takes an array of validation functions to be called to validate a particular form element (and/or its children).
The logic of this approach follows that, on submission of the form, only the specified elements will be validated by the validation functions that they, themselves, specify. Although, in my testing of this approach, I found that the presence
'#required' => TRUE,
Unset the error messages
This approach seeks to directly remove particular error messages before they get set. The function to
Use custom validation
My approach is to
'#required' => TRUE,
'' => t('- Select -'), to your options, then your field will look as if you had required it in the usual way. The final step is to add the #validate property to the appropriate button/submit element. This property takes an array of validation function names. Each function is
Then use some kind of logic to ensure your validation functions are called only when you know their corresponding elements are visible to the user.
Or…try to use #ajax
If, however, you decide, after reading this, you don't want to use