TransWikia.com

Form field not show on Ajax Callback even the callback is called

Drupal Answers Asked by Emad Karhely on January 23, 2021

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;
}

One Answer

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.

Answered by 4k4 on January 23, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP