In my drupal module, I want to dynamically add values to my select list. I also write them to the database. After it is added to the select and written to the db, I sort the options of the list alphabetically.

No problem at all, but whenever I add a value that will be the last one in the list (say zebra), and I select it right away, I get an "illegal choice detected" error. Why is this and how do I fix it?

Code when creating my form:

   $form['acategory_text'] = array(
      '#type' => 'textfield',
      '#title' => t('Nieuwe categorie'),
      '#size' => 25,
      '#maxlength' => 31,
      '#attributes' => array(
        'class' => array('textfield'),

$form['acategory_button'] = array(
  '#type' => 'button',
  '#value' => t('+'),
  '#ajax' => array(
    'callback' => 'new_acategory_callback', 
    'wrapper' => 'orderapp',
    'method' => 'replace',
  '#attributes' => array(
    'class' => array('button'),

$form['store_appcategories'] = array(
  '#type' => 'select',
  '#default_value' => '',
  '#title' => 'Order.app categorieën',
  '#multiple' => TRUE,
  '#options' => get_values('ac_id','appcategory',appcategories_load_multiple(FALSE, array('sid'=>$id))),
  '#prefix' => '<div class="formselect" id="appcat">',
  '#suffix' => '</div>',
  '#size' => 7,
  '#ajax' => array(
    'callback' => 'get_mapped_categories_callback', 
    'wrapper' => 'orderapp',
    'method' => 'replace',

Callback method:

function new_acategory_callback($form, &$form_state) {
  $newappcat = $form_state['values']['acategory_text'];

  $id = $form_state['values']['id'];
  $entity = entity_create('appcategories', array('sid' => $form_state['values']['id'], 'appcategory' => $newappcat));
  entity_save('entity_test', $entity);

  $form['store_appcategories']['#options'][] = $newappcat;

  usort($form['store_appcategories']['#options'],create_function('$a,$b','return strcasecmp($a,$b);'));

  $form_state['rebuild'] = TRUE;
  return $form;

1 Answer 1


You need to build up the correct options directly in your form builder function, not in the ajax callback.

You can for example do so by converting your button to a submit type, add a specific #submit callback function, and then add something to $form_state and trigger a $form rebuild. In your form builder function you can then look into $form_state and build up the $options accordingly.

Logic always needs to be in the form builder/submit callbacks, the only thing that the ajax callback needs to care about is which part(s) of the form need(s) to be returned. The easiest way to correctly implement ajax in most cases is to build the form without ajax (which will just work with the method described above) and then add #ajax on top of it, once it works without.

You also don't need to set $form_state['rebuild'] in your ajax callback that only has an effect in the submit callback.

  • This will probably the answer. I will check it out tomorrow :) Thanks!
    – RienK
    Mar 8, 2012 at 18:04

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.