This Codlet allows you to load state and city dropdown fields from country you select. It works as follow: 1. select country, states dropdown will be loaded from country. 2. select state, city dropdown will be loaded from state you select. Ex. selected country is 'INDIA' you get states dropdown depend on INDIA,

Drupal: Country dependant city dropdowns | Drupal Developer
CodeLet

<?php
/**
* hook_form_alter
*/
function mymodule_form_alter(&$form, $form_state, $form_id) {
  if($form_id == 'my_node_form') {

$country_default_value =$form_state['values']['field_cmn_city']['und']['0']['value'];
$state_default_value = $form_state['values']['field_cmn_state']['und']['0']['value'];
$city_default_value = $form_state['values']['field_cmn_city']['und']['0']['value'];

                  $country_options = _get_location('country');
            $selected_country = $country_default_value;
            $form['field_cmn_country']['und']['#options'] = $country_options;
            $form['field_cmn_country']['und']['#default_value'] = $selected_country;
            $form['field_cmn_country']['und']['#ajax'] = array(
              'callback' => 'field_cmn_country_callback',
              'wrapper' => 'field_cmn_state_replace',
              );
              
            $state_options = _get_location('state', $selected_country);// get state
            $selected_state = $state_default_value;

            $form['field_cmn_state']['und']['#prefix'] = '<div id="field_cmn_state_replace">';
            $form['field_cmn_state']['und']['#suffix'] = '</div>';
            $form['field_cmn_state']['und']['#options'] = $state_options; 
            $form['field_cmn_state']['und']['#default_value'] = $selected_state; 
            
            $form['field_cmn_state']['und']['#ajax'] = array(
              'callback' => 'field_cmn_state_callback',
              'wrapper' => 'field_cmn_city_replace',
              );
              
            $city_options = _get_location('city', $selected_state, $country_default_value);  
            $form['field_cmn_city']['und']['#prefix'] = '<div id="field_cmn_city_replace">';
            $form['field_cmn_city']['und']['#suffix'] = '</div>';
            $form['field_cmn_city']['und']['#options'] = $city_options; 
            $form['field_cmn_city']['und']['#default_value'] = $city_default_value;
                
  }
}

function _get_location($type, $location_id = NULL, $country_id = NULL) {
switch ($type) {
                case 'country':

                                    return $country_options;
                              break;
                
                case 'state':
                                       return $state_options;
                               break;
                
                case 'city':
                                      return $city_options;
                                break;

}
   // ajax country callback
function field_cmn_country_callback($form, $form_state) {
    
    $form_field_state =$form['field_cmn_state'];
    $form_field_city = $form['field_cmn_city'];
    
    return array(
   '#type' => 'ajax',
   '#commands' => array(
     ajax_command_replace("#field_cmn_state_replace", render($form_field_state)),
     ajax_command_replace("#field_cmn_city_replace", render($form_field_city))
   )
 );
    
}
//ajax state callback
function field_cmn_state_callback($form, $form_state) {
    
    return $form['field_cmn_city'];
}
?>

saru1683
Enroll to Drupal 10 Training

sunkathirs

I am looking this same one but I am not able to implement this code, can you please guide me how to implement because i m new to drupal

DrupalD

First you need to create a custom module and use the fields name that you have created in your respective content type. You will also need to change the function name according to your module name. Make sure your system has all the required PHP extensions enabled.

bestinc

Hello,
I am attempting to turn the city field in the locations module into a dropdown dependant on the country. I feel like this might be a start. The problem is its a multiple value field so I am confused on how I can modify this code to suit my needs. Do you have any ideas?
Thank you

saru1683

Given example is for 3 Dropdown (Countries, States and Cities), In your case , you need to remove a States Dropdown code from given example, for a multiple value field I think its as it is.

tester_np

I am using this custom module to apply dependant dropdown inside the field collection. Just a quick question how do you populate the country options in the select list ? Since in my country select list option I populate the data in CCK field. It makes an ajax call but nothing is shown up ? Could it be possible to have the full downloadable version of this code ?

Thanks

saru1683

add bellowed code for pre populate field on your hook_form_alter function.

$country_default_value = isset($form['field_cmn_country']['und']['#entity']->field_cmn_country['und'][0]['value']) ? $form['field_cmn_country']['und']['#entity']->field_cmn_country['und'][0]['value'] : NULL;
$state_default_value = isset($form['field_cmn_state']['und']['#entity']->field_cmn_state['und'][0]['value']) ? $form['field_cmn_state']['und']['#entity']->field_cmn_state['und'][0]['value'] : NULL;
$city_default_value = isset($form['field_cmn_city']['und']['#entity']->field_cmn_city['und'][0]['value']) ? $form['field_cmn_city']['und']['#entity']->field_cmn_city['und'][0]['value'] : NULL;

$country_default_value = (isset($form_state['values'][$type]['field_cmn_country']['und']['0']['value'])) ? $form_state['values'][$type]['field_cmn_country']['und']['0']['value'] : $country_default_value;
$state_default_value = (isset($form_state['values'][$type]['field_cmn_state']['und']['0']['value'])) ? $form_state['values'][$type]['field_cmn_state']['und']['0']['value'] : $state_default_value;
$city_default_value = (isset($form_state['values'][$type]['field_cmn_city']['und']['0']['value'])) ? $form_state['values'][$type]['field_cmn_city']['und']['0']['value'] : $city_default_value;

tester_np

I tried this way:
$country_default_value = $form_state['field']['#parents']['field_dropdown']['und'][0]['#fields']['field_cmn_country']['und']['field']['settings']['allowed_values'];
$state_default_value = $form_state['field']['#parents']['field_dropdown']['und'][0]['#fields']['field_cmn_state']['und']['field']['settings']['allowed_values'];
$city_default_value = $form_state['field']['#parents']['field_dropdown']['und'][0]['#fields']['field_cmn_city']['und']['field']['settings']['allowed_values'];

and disable the line
$form['field_dropdown']['und'][0]['field_cmn_country']['und']['#options']=$country_options;

Then only I can see my country select list populated with data. But it always complain the switch case condition for undefined variable $country_options , $state_options and $city_options.

If you already make this custom module work inside field collection can we have a look at your codes ?

saru1683

I have already posted working code on post
Please have a look at this of hook_form_alter, and ajax call back function.

<?php
/**
* ajax call back
*/
function field_cmn_country_callback($form, $form_state) {

$form_field_state = $form['field_cmn_state'];
$form_field_city = $form['field_cmn_city'];
return array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_replace("#field_cmn_state_replace", render($form_field_state)),
ajax_command_replace("#field_cmn_city_replace", render($form_field_city))
)
);
}

