1

I am trying to dynamically populate a select field (chamiponship) based on the selection in another field (country). It works fine when I load the page but just the first time, the second time I select another country it does not work. Did anyone have this issue and how did you solve? Here is my code

<?php

function testform_menu(){

    $items['data'] = array(
        'title' => 'data access',
        'description' => 'get acess to the data',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('testform_form'),
        'access callback' => TRUE,
    );
    return $items;
}


function testform_form($form, &$form_state) {

        $form['country']=array( 
            '#type'=>'select',
            '#title'=>t('Select your country'),
            '#options'=>array('FR' =>'France', 'UK' =>'England','DE' =>'Germany'),
            '#ajax' => array('event'=>'change','callback' =>'LoadDiv','wrapper' => 'DivSelect',),
        );

        $optionsDiv = array('Ligue 1','Ligue 2');
        if (isset($form_state['values']['country'])) {
            $optionsDiv = loadDivision($form_state['values']['country']);
        }

        $form['champion']=array( 
            '#type'=>'select',
            '#title'=>t('Select your championship'),
            '#options'=>$optionsDiv,
            '#prefix' => '<div id="DivSelect">',
            '#suffix' => '</div>',
        );


        $form['submit'] = array(
            '#type' => 'submit',
            // #value is the text to display inside the button
            '#value' => t('Submit'),
        );

        return $form;
}

function LoadDiv($form, &$form_state) {
  return $form['champion'];
}

function loadDivision($country_id) {
  $data_count=array('FR' => array('Ligue1', 'Ligue2'), 'UK' => array('Premier','Championship'), 'DE' => array('Bundesliga1','Bundesliga2'));
  $championship = $data_count[$country_id];
  return $championship;
}
0

It is hard to say without seeing your JavaScript, but what you describe fits perfectly with the following scenario:

When your page loads initially loads, the LoadDiv JavaScript event is bound to #DivSelect, but when that #DivSelect element is overwritten by the Drupal AJAX api, the event is no longer bound.

The solution is to use Drupal.behaviors - there is a good, short explanation at http://www.amazeelabs.com/en/blog/drupal-behaviors-quick-how.

Wrap your LoadDiv javascript in the drupal behaviors code, and it will be added for every request, including AJAX requests:

Drupal.behaviors.myModuleDoSomethingCool = {
  attach: function (context, settings) {
    $('#DivSelect').change(function() { 
      // Loaddiv etc etc
    });
  }
};

I agree with comments suggesting that this is a good use case for hierarchical select - but the above is the likely explanation for why your AJAX works the first time and not the second time.

  • Thanks, I haven't a javascript file, I was thinking that AJAX will figure out everything and reload 'champion' when I select for the second time a different 'country'. As I am new in drupal I am trying to understand how things works with AJAX. I have see some proposal with the hook_form_alter() so I will go again fur some research and reading to figure it out. – hanes Jan 25 '15 at 15:55
  • Where is the code for your LoadDiv callback? It sounds like you are replacing the form element that has the ajax action on it. Perhaps you need to replace the whole form? – calebtr Jan 25 '15 at 16:46
  • the loadDiv callback is defined in the code above. It only returns form['champion'] as this need to be updated. – hanes Jan 26 '15 at 19:10
  • Oh, scrollbar - my bad! I copied and pasted your code into a new testform.module and I can change the Country field multiple times and it updates Championship every time. Do you see Javascript errors in the Chrome console? PHP errors in your watchdog logs? – calebtr Jan 27 '15 at 6:34

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.