1

I am having an annoying problem whereby $form_state['values']['region'] and $form_state['values']['country'] are being cleared when I upload an image via the managed_file field. This is causing a "...tid cannot be null" error upon DB insertion (of course because the values are now null after managed_file upload). If I disable the managed_file field everything works as it should but of course I need the upload!

I am relatively new to Drupal and thus not quite understanding why this is acting like it is. Can anyone help me out as this is driving me nuts!

My form

function myforms_company_add_form($form, &$form_state, $node) {

  $form['#prefix'] = '<div id="wrapper">';
  $form['#suffix'] = '</div>';

  if(!isset($form_state['values']['region']) && !isset($form_state['values']['country'])) {
      $selectedRegion = array_shift(taxonomy_get_parents($node->field_company_region['und'][0]['tid']))->tid;    
      $selectedCountry = $node->field_company_region['und'][0]['tid'];
    }
    else {
        $selectedRegion = $form_state['values']['region'];    
        $selectedCountry = $form_state['values']['country'];
    }

$form['region'] = array(
    '#title' => t('Region'),
    '#type' => 'select',
    '#required' => TRUE,
    '#options' => _get_region_list('region'),
    '#prefix' => '<div id="contact-selector"><div id="region-wrapper">',
    '#suffix' => '</div>',
    '#default_value' => $selectedRegion,
    '#ajax' => array(
      'callback' => 'region_ajax_callback',
      'wrapper' => 'wrapper',
     ),
  ); 

  $form['country']['wrapper'] = array(
    '#type' => 'markup',
    '#prefix' => '<div id="country-wrapper">',
    '#suffix' => '</div></div>',
  );

  if (isset($selectedRegion)) {
    $form['country'] = array(
        '#title' => t('Country'),
        '#type' => 'select',
        '#required' => TRUE,
        '#options' => _get_country_list($selectedRegion),
        '#default_value' => $selectedCountry,
        '#ajax' => array(
            'callback' => 'region_ajax_callback',
            'wrapper' => 'wrapper',
        ),
      );
   }

  $form['company_logo'] = array(
    '#title' => t('Logo'),
    '#type' => 'managed_file',
    '#upload_location' => 'public://my-files/',
    '#required' => FALSE,
    '#default_value' => $node->field_company_logo['und'][0]['fid'],
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
    '#prefix' => '<hr>',
  );

  return $form;

}

Then my callback

function region_ajax_callback($form, &$form_state) { 
  return $form;
}

2 Answers 2

1

I recently encountered the same problem. I found that data is erased in function - drupal_validate_form(). I have not fully understood why this is happening, therefore, just went bypassed the problem. I have rewritten my code so that the code section that erased the data in drupal_validate_form() is not executed.

My code:

  $managed_file_processing_fn = array_merge(
    element_info_property('managed_file', '#process', array()),
    array('ccw_managed_file_process')
  );

  $form['customization']['main']['request_design']['upload_design'] = array(
    '#type' => 'managed_file',
    '#progress_indicator' => 'bar',
    '#upload_location' => 'public://',
    '#upload_validators' => array(
      'file_validate_extensions' => array('jpg jpeg gif png zip rar tar'),
    ),
    '#states' => array(
      'visible' => array(
        ':input[name="type_of_upload"]' => array(
          array('value' => strval(CCW_GET_HELP)),
        ),
      ),
    ),
    '#process' => $managed_file_processing_fn,
    '#default_value' => $upload_design,
  );

/**
 * Process managed_file.
 */
function ccw_managed_file_process($element, &$form_state, $form) {
  // When AJAX is execute we ignore form validation.
  $element['upload_button']['#limit_validation_errors'] = FALSE;
  $element['remove_button']['#limit_validation_errors'] = FALSE;

  return $element;
}

Topic with the same problem on drupal.org: https://www.drupal.org/node/2311199

Also, I noticed that in Drupal 8 the behavior is the same.

0

Have modified function from the previous example. Filtering of non-empty values for #limit_validation_errors prevents validation errors of required but empty fields, and passes all non-empty values in form_state

function ccw_managed_file_process($element, &$form_state, $form) {
  $limit_validation_errors = array_map(
    function ($value) {
      return [$value];
    },
    array_keys(array_filter($form_state['values']))
  );
  // When AJAX is execute we ignore form validation.
  $element['upload_button']['#limit_validation_errors'] = $limit_validation_errors;
  $element['remove_button']['#limit_validation_errors'] = $limit_validation_errors;


  return $element;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.