1

i'm trying to make a 3 level dropdown lists. Country -> State -> City.

So far i got it working with 2 levels, Country -> State. But when i change state it doesn't give me the cities. I've been reading and i found this previously asked question wich have an answer, but i still can't comment the answer (just starting at drupal.stackexchange) to ask for clarification, because i don't understand the answer given, i don't i even know it that answer apply for my own code, i think it does.

Would some body help understand?

This is the code I'm using.

//define types of locations.
define("LOCATION_TYPE_COUNTRY", 1);
define("LOCATION_TYPE_STATE", 2);
define("LOCATION_TYPE_CITY", 3);

// START PROJECT CREATOR FORM
function project_creator_form($form, &$form_state) {
    global $user;
    $uuid = $user->uid;

     $countries = _location_get_countries();

  $flat_countries = array(
    '' => '-- Seleccione país --',
  );

  $flat_countries = location_flatten_locations_array($countries, $flat_countries);

  $flat_states = array(
    '' => '-- Seleccione departamento --',
  );

   $country_id = ''; 

 if(isset($form_state['values']['p_ctry'])) {    
    $country_id = $form_state['values']['p_ctry'];

    $states = _location_get_states($country_id);

    $flat_states = location_flatten_locations_array($states, $flat_states);
  } 

  $flat_cities = array(
    '' => '-- Seleccione ciudad --',
    );

  $state_id = '';


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

    $cities = _location_get_cities($state_id);

    $flat_cities = location_flatten_locations_array($cities, $flat_cities);
  }

    $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' => '<div id ="state-wrapper">',
    '#options' => $flat_states,
    '#default_value' => $state_id,
    '#suffix' => '</div>',
    '#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' => '<div id ="city-wrapper">',
    '#options' => $flat_cities,
    '#suffix' => '</div>',
    '#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) {
  return $form['p_dept'];
}
function location_city_change_callback($form, &$form_state) {
  return $form['p_city'];
}
function location_flatten_locations_array($array, $start = array()) {
  if(is_array($start)) {
    $result = $start;
  } else {
    $result = array();
  }

  asort($array['by_name']);

  foreach($array['by_name'] as $item) {
    $result[$item['id']] = $item['name'];
  }

  return $result;
}

function _location_get_locations($location_type){

    $location_type = intval($location_type);
    static $locations = array();

    if(!array_key_exists($location_type, $locations)) {

       db_set_active('civilproconstru');

      $query = 'SELECT * FROM `location` WHERE `location_type` = '.$location_type.' AND `is_visible` = 1';

      $result = db_query($query);

      foreach ($result as $row) {
          $name = $row->name;
          $id = $row->location_id;
          $parent = $row->parent_id;

          $record = array(
            'name' => $name,
            'id' => $id,
            'parent' => $parent,
          );

          $locations[$location_type]['by_name'][$name] = $record;
          $locations[$location_type]['by_id'][$id] = $record;
      }

       db_set_active();

    }
    return $locations[$location_type];
}

function _location_get_countries() {
  return _location_get_locations(LOCATION_TYPE_COUNTRY);
}

function _location_get_states($country_id = null) {
  $states = _location_get_locations(LOCATION_TYPE_STATE);
  if(!is_null($country_id)) {
    $closure = function($item) use($country_id) {
      return $item['parent'] == $country_id;
    };
    $states['by_name'] = array_filter($states['by_name'], $closure);
    $states['by_id'] = array_filter($states['by_id'], $closure);
  }
  return $states;
}

function _location_get_cities($state_id = null) {
  $cities = _location_get_locations(LOCATION_TYPE_CITY);
  if(!is_null($state_id)) {
    $closure = function($item) use($state_id) {
      return $item['parent'] == $state_id;
    };
    $cities['by_name'] = array_filter($cities['by_name'], $closure);
    $cities['by_id'] = array_filter($cities['by_id'], $closure);
  }
  return $cities;
}


function project_creator_form_submit($form, &$form_state) {

    db_set_active('civilproconstru'); //OPEN alter DATABASE.
    db_insert('project_info')
        ->fields(array(
        'p_ctry' => $form_state['values']['p_ctry'],
        'p_dept' => $form_state['values']['p_dept'],
        'p_city' => $form_state['values']['p_city'],

        ))->execute();
    drupal_set_message(t('The form has been sbmitted.'));
db_set_active(); //CLOSE alter DATABASE.
}
?>
  • You can try this code: bit.ly/citydrop It has everything you need. – Bhavin Joshi Jun 22 '17 at 11:30
  • This is for any one else who is looking for a solution. – Bhavin Joshi Jun 22 '17 at 11:31
0

After two weeks of looking for an error at this code, it turned out there is no error in the code. The error was at some values of the database, more exactly at the is_visible value.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.