Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.777 diff -u -r1.777 system.module --- modules/system/system.module 26 Aug 2009 10:53:45 -0000 1.777 +++ modules/system/system.module 27 Aug 2009 21:57:36 -0000 @@ -469,7 +469,6 @@ $type['fieldset'] = array( '#collapsible' => FALSE, '#collapsed' => FALSE, - '#value' => NULL, '#process' => array('form_process_fieldset', 'ajax_process_form'), '#pre_render' => array('form_pre_render_fieldset'), '#theme_wrappers' => array('fieldset'), Index: includes/ajax.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/ajax.inc,v retrieving revision 1.7 diff -u -r1.7 ajax.inc --- includes/ajax.inc 27 Aug 2009 04:40:12 -0000 1.7 +++ includes/ajax.inc 27 Aug 2009 21:57:33 -0000 @@ -186,6 +186,9 @@ // Since some of the submit handlers are run, redirects need to be disabled. $form['#redirect'] = FALSE; + // Use the validate section handling on the clicked button (if available). + $form['#validate_section_allowed'] = TRUE; + // The form needs to be processed; prepare for that by setting a few internal // variables. $form_state['input'] = $_POST; 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 27 Aug 2009 21:57:34 -0000 @@ -705,13 +705,27 @@ // If the session token was set by drupal_prepare_form(), ensure that it // matches the current user's session. if (isset($form['#token'])) { - if (!drupal_valid_token($form_state['values']['form_token'], $form['#token'])) { + if (!drupal_valid_token($form['form_token']['#value'], $form['#token'])) { // Setting this error will cause the form to fail validation. form_set_error('form_token', t('Validation error, please try again. If this error persists, please contact the site administrator.')); } } - _form_validate($form, $form_state, $form_id); + // Allow only a portion of the form to be validated. This is only allowed if + // the #validate_section property is on a button AND a custom #submit property + // is defined. This prevents the form-level submit handlers from firing + // accidentally when a portion of the form has not been validated. + $elements = $form; + $button = isset($form_state['clicked_button']) ? $form_state['clicked_button'] : FALSE; + if ($button && !empty($form['#validate_section_allowed']) && isset($button['#validate_section']) && isset($button['#submit'])) { + foreach ($button['#validate_section'] as $section) { + $elements = $elements[$section]; + } + } + + // Validate the section of the form. + _form_validate($elements, $form_state, $form_id); + $validated_forms[$form_id] = TRUE; } @@ -768,7 +782,8 @@ * not be repeated in the submission step. * @param $form_id * A unique string identifying the form for validation, submission, - * theming, and hook_form_alter functions. + * theming, and hook_form_alter functions. Indicates that we are starting a + * new validate operation. */ function _form_validate($elements, &$form_state, $form_id = NULL) { // Also used in the installer, pre-database setup. @@ -780,6 +795,12 @@ _form_validate($elements[$key], $form_state); } } + + // Only validated elements receive a value. + if (array_key_exists('#value', $elements)) { + form_set_value($elements, $elements['#value'], $form_state); + } + // Validate the current input. if (!isset($elements['#validated']) || !$elements['#validated']) { if (isset($elements['#needs_validation'])) { @@ -827,7 +848,7 @@ // #value data. elseif (isset($elements['#element_validate'])) { foreach ($elements['#element_validate'] as $function) { - if (function_exists($function)) { + if (function_exists($function) && $function != '_form_validate') { $function($elements, $form_state, $form_state['complete form']); } } @@ -1184,7 +1205,6 @@ } } } - form_set_value($element, $element['#value'], $form_state); } /**