i have a location.inc file that have a form with a 3 level dependent dropdown. when i execute this file by itself the code works 100% fine. but now i need to call that form into another form (register_contratista.inc). The form_load_include i'm using in register_contratista.inc its working...it render the form items into the new form but just when i select an options at the first dropdown it gives me an ajax error. I have no clue why it's happening been stuck for hours with this error.
I believe the problem is that the callback functions from location.inc are not working through the form_load_include.
this is the code from location.inc:
<?php
//define types of locations.
define("LOCATION_TYPE_COUNTRY", 1);
define("LOCATION_TYPE_STATE", 2);
define("LOCATION_TYPE_CITY", 3);
// start location form creator.
function location_form($form, $form_state) {
$countries = _location_get_countries(); //get all active 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,
'#required' => TRUE,
'#ajax' => array(
'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>',
'#ajax' => array(
'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>',
'#default_value' => isset($form_state['values']['p_city']) ? $form_state['values']['p_city'] : '',
);
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;
}
And this is the code from register_contratista.inc where i'm doing the form_load_include
<?php
function registro_contratista_page($form, &$form_state){
form_load_include($form_state, 'inc', 'lc_core', 'location');
$renderable = drupal_get_form('location_form', $form_state);
$location = render($renderable);
$form['usuario'] = array(
'#type' => 'fieldset',
'#title' => 'Registro de usario',
'#description' => 'Información necesaria para el registro de usuario en la plataforma.',
'#tree' => TRUE,
);
$form['usuario']['name'] = array(
'#title' => 'Nombre de usuario: ',
'#description' => 'Nombre de usuario con el cual se identificará en la plataforma, puede ser diferente a su nombre y debe contener máximo 12 letras.',
'#type' => 'textfield',
'#size' => '20',
'#required' => TRUE,
);
$form['usuario']['mail'] = array(
'#type' => 'textfield',
'#title' => 'Correo electrónico: ',
'#description' => 'Correo electrónico con el cual administrará su cuenta en la plataforma.',
'#required' => TRUE,
);
$form['ubicacion'] = array(
'#type' => 'markup',
'#markup' => $location, //HERE I RENDER THE FORM FROM location.inc
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
function registro_contratista_page_submit($form, &$form_state) {
$new_user = array(
'name' => $form_state['values']['usuario']['name'],
'pass' => user_password(),
'mail' => $form_state['values']['usuario']['mail'],
'init' => $form_state['values']['usuario']['mail'],
'status' => 1,
'access' => REQUEST_TIME,
'field_pais' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['field_pais']))),
'field_dept' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['field_dept']))),
'field_city' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['field_city']))),
);
user_save(null, $new_user);
}
And this is the error i'm getting:
Any idea where this error it's coming from???
UPDATE: NEW THEORY.
I'm not sure if this is the problem or not, i just got this new theory that might be the cause of the problem. As you can see at location.inc i have two functions like this:
function location_country_change_callback($form, $form_state) {
return $form['p_dept'];
}
That are the ones to update the options value of the second and third select list, this function works properly when executing the location.inc separately but when using it with form_load_include it is not working because the function can't find the field (in this case) "['p_dept']" so when i choose an option at the first dropdown i'm getting error because it doesn't know where to put the new values.
If this is the problem is there any way to specify to put those values at a specific field from a different form? like using $form_id? something like:
$form_id = 'my_new_form_id';
function location_country_change_callback($form, $form_state) {
return $form['p_dept'] at $form_id;
}
First let me know if you agree or disagree with this theory and if you do, how could i fix it?