i am trying to write my own module. i didnt like the way taxonomy lists categories so i added 2 selectboxes and update the child with XAJAX. everything works fine. but if i submit the form i got an error saying :

An illegal choice has been detected. Please contact the site administrator.

i dont know how to fix it.
so here is the link for testing: http://www.takasedelim.com/node/add/takas
and code:

function takas_form() {    
    $parent_options     = takas_get_parents();
    $keys               = array_keys($parent_options);
    $children_options   = takas_get_children($parent_options);
    $keys2              = array_keys($children_options);

    $form['title'] = array('#type' => 'textfield','#title' => t('Title'),'#required' => TRUE,'#weight' => -10);

    $form['body_filter']['body'] = array('#type' => 'textarea', '#title' => t('Body'), '#default_value' => $node->body, '#rows' => 12, '#required' => TRUE,'#weight' => -9);
    $form['body_filter']['format'] = filter_form($node->format);
    
    $form['pid'] = array(
    '#type' => 'select',
    '#title' => 'Parent',
    '#options' => $parent_options,
    '#default_value' => $keys[0],
    '#attributes' => array('onChange' => 'xajax_takas_update_select(xajax.getFormValues("node-form"));'),
    '#required' => true
    );
    $form['tid'] = array(
    '#type' => 'select',
    '#title' => 'Child',
    '#options' => $children_options,
    '#default_value' => $keys2[0],
    '#required' => true
    );
    
    $form['debug'] = array(
    '#type' => 'markup',
    '#value' => '<a href="#" onClick=\'xajax_takas_debug(xajax.getFormValues("node-form"));\'>Show Form Values</a>'
    );

    return $form;
}

any ideas would be appreciated! thanks
(i am using Drupal 4.7.2)

Comments

mtinay’s picture

i should add... this happens only if u change the first selectbox. here are functions i used for getting values for options

function takas_get_parents($vid=2) {
    $options = array();
    foreach (taxonomy_get_tree($vid,0,-1,1) as $term){
        $options[$term->tid] = $term->name;
    }
    return $options;
}

function takas_get_children($tid){
    // if $tid is an array, get only the first value
    if(is_array($tid)){
        $keys = array_keys($tid);
        $tid = $keys[0];
    }
    $options = array();
    foreach (taxonomy_get_tree(2,$tid) as $term){
        $options[$term->tid] = $term->name;
    }
    return $options;
}

function takas_update_select($values){
    $options = takas_get_children($values['edit']['pid']);
    $response = new xajaxResponse();

    $response->addAssign('edit-tid','options.length',0);
    while (list($values,$name)=each($options)) {
        $script = " document.getElementById('edit-tid').options.add(new Option('".$name."', '".$values."')); " ;
        $response->addScript($script);
    }
    $response->addScript("document.getElementById('edit-tid').options[0].selected=TRUE;");
    return $response;
}
chx’s picture

Form API has a choice checker. For AJAX applciations the choices may not be available beforehand, therefore there is a property called #DANGEROUS_SKIP_CHECK . As the name implies, it's dangerous -- the choice checker protects you from users submitting bogus information. If you skip it, you must validate the element yourself.

Also, as a member of the security team, if I see this property used, then I will simple refuse to deal with any security holes in such a module.
--
The news is Now Public | Drupal development: making the world better, one patch at a time.

--
Drupal development: making the world better, one patch at a time. | A bedroom without a teddy is like a face without a smile.

mtinay’s picture

thanks chx ... i now can submit the form without error message

johnhanley’s picture

I just encountered this problem working with 5.x.

I have a form with a series of checkboxes. If the form sits long enough without being submitted, some of the checkbox items may have expired. Drupal throws up the error message about illegal choices, which is exactly what it's suppose to do. However, I want to display my own custom error strings. I tried to unset() the expired form elements in hook_validation(), but the error has already occurred and the hook is bypassed.

I would rather not use #DANGEROUS_SKIP_CHECK for security and future 6.x compatibility reasons, but I haven't been able to figure out another way to either suppress or handle the error myself and display my custom error messages.

Any suggestions?

johnhanley’s picture

In case somebody stumbles across this old thread the answer to my previous question is as follows:

'#validated' => TRUE

It's probably wise to use this attribute sparingly, but in my particular use case the form data might contain expired checkbox values upon submission. In other words the "illegal choice" was at one point "legal". For instance when a form is left unattended and submitted at a later time. The data is validated and the submission is allowed to fail gracefully with context messaging.