Having a simple form with few input fields. After clicking on ajax callback submit button, I'm returning the table element.


//Hypertension treatment
        $form['hyper_treat'] = array (
      '#type' => 'radios',
      '#title' => ('Hypertension treatment:'),                                  
      '#options' => array(
        'y' => 'Yes', 
        'n' => 'No'

    $form['hyperchol'] = array (
  '#type' => 'radios',
  '#title' => ('Hypercholesterolemia:'),                                        
  '#options' => array(
    'y' => 'Yes', 
    'n' => 'No'

//submit button
    $form['action'] = [
    '#prefix' => '<div id = "ajax_submit">',
     '#name' => 'ajax_action',
    '#type' => 'button',
    '#value' => $this->t('Submit'),
    '#ajax' => [
    'callback' => '::setMessage',
    'wrapper' => 'scrollable',
    'method' => 'replaceWith',
    'effect' => 'fade', 

    $form['table'] = array(
    '#prefix' => '<div id="scrollable" class = "col-md-8"><h4>View Data</h4>',
        '#type' => 'tableselect',
         '#suffix' => '</div>',
        '#header' => $header,
         '#options' => $options,
        '#disabled' => $disabled,
        '#attributes' => array('id' => 'sort-table'),
        '#empty' => t('Select criteria and search data'),

//callback function
   public function setMessage(array $form, FormStateInterface $form_state) {
  $options = getOptions(); //gets the associative array
  $form['table']['#options'] = $options;
  return $form['table'];

I had issues with the pagination and sorting of the table returned using ajax. So I thought of using "Datatables" as the alternative option.

So after the callback, I would want to apply the below jquery to have the table shown as a datatable.

 $('#sort-table').DataTable( {
        order: [[ 1, 'asc' ]]
    } );

Tried executing the 'mousedown' event for the button but the jquery executes before the ajax callback.

Is there a possible way to represent the $form['table'] element returned from the ajax callback, as a datatable?

enter image description here

Triggering any other event after table returned would display it as a datatable, but I'm looking to have the returned table displayed as a datatable immediately after the $form['table'] is returned. This happens only when the jquery snippet is executed immediately after the table element is returned from the ajax callback function.

  • Normally you put the js code in a Drupal.behaviors.myBehavior object and attach it as library. On each ajax request the Drupal behaviors are run again, with the context limited to the newly loaded content.
    – 4k4
    Jun 27 '18 at 12:10
  • I did exactly the same thing and it worked fine
    – Abhi
    Jun 27 '18 at 23:51

You can use custom ajax commands for this. Ajax commands are php classes that correspond to a JS function on the server, which the Drupal JS API calls after Ajax responses.

At a quick lookover, this tutorial looks like it gives a good overview on how to create a custom Ajax command in Drupal 8.


jQuery has .ajaxComplete() and ajaxSuccess() methods among other ajax event handlers. So on the client side you could try something like this:

    $('#sort-table').DataTable( {
        order: [[ 1, 'asc' ]]
  • Sure, but just be careful you are invoking it against the exact thing you want to touch. Otherwise, this will fire every single time any AJAX has completed in the application. I wrote some conditions around this before... let me see if I can find them.
    – Kevin
    Jun 27 '18 at 21:49
  • Right here - you will want to check for the triggering element. This was the only way I could tell what triggered AJAX, so I knew if I wanted to continue and fire specific code: kevinquillen.com/javascript/2014/06/04/kill-the-ajax-throbber
    – Kevin
    Jun 27 '18 at 21:51
  • putting the js code within Drupal.behaviors.myBehavior object solved the problem.
    – Abhi
    Jun 27 '18 at 23:57

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.