Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Here is a little extension that would allow conditional required fields to have custom validation done on them. Most my patches seem to fail to parse, so I'll paste it here:
<?php
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.327
diff -u -r1.327 form.inc
--- includes/form.inc 11 Apr 2009 22:19:44 -0000 1.327
+++ includes/form.inc 19 Apr 2009 15:43:18 -0000
@@ -780,10 +780,18 @@
// A simple call to empty() will not cut it here as some fields, like
// checkboxes, can return a valid value of '0'. Instead, check the
// length if it's a string, and the item count if it's an array.
- if ($elements['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) {
- form_error($elements, $t('!name field is required.', array('!name' => $elements['#title'])));
+ if ($elements['#required'] || isset($elements['#required_validate'])) {
+ if (isset($elements['#required_validate'])) {
+ foreach ($elements['#required_validate'] as $function) {
+ if (function_exists($function)) {
+ $function($elements, $form_state, $complete_form);
+ }
+ }
+ }
+ elseif (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0)) {
+ form_error($elements, $t('!name field is required.', array('!name' => $elements['#title'])));
+ }
}
-
// Verify that the value is not longer than #maxlength.
if (isset($elements['#maxlength']) && drupal_strlen($elements['#value']) > $elements['#maxlength']) {
form_error($elements, $t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'], '%max' => $elements['#maxlength'], '%length' => drupal_strlen($elements['#value']))));
?>
The usage is as follows:
<?php
// Form element
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Preset name'),
'#default_value' => $edit['name'],
'#maxlength' => 215,
'#required' => TRUE,
'#required_validate' => array('crc_test'),
);
// The callback
function crc_test($elements, $form_state, $complete_form) {
if (empty($elements['#value']) && !empty($form_state['values']['another field'])) {
form_error($elements, t('!name field is required.', array('!name' => $elements['#title'])));
}
}
?>
Use case, a number of different options on a form and other fields are dependent on the values of these. Using the above patch, we can flag all fields are required, but only trigger an error if missing the correct combination of values. This is fairly common with javascript based toggles.
Comment | File | Size | Author |
---|---|---|---|
#3 | form.validation.3.patch | 1.86 KB | Alan D. |
Comments
Comment #1
chx CreditAttribution: chx commentedThere is no patch so this hardly can be CNR. Your patch would be quite fine by the way. I cant see the use for this, however -- why you cant simply use #process to copy the #value around if necessary?
Comment #2
Alan D. CreditAttribution: Alan D. commentedI can not understand how you would do this using the #process callback to trick the theme layer that the element is required and to stop the validation at the logic layer. Could you expand on this idea? Thanks.
The simplest example would be a select list with an "Other, please specify" option & matching textfield.
A simple JScript toggle can be used to hide or show the textfield, but there is no simple way to highlight the textfield as required when the "Other, please specify" option is selected. On a custom install, this can be done with JScript, but not on a generic site as the HTML for the required flag could have custom theming applied.
Regarding the patch, or lack of, I've set Eclipse up to use all of the standard CVS preferences for drupal.org, but not a single patch has passed the Bot in the last 6 months+. So I've given up on posting patches.
Comment #3
Alan D. CreditAttribution: Alan D. commented@chx Is it possible to get an 30sec overview of how you would use #process to trick the system into thinking that the element is required without actually validating it. Many thanks. I've read over the code a few times and can not figure out how this is possible.
I am finding many use cases now I'm thinking of this issue. For example, in a multistep form with prev & next submit handlers, when the fields are marked as required, you get errors trying to go back a step. Another use case is a cancel button (or another similar action), and a submit. Having standard required fields result in validation errors on the cancel action.
Comment #4
sunThis mixes two completely separate issues:
1) (Just) Marking fields as required, without requiring them to be non-empty.
2) Conditionally using optional validation handlers for fields.
3) Making multi-step forms as well as form buttons executing non-default actions work with unrelated, required fields in the form.
--
3) shouldn't be discussed here.
2) Is a valid use-case, but we want to look at this in a broader scope, and I believe that there is at least one other issue with regard to more flexible validation.
1) If you think about it, it doesn't make sense to mark a non-required field as required from a usability perspective. The only use-case that I know of is if you have a group of form items (i.e. a 'multiple' field containing multiple other fields), which are - as group - optional, but only if the user wants to fill out (add) the group of fields, one or more of the fields may be required.
Comment #5
Alan D. CreditAttribution: Alan D. commentedHi Sun
Thanks for the feedback.
#1 This is where I first started thinking that there must be an alternative and could not find one. I know that I've been surprised a couple times on Drupal sites when the required flag is missing (always due to custom validation on a split workflow within a form). In core there is a save / delete that also suffers from this issue, but I can not remember where at the moment.
#2 I'm do a search and look into it. Happy to mark this as a duplicate if these other solutions help. This is primarily focused on being able to interact with the theming of the required field, the only element outside of the elements direct control. Maybe a theming call for this chunk of HTML to allow elements to insert the required HTML themselves and to keep the markup consistent with the rest of the system.
I hit #3 in a custom shopping cart system, where having a Modify button (Eg: Modify the cart) on the checkout screen where user enters their details. This was the clients design, not ours. Workaround, changing this button to a image link (returns to another form so easily bypassed).
Comment #7
sun.core CreditAttribution: sun.core commentedComment #8
Cyberwolf CreditAttribution: Cyberwolf commentedSubscribing.
Comment #9
Bodo Maass CreditAttribution: Bodo Maass commentedSubscribing.
My use case is related the cancel action described by Alan in #3. I want a special button that allows users to save an incomplete form so that they can return to it later. The normal submit button should have full validation, but the cancel+save button should allow required fields to be empty. I think the logic described here would allow something like this, while the forms api out of the box does not.
Comment #10
Alan D. CreditAttribution: Alan D. commentedVery simple workaround that works in D7 and probably D6 (Don't overwrite any existing #pre_renders!!)
This works by tricking the theme layer that the element is required
Comment #11
iMiksuI think this is still a valid request for example cases where developers wants the element to be required in certain conditions.
Good use case would be that certain elements are required if some checkbox is checked (eq. radio "Other, write below"). After moments, I still haven't figure it out how to implement this.
Only thing I came up with was that I actually determine a callback function as string instead a TRUE/FALSE for
$element['#required']
element.When running
_form_validate()
it could check the$elements['#required']
variable type whether it's a boolean or string. If it's a string, try to call the function.Comment #12
iMiksuSorry for last post. Like always, the solutions are always found suddenly just after writing something to the issue queue :D
I found
#element_validate
:)