0

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:

ajax-error

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?

2 Answers 2

0

Ive been through a lot of that kind of error. When you are sure there's really nothing wrong with your code, check your values queried from the database. There might be unwanted characters in your data. Sanitize your data.

In my case, I encountered ñ characters, so what I did is clean the string before saving it in a variable.

 foreach ($result as $row) {
     $name = myid_clean_string($row->name);
 }

 //A function that cleans a string by replacing '?' by 'ñ'
 function myid_clean_string($word){
     return str_replace('?','ñ', trim($word));  
 }

You might do the same. Just check your data. Abba Yahweh bless you.

6
  • I'm 100% sure that the code from location.inc is working perfect because I tested outside the register_contratista.inc and I'm using it in another module a and it's working perfect too... I've been reading more about it but haven't found anything yet.... Mar 28, 2016 at 4:32
  • I'm almost sure it got it be something with the form_load_include. Mar 28, 2016 at 4:33
  • Is this Drupal 7? Mar 28, 2016 at 6:05
  • Yes Alyssa it is Drupal7. Mar 28, 2016 at 17:20
  • It isnt the answer, but I think drupal_get_form has only parameter. Mar 29, 2016 at 0:43
0

The callback functions might not be visible to the calling form. You can test it by moving the callbacks back into register_contratista.inc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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