Index: modules/field/field.form.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/field/field.form.inc,v retrieving revision 1.23 diff -u -r1.23 field.form.inc --- modules/field/field.form.inc 27 Aug 2009 04:40:12 -0000 1.23 +++ modules/field/field.form.inc 28 Aug 2009 03:12:50 -0000 @@ -196,7 +196,8 @@ '#name' => $field_name . '_add_more', '#value' => t('Add another item'), '#attributes' => array('class' => array('field-add-more-submit')), - // Submit callback for disabled JavaScript. + '#validate' => array(), + '#validate_section' => array($field_name), '#submit' => array('field_add_more_submit'), '#ajax' => array( 'callback' => 'field_add_more_js', Index: modules/poll/poll.module =================================================================== RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v retrieving revision 1.310 diff -u -r1.310 poll.module --- modules/poll/poll.module 24 Aug 2009 00:14:21 -0000 1.310 +++ modules/poll/poll.module 28 Aug 2009 03:12:50 -0000 @@ -279,7 +279,9 @@ '#value' => t('More choices'), '#description' => t("If the amount of boxes above isn't enough, click here to add more choices."), '#weight' => 1, - '#submit' => array('poll_more_choices_submit'), // If no javascript action. + '#validate' => array(), + '#validate_section' => array('choice_wrapper'), + '#submit' => array('poll_more_choices_submit'), '#ajax' => array( 'callback' => 'poll_choice_js', 'wrapper' => 'poll-choices', Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.367 diff -u -r1.367 form.inc --- includes/form.inc 27 Aug 2009 04:40:12 -0000 1.367 +++ includes/form.inc 28 Aug 2009 03:12:50 -0000 @@ -787,7 +787,7 @@ // 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))) { + if ($elements['#required'] && !_form_validate_skip($elements, $form_state) && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) { form_error($elements, $t('!name field is required.', array('!name' => $elements['#title']))); } @@ -825,7 +825,7 @@ } // Call any element-specific validators. These must act on the element // #value data. - elseif (isset($elements['#element_validate'])) { + elseif (isset($elements['#element_validate']) && !_form_validate_skip($elements, $form_state)) { foreach ($elements['#element_validate'] as $function) { if (function_exists($function)) { $function($elements, $form_state, $form_state['complete form']); @@ -837,6 +837,36 @@ } /** + * Check if an element's validation should be skipped. + * + * This is used to skip #required and #element_validate properties but never + * properties that should be enforced by HTML, such as #maxlength or #options. + * + * @param $element + * The element whose parents will be checked to determine if this element's + * validation should be skipped. + * @param $form_state + * The form state. The 'clicked_button' property will be checked to determine + * which elements should be validated. + * @return + * Boolean TRUE if the element should not be validated. FALSE if the element + * should be validated. + */ +function _form_validate_skip($element, $form_state) { + $skip = FALSE; + if (isset($form_state['clicked_button']['#validate_section'])) { + $parents = $form_state['clicked_button']['#validate_section']; + foreach ($parents as $key => $parent) { + if ($element['#parents'][$key] != $parent) { + $skip = TRUE; + break; + } + } + } + return $skip; +} + +/** * A helper function used to execute custom validation and submission * handlers for a given form. Button-specific handlers are checked * first. If none exist, the function falls back to form-level handlers.