3

I have a custom form that uses ajax submit successfully. However, form validation is not working as expected. Fields marked as required are being highlighted in red, but other fields that do not pass validation are not being marked.

function my_custom_form($form, &$form_state, $nid=NULL) {
  global $user;
  $form['nid'] = array(
    '#type' => 'hidden',
    '#value' => $nid,
  );
  $form['#attributes'] = array('enctype' => "multipart/form-data");
  $form['video_fid'] = array(
    '#title' => t('Video'),
    '#type' => 'managed_file',
    '#description' => t('Upload your video.'),
    '#default_value' => variable_get('video_fid', ''),
    '#upload_location' => 'public://video/',
    '#upload_validators' => array(
      'file_validate_extensions' => array('mp4'),
      // Pass the maximum file size in bytes
      'file_validate_size' => array(MAX_CUSTOM_UPLOAD_FILE_SIZE),
    ),
    '#progress indicator' => 'bar',
    '#required' => true,
  );
  $form['title'] = array(
    '#title' => t('Title'),
    '#type' => 'textfield',
    '#description' => t('Video title, ex. "First Attempt" etc.'),
    '#default_value' => '',
    '#size' => 60,
    '#maxlength' => 64,
    '#required' => true,
  );
  $form['notes'] = array(
    '#title' => t('Notes'),
    '#type' => 'textarea',
    '#description' => t('notes about this video'),
  );
  $form['team_message'] = array(
    '#markup' => 'Your team: <strong>'.$user->name.'</strong> (you)<br/>',
  );
  $form['teammates'] = array (
    '#type' => 'textfield',
    '#autocomplete_path' => 'my_custom/teammate/autocomplete',
    '#description' => t('Type each teammate\'s username, separated by commas'),
    '#element_validate' => array('_my_custom_form_team_validate'),
    '#ajax' => array(
      'callback' => 'my_custom_form_validate_teammates',
      'wrapper' => 'teammates-error',
      'method' => 'html',
      'effect' => 'none',
      'progress' => array (
    'message' => NULL,
      ),
    ),
  );
  $form['teammates_verify'] = array (
    '#type' => 'markup',
    '#prefix' => '<div id="teammates-error">',
    '#suffix' => '</div>'
  );
  if ('' != _are_teammates_valid($form_state['values']['teammates'])) {
    $form['teammates']['#error'] = true;
    $form['teammates_verify']['#markup'] = '<span class="error">'.t('The following are not valid users: ')._are_teammates_valid($form_state['values']['teammates']).'<pre>'.print_r($form_state,1).'</pre></span>';
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#ajax' => array(
      'callback' => 'my_custom_form_callback',
      'wrapper' => 'level-form',
      'method' => 'replace',
      'effect' => 'fade',
      'name' => 'submit',
    ),
    '#value' => t('Submit'),
  );
  return $form;
}
function _my_custom_form_team_validate($element, &$form_state) {
  if (!empty($element['#value']) && '' != _are_teammates_valid($element['#value'])) {
    form_error($element, t('!teammates are not valid user. Please check spelling.', array('!teammates' => _are_teammates_valid($element['#value']))));
  }
}
function my_custom_form_validate($form,&$form_state) {
  // validate file upload
  // validate teammate list
  if (''!=_are_teammates_valid($form_state['values']['teammates'])){
    form_set_error('teammates');
  }
}
function my_custom_form_validate_teammates($form, &$form_state) {
  if ('' != _are_teammates_valid($form_state['values']['teammates'])) {
    form_set_error('teammates');
  }
  return $form['teammates_verify'];
}
function _are_teammates_valid($teammates) {
  if ('' != $teammates) {
    $team = drupal_explode_tags($teammates);
    $bad_usernames = ',';
    foreach($team as $possible_teammate) {
      $teammate = user_load_by_name($possible_teammate);
      if (!$teammate) {
        $bad_usernames += $possible_teammate;
      }
    }
    if (2 < strlen($bad_usernames)) {
      form_set_error('teammates',t('The following are not valid users: ').substr(2,$bad_usernames).t('. Please recheck spelling.'));
    }
  }
}
function my_custom_form_callback($form, $form_state) {
  my_custom_form_validate($form,$form_state);
  if (form_get_errors()) {
    return $form;
  }

  global $user;
  $nid = $form_state['values']['nid'];
  // $account = user_load($user->uid);
  $file = file_load($form_state['values']['video_fid']);
  if (!$file) {
    $pre['message'] = array(
      '#markup' => '<p class="error">'.t('Please upload file first').'</p>',
    );
    return $pre+$form;
  }
  $file->status = FILE_STATUS_PERMANENT;
  file_save($file);
  // TODO change this file_usage_add() call to reflect current module ownership - see http://api.drupal.org/api/drupal/includes!file.inc/function/file_usage_add/7
  file_usage_add($file, 'user', 'user', $user->uid);

  if (!file_save($file)) {
    return t('There was an error uploading the file');
  }

  $team = array_map('user_load_by_name',drupal_explode_tags($form_state['values']['teammates']));
  array_unshift($team, $user);
  foreach ($team as $teammate) {
    $vnid = _make_video_node($teammate->uid,$form_state['values']['title'],$form_state['values']['notes'],$form_state['values']['nid'],$file);
    _make_completion_node($teammate->uid, $form_state['values']['title'],$form_state['values']['notes'],$vnid,$form_state['values']['nid']);
  }

  if (_my_custom_form_completes($nid, $team)) {
    drupal_set_message('Level Completed');
    return '<h2>'.t('Level completed!').'</h2>';
  }
  drupal_set_message('Error Completing Level');
  return '<h2>'.t('Error Completing Level').'</h2>';
}

1 Answer 1

3

It would be helpful if you could write which fields actually get validated. But from the code I guess the only validation working is

function my_custom_form_validate($form,&$form_state) {
  // validate file upload
  // validate teammate list
  if (''!=_are_teammates_valid($form_state['values']['teammates'])){
    form_set_error('teammates');
  }
}

It looks like you have created many different validation functions. But the hook validate is per form and not per field. So if was to wrote a validation function for your form I would try this:

function my_custom_form_validate($form,&$form_state) 
{
   if (_are_teammates_valid($form_state['values']['your form field'])!='')
   {
     form_set_error('teammates');t('Your error message.'));
   }          
   if ($form_state['values']['your form field']!='What it should be')
   {
     form_set_error('your form field');t('Your error message.'));
   }          

   // ... and so on...
 }

You basically create one validate function and check each field in "$form_state['values']" and set the correct error message.

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.