2 abhängige Selectboxen - An illegal choice has been detected
am 18.01.2010 - 14:49 Uhr in
Hi,
ich habe mir ein kleines Modul gebaut, was 2 Selectobxen enthält. Wird in der einen Box was ausgewählt, dann erscheinen die zugehörigen Werte in der 2. Selectbox (mittel Ajax). Nach dem Abschicken sollen unter dem Formular Werte angezeigt werden und oben wiederrum beide Selectboxen. Leider funktioniert das nicht, denn sobald ich das Formular abschicke kommt folgende Fehlermeldung:
An illegal choice has been detected. Please contact the site administrator.
In der 2. Selectbox stehen dann auch gar keine Werte mehr drin, obwohl ich eigentlich eine Datenbankabfrage eingebaut habe (denn nach dem Abschicken wirkt ja Ajax nicht mehr). Ich habe dazu auch im Netz nicht so viel gefunden.
- Anmelden oder Registrieren um Kommentare zu schreiben

Source?
am 18.01.2010 - 17:46 Uhr
Hi,
ich glaube ohne den Source oder wenigstens mehr Informationen wird man dir nicht helfen können.
Du könntest den Source auch hier posten:
http://pastebin.org/
---
Viele Grüße,
Kars-T
| comm-press
hier noch der quellcode
am 19.01.2010 - 10:07 Uhr
<?php
/**
* Implementation of hook_menu
*/
function vergleich_menu(){
$items = array();
$items['vergleich'] = array(
'title' => 'Test Test Test',
'page callback' => 'vergleich_page',
'access arguments' => array('access content'),
'type' => MENU_SUGGESTED_ITEM,
);
$items['vergleich/fetch/%'] = array(
'page callback' => 'vergleich_get_items',
'access arguments' => array('access content'),
'page arguments' => array(2),
'type' => MENU_CALLBACK,
);
return $items;
}
function vergleich_page(){
$module_path = drupal_get_path('module','vergleich');
drupal_add_js($module_path.'/vergleich.js');
$db = array('name'=>'Name','vorname'=>'Vorname'); /*nur zum testen*/
$selectbox = drupal_get_form('vergleich_form',3);
$output = theme('vergleich', $db, $selectbox);
return $output;
}
/**
* Implementation of hook_theme
*/
function vergleich_theme(){
return array(
'vergleich' => array(
'template' => 'vergleich',
'arguments' => array('dbData' => NULL, 'selectbox' => NULL),
),
'vergleich_results' => array(
'template' => 'vergleich_results',
'arguments' => array('results' => NULL),
),
'vergleich_form' => array(
'arguments' => array('formular' => NULL),
)
);
}
/**
* Implementation of preprocess function
*/
function template_preprocess_vergleich($tplVars){
// Datenbank
$dbData = $tplVars['dbData'];
// Selectbox
$selectbox = $tplVars['selectbox'];
// Variablen im Template
$tplVars = $dbData;
$tplVars['manufacturer_selectbox'] = $selectbox;
}
function template_preprocess_vergleich_results($tplVars){
$tplVars['result'] = $tplVars['results'];
}
function vergleich_form($form_state,$maxColumns){
// Abfrage aller Hersteller
....
$options_manufacturer = array('-- wählen --');
while($row = db_fetch_object($res)){
$options_manufacturer[$row->hs] = $row->hs;
}
$form['#redirect'] = false;
for($i=1;$i<=$maxColumns;$i++){
$options[$i] = array();
$form['vergleich']['hs'.$i] = array(
'#type' => 'select',
'#options' => $options_manufacturer,
'#default_value' => $form_state['values']['hs'.$i],
);
// hier sollten alle Geräte nach dem abschicken in der 2. Selectbox angezeigt werden
if (!empty($form_state['values']) && !empty($form_state['values']['hs'.$i])){
$options[$i] = vergleich_get_items($form_state['values']['hs'.$i],1);
}else{
$options[$i] = array('-- wählen --');
}
$form['vergleich']['h'.$i] = array(
'#type' => 'select',
'#options' => $options[$i],
);
}
$form['vergleich']['compare'] = array(
'#type' => 'submit',
'#value' => 'vergleichen',
'#submit' => array('vergleich_form_submit'),
);
if (!empty($form_state['values'])){
$results = 'Formular abgeschickt';
}else{
$results = 'Formular noch nicht abgeschickt';
}
$form['results'] = array(
'#type' => 'item',
'#value' => theme('vergleich_results', $results),
);
return $form;
}
function vergleich_get_items($manufacturer,$type=NULL){
// DB-Abfrage - alle Geräte zu einem Hersteller
$res = db_query($query);
$data = array();
while($row = db_fetch_object($res)){
$data[] = $row;
}
return empty($type) ? drupal_json($data) : $data;
}
function vergleich_form_submit($form, &$form_state){
$form_state['storage'] = array(
$form_state['values']['h1'],
);
$form_state['rebuild'] = TRUE;
}
function theme_vergleich_form($form){
$output = '';
$output .= '<div class="selectbox-block">';
$output .= drupal_render($form['vergleich']['hs1']);
$output .= drupal_render($form['vergleich']['h1']);
$output .= '</div>';
$output .= '<div class="selectbox-block">';
$output .= drupal_render($form['vergleich']['hs2']);
$output .= drupal_render($form['vergleich']['h2']);
$output .= '</div>';
$output .= '<div class="selectbox-block">';
$output .= drupal_render($form['vergleich']['hs3']);
$output .= drupal_render($form['vergleich']['h3']);
$output .= '</div>';
$output .= '<br style="clear: both;">';
$output .= drupal_render($form);
return $output;
}
?>
Das Problem ist relativ
am 19.01.2010 - 16:20 Uhr
Das Problem ist relativ einfach erklärt, habe ich bei einem derzeitigen Projekt.
Werte, die in der Select Box nicht enthalten sind, dürfen auch nicht übertragen werden.
Wenn Du also per AJAX Select Boxen veränderst müssen diese Werte in den "#options" der Select Box stehen.
Der einfachste Weg dieses abzufangen:
Alle Werte, die möglich sind in "#options" des selects einzutragen und dann bei Aufruf des Fomulars mit AJAX / Javascript zu ersetzen / entfernen.
So was in der richtung
am 19.01.2010 - 20:22 Uhr
So was in der richtung dachte ich mir schon, aber dann müsste ich ja alle möglichen Werte schon vorher in die options eintragen, das wären bestimmt über 500 Einträge. (die ja auch alle im Quelltext stehen)
Also alle 500 Einträge in die options schreiben und dann beim Aufruf der Seite die 2. Selektbox per Javascript erstmal leeren?
genau, anders wirst du keine
am 19.01.2010 - 20:34 Uhr
genau, anders wirst du keine möglichkeit haben dieses zu ermöglichen.
ansonsten löst nur noch ein core hack in der form.inc das problem, in dem das entsprechende "form_set_error" auskommentiert, wovon ich aber abrate.
ok, ich dachte es geht doch
am 19.01.2010 - 21:06 Uhr
ok, ich dachte es geht doch irgendwie besser :-) aber danke für deine hilfe.
Options per JS dynamisch zur Validierung nachtragen
am 21.03.2013 - 11:37 Uhr
Hallo zusammen,
ich habe momentan genau das gleiche Anliegen dieses Threads und Probleme mit der Validierung.
Ich lade über eine View und Views Data Source neue Options in ein Select-Feld und benötige nun wohl
auch eine JavaScript-Funktion, um die Optionen für die Validierung der Webform nachzutragen.
Es handelt sich um Termine, die als Multi-Date-Field in einem Veranstaltungs-Content-Type eingetragen
werden. Das erste Select-Feld listet die Namen der Veranstaltungen, das zweite die zugehörigen Termine.
In meinem Fall gibt es pro Termin nur um die zehn Termine, weshalb das Nachtragen funktionieren sollte.
Übertrgen werden die Daten bisher problemlos nur kann ich eben leider das Formular nicht abschicken.
Könntet ihr mir hier evtl. eure Lösung des Problems beschreiben bzw. eine Beispiels-Funktion
schreiben mit der ich die Optionen fix hinterlegen kann?
Über eure Hilfe wäre ich wirklich sehr dankbar!
Mein Code:
$(function() {
select = $("select#edit-submitted-stuck");
select.change(function(){
$.getJSON("/vorstellungen_arg/"+$(this).attr('value'), populateTermine);
});
});
function populateTermine(data, textStatus) {
select = $("select#edit-submitted-vorstellung");
select.removeOption(/./);
for(i in data.nodes){
value = data.nodes[i].node.nodeid;
label = data.nodes[i].node.termin;
select.addOption(value, label);
}
select.val("");
}
Die JSON-Ausgabe hat folgendes Muster:
{"nodes":[{"node":{"nodeid":"vorstellung-72","termin":"03.05.2013 | 10:30"}},{"node":{"nodeid":"vorstellung-73","termin":"20.06.2013 | 10:30"}}]}