1

I am trying to load a Drupal form through an AJAX callback when the user selects an option from a select list. The code used to generate this form as follows:

public function buildForm(array $form, FormStateInterface $form_state) {
    $form['dashboard_list'] = array(
    '#title' => t('Select Dashboard:'),
    '#type' => 'select',
    '#ajax' => array(
        'callback' => 'Drupal\dashboard\Controller\DashboardController::OnPanelSwitch',
        'effect' => 'fade',
        'event' => 'change',
        'progress' => array(
            'type' => 'throbber',
            'message' => NULL,
            ),
        ),

   );
return $form;
}

Inside of OnPanelSwitch(), which is called when the user selects an option from the list. I am using the renderer service to get the form's HTML and then inserting the form into a div.

 public static function OnPanelSwitch(array &$form, FormStateInterface $form_state) {
    $ajax_response = new AjaxResponse();

    $AddChartForm = \Drupal::formBuilder()->getForm('Drupal\dashboard\Form\AddChartForm');
$AddChartFormHTML =\Drupal::service('renderer')->render($AddChartForm);


    $ajax_response->addCommand(new HtmlCommand('#formarea', $AddChartFormHTML));

    return $ajax_response;

}

This HTML is then inserted into a DIV in the page. The form being loaded via AJAX is built in the following manner and contains a single select list:

public function buildForm(array $form, FormStateInterface $form_state) {    
   $form['query_type'] = array(
      '#title' => t('Query Type'),
      '#title_display' => 'invisible',
      '#type' => 'select',
      '#options' => array(t('Chart'), t('Table')),
      '#prefix' => '<div class="floatLeft"',
      '#suffix' => '</div>',
      '#ajax' => array(
          'callback' => 'Drupal\dashboard\Controller\DashboardController::OnQueryFieldChange',
          'effect' => 'fade',
          'event' => 'change',
          'progress' => array(
              'type' => NULL,
              'message' => NULL,
              ),
          ),

  );
return $form
}

The OnQueryFieldChange() callback is not being called when this form is being loaded via the initial AJAX call. If I load this form without AJAX through the twig template everything works correctly. So it seems to be an issue of the form being loaded via AJAX.

From my research it seems like I might have todo something with Drupal Behaviors to enable AJAX for this form? Any guidance would be really helpful.

  • Depending on how you're invoking the AJAX you might just need to call Drupal.attachBehaviors(); when the request completes – Clive Mar 15 '17 at 22:55
  • the early rendering could also be a problem, because the ajax response (if you use one) gets the attached drupal settings from the render array and if this is already rendered this is not possible – 4k4 Mar 16 '17 at 7:36
  • @Clive I'm a little unsure on how to go about using the Drupal behaviors to fix the issue. I have added some more code in my post to possibly clarify how I'm using ajax. – iWig Mar 16 '17 at 15:15
  • Please post the JS code you have – Kevin Mar 16 '17 at 15:18
  • @4k4 I have edited my post to possibly clarify how Im using the ajax responses. I'm a little unclear on exactly how to fix the early rendering issue. How you suggest I load the form via AJAX then? – iWig Mar 16 '17 at 15:18
0

I have fixed the issue I was having by just returning the render array of the form rather than trying to get the form's HTML. So my AJAX callback function now looks something like this:

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

   $ajax_response = new AjaxResponse();

   $AddChartForm = \Drupal::formBuilder()->getForm('Drupal\dashboard\Form\AddChartForm');

   $ajax_response->addCommand(new HtmlCommand('#formarea', $AddChartForm));

return $ajax_response;
  • 1
    Anytime it comes to forms, always deal in render arrays and not raw HTML - so you will want to return the array itself. This will ensure everything renders as expected and let the form system do its thing. – Kevin Mar 17 '17 at 13:40

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.