2

I have a form with an AJAX callback. I need to run some JavaScript when the form is submitted. Ive got this working by following the tutorial below:

http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7

However I already have a JavaScript file in the module and I would prefer to put my code in there. This file is loaded on page load so I think I would need to listen for an event and run when this was detected. Can I use the AJAX callback to trigger an event thats within a Drupal behaviour?

function after_ajax_form($form, &$form_state)
{
    // First we create a form element with AJAX enabled
    $form['ajax_example'] = array
    (
        '#type' => 'select',
        '#title' => t('Change me'),
        // Note that I am setting the value and the display of the elements to be the same, for convenience sake in our callback function
        '#options' => array(t('Select something') => t('Select something'), t('Something selected') => t('Something selected')),
        '#prefix' => '<div id="after_ajax_element_wrapper">',
        '#suffix' => '</div>',
        '#ajax' => array
        (
            'callback' => 'after_ajax_ajax_callback',
            'event' => 'change',
        ),
    );

    // Next we add our JavaScript file, named after_ajax.js. This file
    // lives in the /js folder inside our module:
    $form['#attached']['js'] = array
    (
        array
        (
            'type'  => 'file',
            'data' => drupal_get_path('module', 'after_ajax') . '/js/after_ajax.js',
        ),
    );
    return $form;
}


function after_ajax_ajax_callback($form, &$form_state)
{
    // First, we initialize our $commands array. This array will
    // contain each of the commands we want to fire for our
    // #AJAX callback:
    $commands = array();

    // Next, we create our insert function that will insert our updated content
    // back into the page. To do this, we use the system provided
    // ajax_command_html() function. We pass this function two values:
    // 1) Our AJAX wrapper (that we defined as the #prefix and #suffix of our form element)
    // 2) The rendered HTML that needs to be inserted into the wrapper in the page.
    $commands[] = ajax_command_html('#after_ajax_element_wrapper', render($form['ajax_example']));

    // Next, we will use the system provided ajax_command_alert() function as an example to show it's
    // working:
    $commands[] = ajax_command_alert(t('ajax_command_alert() is working'));

    // Next we will include a custom function that we will call ourselves in our JavaScript file:
    $commands[] = array
    (
        // The command will be used in our JavaScript file (see next section)
        'command' => 'afterAjaxCallbackExample',
        // We pass the value that the user selected in the select element to our
        // JavaScript function:
        'selectedValue' => $form_state['values']['ajax_example'],
    );

    // And finally, we will return all of our commands to the system to be executed:
    return array('#type' => 'ajax', '#commands' => $commands);
}




(function($, Drupal)
{
    // Our function name is prototyped as part of the Drupal.ajax namespace, adding to the commands:
    Drupal.ajax.prototype.commands.afterAjaxCallbackExample = function(ajax, response, status)
    {
        // The value we passed in our Ajax callback function will be available inside the
        // response object. Since we defined it as selectedValue in our callback, it will be
        // available in response.selectedValue. Usually we would not use an alert() function
        // as we could use ajax_command_alert() to do it without having to define a custom
        // ajax command, but for the purpose of demonstration, we will use an alert() function
        // here:
        alert(response.selectedValue);
    };
}(jQuery, Drupal));

1 Answer 1

3

AJAX callbacks only return an array of commands, and those commands are then executed by Drupal. It is the method I prefer when dealing with AJAX in Drupal.

Behaviors are attached to every page. If you really want to call the behavior, detached from a Drupal AJAX response, then your behavior needs to react when the form is submitted by attaching to that event without using AJAX event on the submit button of the form. See this answer: https://drupal.stackexchange.com/a/87600/57.

With an AJAX command, you can ensure that your command only executes if the form is validated without messing around with a lot of Javascript - though it depends on what you are doing. If you are showing a modal or some notification to the user about submitting the form, you may want to opt for the command so that you aren't running JS if the form did not really submit (i.e. not validated).

In your case, if you are using AJAX submission, then the submit event won't bubble up to the document. You can use ajax_command_invoke however to call a method. I recently had to do this on an AJAX'd form to push data to Google. Here is an example:

$commands[] = ajax_command_invoke(NULL, 'onFormSubmitSuccess');
return array('#type' => 'ajax', '#commands' => $commands);

Javascript file:

(function($) {
  $.fn.onFormSubmitSuccess = function(data) {
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      'event' : 'formSubmitted',
    });
  };
})(jQuery);

https://api.drupal.org/api/drupal/includes!ajax.inc/function/ajax_command_invoke/7

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.