0

I'm trying to add an AJAX callback to a list field with multiple selection enabled. This works properly on its own, but if I add an image field, the form will throw errors when 2 or more fields are selected.

Here's my setup:

  1. Blank installation of Drupal 7 + image + list modules.
  2. Create a "Sample" (machine name: sample) content type.
  3. Add an image field ("Image").
  4. Add a list field with possibility to select unlimited values ("List").
  5. Enable the custom module below.
  6. Try creating a new node and select 2 options in the "List" field. This will throw the following AJAX validation error:
    "An illegal choice has been detected. Please contact the site administrator."

Code:

//
// File: sample.module
//
function sample_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case 'sample_node_form':
      $form['#id'] = $form_id;
      $form['field_list'][LANGUAGE_NONE]['#ajax'] = array(
        'method' => 'replaceWith',
        'wrapper' => $form_id,
        'callback' => 'sample_form_alter_ajax',
      );
      break;
  }
}
function sample_form_alter_ajax($form, $form_state) {
  // Of course, my logic will be added here.
  return $form;
}

//
// File: sample.info
//
name = Sample
description = Sample
package = Sample
core = 7.x
version = 7.x-1.0

Am I doing something wrong or is this a bug in image.module?
Is there anything I need to change in the way I set up my AJAX callback?

Thanks!

Update 1

The problem can be further narrowed to any file upload field. Here's a sample module that can be used standalone to replicate the issue. No need for creating content types.

sample.module file content:

function sample_menu() {
  $items['sample'] = array(
    'title' => 'Sample page',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('sample_page_form'),
    'access callback' => TRUE,
  );

  return $items;
}

function sample_page_form($form, &$form_state) {
  $form['#id'] = 'sample-page-form';
  $form['list'] = array(
    '#type' => 'select',
    '#title' => t('Select something'),
    '#options' => array(
      'option1' => t('Option 1'),
      'option2' => t('Option 2'),
      'option3' => t('Option 3'),
    ),
    '#multiple' => TRUE,
    '#ajax' => array(
      'method' => 'replaceWith',
      'wrapper' => $form['#id'],
      'callback' => 'sample_page_form_ajax',
    ),
  );
  $form['image'] = array(
    '#type' => 'file',
    '#title' => t('Test fileupload field'),
  );

  $form['actions'] = array('#type' => 'actions');
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit the form',
  );

  return $form;
}

function sample_page_form_ajax($form, $form_state) {
  return $form;
}

Update 2

This seems to work properly if the field type is changed to checkboxes instead. Not a real solution though, just a workaround.

9
  • Can you share your ajax code here?
    – Cool
    Commented Jul 28, 2016 at 11:39
  • Thanks for the message. I isolated the problem in the code above - the AJAX code is not causing the issue 100%. The problem occurs even when the AJAX callback just returns the same form. Commented Jul 28, 2016 at 12:08
  • js error is triggering when u select multiple items from select box. right?
    – Cool
    Commented Jul 28, 2016 at 12:10
  • Yes, that is correct. Commented Jul 28, 2016 at 12:12
  • did you check what value is coming for that field in validate function?
    – Cool
    Commented Jul 28, 2016 at 12:22

1 Answer 1

0

After additional testing, this seems to be a bug in Drupal core that affects only the select form elements.

Workaround is to change the field type to checkboxes. Everything else can stay the same. Values are then passed properly and everything works OK even with multiple file upload fields added to the same form.

Also the validation and submit handlers work as expected in this case.

I created a ticket for Drupal core here.

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.