1

I have a form with one shown field of type select with ajax callback to show another form field dynamically of type select and with ajax callback again, the problem is second field ajax callback should show a third field dynamically but nothing is shown. here is my code

public function buildForm(array $form, FormStateInterface $form_state) {
    $controller = new Place_AdsController();
    $terms = $controller->content();

    $form['#attached']['library'][] = 'Place_Ads/general';
    $form['level1value'] = array(
        '#type' => 'hidden',
    );
    $form['level1'] = array(
        '#type' => 'select',
        '#description' => 'Please select level one term',
        '#options' => $terms,
        '#attributes' => array(
            'class' => array(
                'mycategory'
            ),
        ),
        '#ajax' => array(
            // Function to call when event on form element triggered.
            'callback' => '::level1SelectedCallback',
            // Effect when replacing content. Options: 'none' (default), 'slide', 'fade'.
            'wrapper' => 'ajax-wrapper2',
            'effect' => 'fade',
            // Javascript event to trigger Ajax. Currently for: 'onchange'.
            'event' => 'change',
            'progress' => array(
                // Graphic shown to indicate ajax. Options: 'throbber' (default), 'bar'.
                'type' => 'throbber',
                // Message to show along progress graphic. Default: 'Please wait...'.
                'message' => NULL,
            ),
        ),
    );
    $form['ajax_wrapper2'] = [
        '#type' => 'container',
        '#attributes' => ['id' => 'ajax-wrapper2'],
    ];
    $form['ajax_wrapper3'] = [
        '#type' => 'container',
        '#attributes' => ['id' => 'ajax-wrapper3'],
    ];

    if ($form_state->getValue('level1') != false) {
        $form['ajax_wrapper2']['level2'] = array(
            '#type' => 'select',
            '#description' => 'Please select level two term',
            //'#options' => '',
            '#attributes' => array(
                'class' => array(
                    'mycategory'
                ),
            ),
            '#ajax' => array(
                // Function to call when event on form element triggered.
                'callback' => '::level2SelectedCallback',
                // Effect when replacing content. Options: 'none' (default), 'slide', 'fade'.
                'wrapper' => 'ajax-wrapper3',
                'effect' => 'fade',
                // Javascript event to trigger Ajax. Currently for: 'onchange'.
                'event' => 'change',
                'progress' => array(
                    // Graphic shown to indicate ajax. Options: 'throbber' (default), 'bar'.
                    'type' => 'throbber',
                    // Message to show along progress graphic. Default: 'Please wait...'.
                    'message' => NULL,
                ),
            ),
        );
    }
    if ($form_state->getValue('level2') != false) {
        //$form['ajax_wrapper3'][0]['#suffix'] = '</div>';
        $form['ajax_wrapper3']['level3'] = array(
            '#type' => 'select',
            '#description' => 'Please select level three term',
            //'#options' => '',
            '#attributes' => array(
                'class' => array(
                    'mycategory'
                ),
            ),
            '#ajax' => array(
                // Function to call when event on form element triggered.
                'callback' => '::level3SelectedCallback',
                // Effect when replacing content. Options: 'none' (default), 'slide', 'fade'.
                'wrapper' => 'ajax-wrapper4',
                'effect' => 'fade',
                // Javascript event to trigger Ajax. Currently for: 'onchange'.
                'event' => 'change',
                'progress' => array(
                    // Graphic shown to indicate ajax. Options: 'throbber' (default), 'bar'.
                    'type' => 'throbber',
                    // Message to show along progress graphic. Default: 'Please wait...'.
                    'message' => NULL,
                ),
            ),
        );
    }

    return $form;
}

public function level1SelectedCallback(array &$form, FormStateInterface $form_state) {
    // Instantiate an AjaxResponse Object to return.
    $ajax_response = new AjaxResponse();
    $controller = new Place_AdsController();
    $terms = array();
    if ($form_state->getValue('level1') != false) {
        $val = $form_state->getValue('level1');
        $terms = $controller->getTerms($val);

    }

    $form['ajax_wrapper2']['level2']['#options'] = $terms;
    $ajax_response->addCommand(new HtmlCommand('#ajax-wrapper2', $form['ajax_wrapper2']['level2']));
    // We can still invoke the change command on #edit-user-name so it triggers Ajax on that element to validate username.
    $ajax_response->addCommand(new InvokeCommand('#ajax-wrapper2', 'change'));
    $ajax_response->addCommand(new InvokeCommand('#level2', 'change'));

    return $ajax_response;
}

public function level2SelectedCallback(array &$form, FormStateInterface $form_state) {

    $ajax_response = new AjaxResponse();
    $controller = new Place_AdsController();
    $terms = array();
    if ($form_state->getValue('level2') != false) {
        $val = $form_state->getValue('level2');
        $terms = $controller->getTerms($val);

    }

    $form['ajax_wrapper3']['level3']['#options'] = $terms;
    $ajax_response->addCommand(new HtmlCommand('#ajax-wrapper3', $form['ajax_wrapper3']['level3']));
    // We can still invoke the change command on #edit-user-name so it triggers Ajax on that element to validate username.
    $ajax_response->addCommand(new InvokeCommand('#ajax-wrapper3', 'change'));
    $ajax_response->addCommand(new InvokeCommand('#level3', 'change'));

    return $ajax_response;

}

public function level3SelectedCallbackold(array &$form, FormStateInterface $form_state) {
    return null;
}
  • any errors showing? – aegc Aug 2 '16 at 7:54
  • No error showing – Emad Karhely Aug 2 '16 at 8:44
0

Changing the option list in an ajax callback like this

$form['ajax_wrapper2']['level2']['#options'] = $terms;

does not work, because the formbuilder does not know about this and will not recognize the new options. You have to move this code to buildForm().

Otherwise you will see a select element, but when you choose an option, nothing will happen or an error occurs that you have chosen the wrong option.

|improve this answer|||||
  • this piece of code is working fine and the select "#level2" is shown successfully with its ajax callback being fired, however the problem is in the 3rd level "#level3" select not shown even with empty options. So the question why its working with level2 but never with level3? – Emad Karhely Aug 2 '16 at 8:57
  • sorry, can't debug the whole code, but this was the most obvious problem, i explain this a bit more, see the edit – 4k4 Aug 2 '16 at 9:18

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.