0

I'm trying to convert old code written in standard HTML/PHP/Javascript/JQuery into a format (more) consistent with Drupal. The code consists of a form with interactive elements (regulated by Javascript functions) and a table produced with AJAX that can be manipulated (column sorting, page selection) with AJAX. I'm currently having trouble with Drupal AJAX.

I initially tried to simply use a callback function, but it seems that AJAX does not work from a callback. Here's some info (although it's D8, not D7). The following demo code fails to attach AJAX (verified with developer web inspector) but successfully creates the textfield element.

<?php

function test_main_form($form, $form_state) {
  $form['test1'] = array(
    '#type' => 'textfield',
    '#name' => 'test1',
    '#ajax' => array(
      'callback' => 'my_callback_function',
      'wrapper' => 'my_target_area',
      'method' => 'replace',
      'event' => 'blur',
    ),
  );
  $form['my_target_area'] = array(
    '#prefix' => '<div id="my_target_area">',
    '#suffix' => '</div>',
  );
  return $form;
}

function my_callback_function($form, $form_state) {  
  $form['my_target_area'] = array(
    '#prefix' => '<div id="my_target_area">',
    '#suffix' => '</div>',
  );
  $form['my_target_area']['result'] = array(
    '#type' => 'markup',
    '#markup' => 'You have selected: ' . $_POST['test1'] . '<br>',
  );
  $form['my_target_area']['test2'] = array(
    '#type' => 'textfield',
    '#name' => 'test2',
    '#ajax' => array(
      'callback' => 'my_callback_function',
      'wrapper' => 'my_target_area',
      'method' => 'replace',
      'event' => 'blur',
    ),
  );
  return $form['my_target_area'];
}

After additional digging, I found that the advised method (following Examples module, ajax_example -> add_more) uses $form_state['rebuild'] = TRUE which reloads the entire page, allowing form elements to be included/excluded based on prior inputs. This could work, but my current code depends heavily on Javascript functions, some of which create custom form elements that would be reset/removed by $form_state['rebuild'] = TRUE. It is significantly more difficult to implement the form rebuild than a callback function. Is there any way to include AJAX within a callback function?

  • 1
    Manipulating elements in the AJAX callback has unpredictable results, the generally accepted workflow is to set $form_state['foo'] = 'bar'; in the callback, and check if (isset($form_state['foo'])) { in the form builder, adding/changing the elements based on the result of the conditional – Clive Jun 25 at 18:49
  • 1
    As Clive has said, you're adding elements in your AJAX callback. You cannot do this in Drupal, it will result in errors and problems like you're seeing. The new elements must be added in the form definition - you can check if there are any values in the $form_state to determine if you are on original page load, or ajax page load. – Jaypan Jun 25 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.