/**
* ajax call back
*/
function field_cmn_state_callback($form, $form_state) {
return $form['field_cmn_city']));
}

function hook_form_alter() {

$country_default_value = isset($form['field_cmn_country']['und']['#entity']->field_cmn_country['und'][0]['value']) ? $form['field_cmn_country']['und']['#entity']->field_cmn_country['und'][0]['value'] : NULL;
$state_default_value = isset($form['field_cmn_state']['und']['#entity']->field_cmn_state['und'][0]['value']) ? $form['field_cmn_state']['und']['#entity']->field_cmn_state['und'][0]['value'] : NULL;
$city_default_value = isset($form['field_cmn_city']['und']['#entity']->field_cmn_city['und'][0]['value']) ? $form['field_cmn_city']['und']['#entity']->field_cmn_city['und'][0]['value'] : NULL;

$country_default_value = (isset($form_state['values'][$type]['field_cmn_country']['und']['0']['value'])) ? $form_state['values'][$type]['field_cmn_country']['und']['0']['value'] : $country_default_value;
$state_default_value = (isset($form_state['values'][$type]['field_cmn_state']['und']['0']['value'])) ? $form_state['values'][$type]['field_cmn_state']['und']['0']['value'] : $state_default_value;
$city_default_value = (isset($form_state['values'][$type]['field_cmn_city']['und']['0']['value'])) ? $form_state['values'][$type]['field_cmn_city']['und']['0']['value'] : $city_default_value;

$xfield_options = _get_location('all', NULL, 'country');
$selected = $country_default_value;//(isset($form_state['values']['field_cmn_country']['und']['0']['value'])) ? $form_state['values']['field_cmn_country']['und']['0']['value'] : (isset($form['#node']->field_cmn_country['und'][0]['value']) ? $form['#node']->field_cmn_country['und'][0]['value'] : NULL);
$form['field_cmn_country']['und']['#options'] = $xfield_options;
$form['field_cmn_country']['und']['#default_value'] = $selected;
$form['field_cmn_country']['und']['#ajax'] = array(
'callback' => 'field_cmn_country_callback',
'wrapper' => 'field_cmn_state_replace',
);

$state_options = _get_location('all', $selected, 'state');
$selected_state = $state_default_value;//(isset($form_state['values']['field_cmn_state']['und']['0']['value'])) ? $form_state['values']['field_cmn_state']['und']['0']['value'] : (isset($form['#node']->field_cmn_state['und'][0]['value']) ? $form['#node']->field_cmn_state['und'][0]['value'] : NULL);
$form['field_cmn_state']['und']['#prefix'] = '';
$form['field_cmn_state']['und']['#suffix'] = '';
$form['field_cmn_state']['und']['#options'] = $state_options;
$form['field_cmn_state']['und']['#default_value'] = $selected_state;

$form['field_cmn_state']['und']['#ajax'] = array(
'callback' => 'field_cmn_state_callback',
'wrapper' => 'field_cmn_city_replace',
);

$city_options = _get_location('all', $selected_state, 'city');
$form['field_cmn_city']['und']['#prefix'] = '';
$form['field_cmn_city']['und']['#suffix'] = '';
$form['field_cmn_city']['und']['#options'] = $city_options;
$form['field_cmn_city']['und']['#default_value'] = $city_default_value;
}?>

