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