Hi to all,

i have a problem with a module that i am developing. I have a form that consists of two select lists and a table with the results. The options in the second list depend on the selection in the first list. I use an ajax_callback function to update the contents of the second list and the table results . The problem is that while i have set '#default_value' => 0 for the second list , when i change the first one, the selection appears to be the selected item index of the previous list. To be more clear , if I chose the third item in the second list and then change the first list, the contents of the second list will be updated but the third item of the new list will be selected. Here ' s my code with some comments.

function test_form($form, &$form_state) {
 $options_perifereia = perifereia_dropdown_options();
 $default_options_perifereia = isset($form_state['values']['Perifereia']) ? $form_state['values']['Perifereia'] : key($options_perifereia);
//first list
  $form['Perifereia'] = array(
    '#title' => t('Περιφέρεια'),
	'#type' => 'select',	
	'#options' => $options_perifereia,
	'#default_value' => $default_options_perifereia,
    '#description' => t('Σε ποια περιφέρεια ανήκεις?'),
	 '#ajax' => array(
            // When 'event' occurs, Drupal will perform an ajax request in the
            // background. Usually the default value is sufficient (eg. change for
            // select elements), but valid values include any jQuery event,
            // most notably 'mousedown', 'blur', and 'submit'.
            'event' => 'change',
            'callback' => 'perifereia_ajax_callback', 
            'wrapper' => 'dhmos_replace',
        ),
  );
  $options_dhmos = dhmos_options($options_perifereia[$default_options_perifereia]);
  $default_options_dhmos = isset($form_state['values']['Dhmos']) ? $form_state['values']['Dhmos'] : 0;
  $form['Dhmos'] = array(
    '#title' => t('Δήμος'),
	'#type' => 'select',
	'#prefix' => '<div id="dhmos_replace">',
    '#suffix' => '</div>',	
    '#description' => t('Σε ποιον Δήμο ανήκεις?'),
	'#options' => $options_dhmos,
    '#default_value' => 0,
	'#ajax' => array(
            // When 'event' occurs, Drupal will perform an ajax request in the
            // background. Usually the default value is sufficient (eg. change for
            // select elements), but valid values include any jQuery event,
            // most notably 'mousedown', 'blur', and 'submit'.
            'event' => 'change',
            'callback' => 'dhmos_ajax_callback',
            'wrapper' => 'results_replace',
        ),
  );
   

 $form['results'] = array(
  '#prefix' => '<div id="results_replace">',
  '#suffix' => '</div>',
  '#tree' => TRUE,
  '#theme' => 'table',
  '#header' => array(t('Κωδικός Παραλίας'), t('Όνομα Παραλίας')),
  '#rows' => table_results($options_dhmos[$default_options_dhmos]),
  
);

  return $form;
}

//function to fetch contents of the first list

function perifereia_dropdown_options() {	
	db_set_active('custom');  
 $result = db_query('SELECT distinct(kal_perifereia) FROM "FINAL_POINTS_WGS84" order by kal_perifereia')->fetchCol();
db_set_active();
return $result; 
}


//ajax callback function for the first list

function perifereia_ajax_callback($form, $form_state) {
   
  $commands = array();
	//unset($form_state['values']['Dhmos']);
	
    $commands[] = ajax_command_replace("#dhmos_replace", render($form['Dhmos']));
    $commands[] = ajax_command_replace("#results_replace", render($form['results']));
    return array('#type' => 'ajax', '#commands' => $commands);
	
}

//ajax callback function for the second list

function dhmos_ajax_callback($form, $form_state) {
    return $form['results'];
}

//function to fetch contents of the second list

function dhmos_options($key) {
    
    if (isset($key)) {
	$sqlquery = "SELECT distinct(kal_dhmos) FROM \"FINAL_POINTS_WGS84\" where kal_perifereia='".$key."'  order by kal_dhmos";        
    }
    else {
    $sqlquery = 'SELECT distinct(kal_dhmos) FROM "FINAL_POINTS_WGS84" order by kal_dhmos';    
    }
	//drupal_set_message($sqlquery);
	db_set_active('custom');  
 $result = db_query($sqlquery)->fetchCol();
db_set_active();
return $result; 
}

//function to get table results

function table_results($key)
{
db_set_active('custom');
  $sqlquery = "SELECT bpcode,bpname FROM \"FINAL_POINTS_WGS84\" where kal_dhmos='".$key."' order by bpname";
 $result = db_query($sqlquery)->fetchAll();
db_set_active();
 $rows = array();
 foreach ($result as $row)
	{
		 $rows[] = array(
                    $row->bpcode,
                    $row->bpname,                    
    );
	}
	return $rows;
}

Thank you in advance for your help

Comments

bbeellkk’s picture

I have the same problem. It seems the form memorize the state of the element and do not want to change it. I'm currently working on Country - State/Province drop-down lists. AJAX loads states for the value selected from the Country drop-down menu. The problem is that there are 'Other' options for both lists, when the 'Other' option is selected an empty textfield will be shown (for both parameters). Once a visitor selects the 'Other' option drupal will set the State/Province value to 'Other' too. When he/she select a country from the list drupal returns the correct list but anyway shows the 'Other' option selected even I set the '#default_value' to NULL or first value from the '#options' array.

bbeellkk’s picture

The following helped me to resolve the issue:

I added this before definition of the $form['state'] element within the form function.
$form_state['input']['state'] = $form_state['values']['state'];

It, in addition to defining $form['state']['#default_value'] = $form_state['values']['state'], allowed to display the correct value.
I hope it will help to resolve your problem, unset($form_state['input']['state']) has not helped.