3

I know this has been asked before and I'm trying to use the example at Dynamic select list in the form (dependent dropdown) but I am struggling to get the desired results.

The goal: Have a form that presents the user with a Platform select field. Once selected take the value from that field pass it to the a SQL statement to render an additional select field with a list of results from the query. Right now the following code displays both select fields when the form renders. I would like only the platform select field to be rendered until the user chooses an option.

I'm a little bit confused about the AJAX function and how you wrap another select item to be marked for replacement when the page is called again so any explanations or pointers would be great.

Per @Clive I've adjusted the code below. However I'm fighting with pulling the selected value into the model lookup query statement. Right now as is the form doesn't even render.

Update 2

I've been cleaning up my code and catching small stupid errors. Which have yielded: 1)AJAX call back working. 2)Hiding the model select field when the platform select hasn't changed.

However I can't seem to make the model field appear when an option is selected in the Platform field. I suspect it's a problem with if (isset($form_state['values']['platform'])) {. Updated full code below. I feel close to completing this just need some guidance.

Full Code

function iosupload_menu() {
$items = array();
$items['ios_upload/form'] = array(
  'title' => t('IOS Upload'),
  'page callback' => 'iosupload_form',
  'access arguments' => array('access content'),
  'description' => t('IOS Upload'),
  'type' => MENU_CALLBACK,
);
return $items;
}

function iosupload_form() {
return drupal_get_form('main_iosupload_form');
}

function main_iosupload_form($form, &$form_state) {
//Define SQL Lookup Query
$sqlplatform = "SELECT vid, name FROM {taxonomy_vocabulary} WHERE vid >= 4";

$result = db_query($sqlplatform);
$options = array();
  foreach ($result as $row) {
    $options[$row->vid] = t($row->name);
  }

$form['platform'] = array(
  '#type' => 'select',
  '#title' => t('Select a Platform'),
  '#options' => array(
    0 => t('- Select -')) + $options,
  '#default_value' =>  0,
  '#required' => TRUE,
  '#ajax' => array(
    'callback' => 'ajax_select_callback',
    'wrapper' => 'replace_model_div',
    'effect' => 'slide',
   ),
);
if (isset($form_state['values']['platform'])) {
 $platform_value = $form_state['values']['platform'];
 $sqlmodel = "SELECT tid, name FROM {taxonomy_term_data} WHERE vid = $platform_value";
 $result = db_query($sqlmodel);
 $options = array();
   foreach ($result as $row) {
     $model_options[$row->vid] = t($row->name);
    }

$form['model_wrapper'] = array(
  '#type' => 'select',
  '#title' => t('Select a Model'),
  '#options' => $model_options,
  '#options' => t('$platform_value'),
  '#prefix' => '<div id="replace_model_div">',
  '#suffix' => '</div>',
);
}
return $form;
}
function ajax_select_callback($form, $form_state) {
  return $form['model_wrapper'];
}
2

A few problems I can see:

  • The $model_options variable is used both in the form and AJAX callback function, but isn't defined anywhere. Same thing with the $platform variable in the AJAX callback.
  • You're putting a wrapper around a particular element, but instead of returning that element you're returning the entire form.
  • It looks like you're attempting to put form-altering logic into the AJAX callback function - it should be used only to return the updated element, the actual building of it should be done in the form function.
  • You're defining the AJAX callback wrapper as 'replace_model_div', and implementing it as a class name instead of an ID, and with a complete different name (model-wrapper).
  • The function signature for your form is wrong (in Drupal 7 it's:

    function form_name($form, &$form_state)
    

You should get some joy with code a bit more like this:

function main_iosupload_form($form, &$form_state) {
  //Define SQL Lookup Query

  $sqlplatform = "SELECT vid, name FROM {taxonomy_vocabulary} WHERE vid >= 4";
  $sqlmodel = "SELECT tid, name FROM {taxonomy_term_data}";

  $result = db_query($sqlplatform);
  $options = array();
  foreach ($result as $row) {
    $options[$row->vid] = t($row->name);
  }

  $form['platform'] = array(
    '#type' => 'select',
    '#title' => t('Select a Platform'),
    '#options' => array(
      0 => t('- Select -')) + $options,
    '#default_value' => isset($form_state['values']['platform']) ? $form_state['values']['platform'] : 0,
    '#required' => TRUE,
    '#ajax' => array(
      'event' => 'change',
      'callback' => 'ajax_select_callback',
      'wrapper' => 'replace_model_div',
      'method' => 'replace',
     ),
  );

  if (isset($form_state['values']['platform'])) {
    $model_options = function_to_get_model_options_by_platform($form_state['values']['platform']);

    $form['model_wrapper'] = array(
      '#prefix' => '<div id="replace_model_div">',
      '#suffix' => '</div>',
    );

    $form['model_wrapper']['model'] = array(
      '#type' => 'select',
      '#title' => t('Select a Model'),
      '#options' => $model_options,
    );
  }

  return $form;
}

function ajax_select_callback($form, $form_state) {
  return $form['model_wrapper'];
}
| improve this answer | |
  • I knew I had this horribly jacked up. I'll play around with this later today and report back. Thanks. – rsaturns Jun 27 '12 at 13:56
  • I've taken the format you've used above but am having trouble evaluating what was selected in the Platform dropdown and taking that value to pass it into the SQL lookup for model. This is what I have that is failing: if (isset($form_state['values']['platform'])) { $platform_reference = $form_state['values']['platform'] $sqlmodel = "SELECT tid, name FROM {taxonomy_term_data} WHERE vid = $platform_reference"; $result = db_query($sqlmodel); $options = array(); foreach ($result as $row) { $model_options[$row->vid] = t($row->name); } – rsaturns Jun 27 '12 at 21:03
  • 1
    "'#default_value' => isset($form_state['values']['platform']) ? $form_state['values']['platform'] : 0,". This isn't necessary. FAPI will automatically prefer the value from $form_state['values'] over the one in #default_value. – Berdir Jun 28 '12 at 6:22
  • @Berdir I have reverted that line back to '#default_value' => 0, – rsaturns Jun 28 '12 at 14:36

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.