saru1683

Hello tester_np, is this working for you? let me know if I can do anything for you.

tester_np

I have a small concern, is the definition for the function _get_location() is the same as the first code that you have posted, since I don't see its definition there in the code you have posted above. Another is I use the data for the Country, State and City while I was creating the select list option for the cck field inside the field collection. I am not sure whether this work in a field collection with unlimited option.

DrupalD

To make it working with field collectin, you may require some more code, related to field collection. But at most, current code should work out of the box!

GoldenHawk

Hello! i'm working on a similar code so far the first two levels are working but the 3rd one it's not updating after user select (state) sencond dropdown... could some body help my find the problem this is the link to the question at drupal.stackexchange:https://drupal.stackexchange.com/q/194141/56202 if your not registered at stackexchange you could answer me at this site... thank you for your help!!!!

saru1683

Hello @GoldenHawk, You did well and its working, Here is the code which one working fine for me. If still not working reply me.
<?php
function project_creator_form($form, &$form_state) {
global $user;
$uuid = $user->uid;

$flat_countries = array( '' => '-- Select Country --', 'ind' => 'India');

$flat_states = array(
'' => '-- Select State --',
);

$state_id = $country_id = '';
$flat_cities = array(
'' => '-- Select City --',
);

if(!empty($form_state['values']['p_ctry'])) {
$country_id = $form_state['values']['p_ctry'];
$flat_states = array('' => '-- Select State --', 'guj' => 'Gujarat');

if(!empty($form_state['values']['p_dept'])) {
$state_id = $form_state['values']['p_dept'];

$flat_cities = array(
'' => '-- Select City --',
'rjt' =>'Rajkot',
'ahmd' => 'Ahmedabad'
);
}
}

$form['p_ctry'] = array(
'#type' => 'select',
'#title' => t('Seleccione país del proyecto'),
'#options' => $flat_countries,
'#default_value' => $country_id,
'#description' => "Seleccione el país donde se ejecutará el proyecto.",
'#required' => TRUE,
'#ajax' => array(
'event' => 'change',
'callback' => 'location_country_change_callback',
'wrapper' => 'state-wrapper',
),
);

$form['p_dept'] = array(
'#type' => 'select',
'#title' => t('Seleccione el departamento/estado'),
'#prefix' => '',
'#options' => $flat_states,
'#default_value' => $state_id,
'#suffix' => '',
'#description' => "Seleccione el departamento o estado donde se ejecutará el proyecto.",
'#ajax' => array(
'event' => 'change',
'callback' => 'location_city_change_callback',
'wrapper' => 'city-wrapper'
),
);

$form['p_city'] = array(
'#type' => 'select',
'#title' => t('Seleccione ciudad'),
'#prefix' => '',
'#options' => $flat_cities,
'#suffix' => '',
'#description' => "Seleccione la ciudad donde se ejecutará el proyecto.",
);

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

return $form;

}

function location_country_change_callback($form, &$form_state) {
$form_field_state = $form['p_dept'];
$form_field_city = $form['p_city'];
return array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_replace("#state-wrapper", render($form_field_state)),
ajax_command_replace("#city-wrapper", render($form_field_city))
)
);
}
function location_city_change_callback($form, &$form_state) {
return $form['p_city'];
}
?>

GoldenHawk

Thank you!! turns out the error wasnt at the code... it was an error at some database values. I tested your code and its working good too.. THANKS!

DrupalD

We are glad that worked. We would appreciate if you can share your live codes too.

Regards.

DrupalD

There are two options: Either you can read the country/sate & city details from a file with short codes or from DB. It completely depends on the way you want it. This CodeLet just suggests a way to achieve the desired result. Regards.