=== modified file 'includes/form.inc' --- includes/form.inc 2009-12-17 21:59:31 +0000 +++ includes/form.inc 2009-12-25 08:04:27 +0000 @@ -280,6 +280,7 @@ function form_state_defaults() { 'cache'=> FALSE, 'method' => 'post', 'groups' => array(), + 'validate_exclusively_on_button' => array(), ); } @@ -412,6 +413,7 @@ function form_state_keys_no_cache() { 'method', 'submit_handlers', 'submitted', + 'validate_exclusively_on_button', 'validate_handlers', 'values', ); @@ -786,6 +788,12 @@ function drupal_validate_form($form_id, } } + // Only keep the validate_exclusively_on_button state if there is a section + // relating to the pressed button. + if (!empty($form_state['validate_exclusively_on_button']) && !in_array($form_state['clicked_button']['#value'], $form_state['validate_exclusively_on_button'])) { + $form_state['validate_exclusively_on_button'] = array(); + } + _form_validate($form, $form_state, $form_id); $validated_forms[$form_id] = TRUE; } @@ -884,7 +892,9 @@ function _form_validate(&$elements, &$fo // Recurse through all children. foreach (element_children($elements) as $key) { - if (isset($elements[$key]) && $elements[$key]) { + // If there was no button-specific validate section specified or this + // element is inside that section then validate. + if (empty($form_state['validate_exclusively_on_button']) || (isset($elements[$key]['#validate_exclusively_on_button']) && in_array($form_state['clicked_button']['#value'], $elements[$key]['#validate_exclusively_on_button']))) { _form_validate($elements[$key], $form_state); } } @@ -967,8 +977,9 @@ function form_execute_handlers($type, &$ if (isset($form_state[$type . '_handlers'])) { $handlers = $form_state[$type . '_handlers']; } - // Otherwise, check for a form-level handler. - elseif (isset($form['#' . $type])) { + // Otherwise, check for a form-level handler. If a per-button validate is in + // effect then neither the validate nor the submit handler should fire. + elseif (isset($form['#' . $type]) && empty($form_state['validate_exclusively_on_button'])) { $handlers = $form['#' . $type]; } else { @@ -1006,7 +1017,7 @@ function form_execute_handlers($type, &$ * @param $message * The error message to present to the user. * @return - * Return value is for internal use only. To get a list of errors, use + * Return value is for internal use only. To get a list of errors, use * form_get_errors() or form_get_error(). */ function form_set_error($name = NULL, $message = '') { @@ -1170,6 +1181,10 @@ function form_builder($form_id, $element // later. unset($element['#sorted']); } + if (isset($element['#validate_exclusively_on_button'])) { + $element[$key]['#validate_exclusively_on_button'] = $element['#validate_exclusively_on_button']; + $form_state['validate_exclusively_on_button'] = array_merge($form_state['validate_exclusively_on_button'], $element['#validate_exclusively_on_button']); + } $element[$key] = form_builder($form_id, $element[$key], $form_state); $count++; } @@ -3261,7 +3276,7 @@ function batch_process($redirect = NULL, $batch =& batch_get(); drupal_theme_initialize(); - + if (isset($batch)) { // Add process information $process_info = array( @@ -3276,7 +3291,7 @@ function batch_process($redirect = NULL, ); $batch += $process_info; - // The batch is now completely built. Allow other modules to make changes to the + // The batch is now completely built. Allow other modules to make changes to the // batch so that it is easier to reuse batch processes in other enviroments. drupal_alter('batch', $batch); === modified file 'modules/field/field.form.inc' --- modules/field/field.form.inc 2009-12-21 13:47:31 +0000 +++ modules/field/field.form.inc 2009-12-25 07:07:21 +0000 @@ -227,6 +227,7 @@ function field_multiple_value_form($fiel '#field_name' => $field_name, '#language' => $langcode, ); + $field_elements[$field_name]['#validate_exclusively_on_button'] = array(t('Add another item')); } } } === modified file 'modules/poll/poll.module' --- modules/poll/poll.module 2009-12-14 20:38:15 +0000 +++ modules/poll/poll.module 2009-12-25 07:08:53 +0000 @@ -234,6 +234,7 @@ function poll_form($node, &$form_state) // Add a wrapper for the choices and more button. $form['choice_wrapper'] = array( '#tree' => FALSE, + '#validate_exclusively_on_button' => array(t('More choices')), '#weight' => -4, '#prefix' => '