Drupal.settings merging when using AJAX I have an AJAX form. I'm using drupal_add_js() after AJAX calls to update 'settings' and pass new information to my Drupal.behaviour object. However, the results are being merged instead of replaced. I know this is by design but it's messing up my Javascript code because I end up with information from the last callback. Does anyone know of a good workaround for this?

Update:

Current workaround is overriding the code so settings is replaced rather than merged, though only for the page my form is in.

Drupal.ajax.prototype.commands.settings = function (ajax, response, status) {
  ajax.settings = response.settings;
};


Feels wrong, but things are working as expected.

Solution:

The final solution I used, as solved by Alice Heaton, isn't to override code in ajax.js, instead I returned both the form and an AJAX command in the forms AJAX callback:

function my_ajax_callback($form, $form_state) {
  $commands = array();
  $commands[] = ajax_command_settings(array(
    'key1' =&gt; 'value1',
    'key2' =&gt; 'value2',
  ));
  $output = drupal_render($form['locator']);
  $commands[] = ajax_command_insert(NULL, $output);

  return array('#type' =&gt; 'ajax', '#commands' =&gt; $commands);
}
So when you use drupal_add_js to add settings during an ajax callback, this indeed merges the results. On the server side this is done in ajax_render (called from ajax_deliver or equivalent) which adds an ajax_command_settings command, instructing it to merge the results.

On the client side the merging is done by calling jQuery.extend, which causes the behaviour you have seen, and cannot be changed.

There is no work around if you want your results to be inserted into Drupal.settings. However you can pass your settings to your behaviour directly without using Drupal.settings. For this you would add a call to ajax_command_settings yourself. It would be something like this:

function mymodule_ajax_callback() {
  $commands = array();
  // ...
  $commands[] = ajax_command_settings(array(
    'key1' =&gt; 'value1',
    'key2' =&gt; 'value2',
  ));
  ajax_deliver(array(
    '#type' =&gt; 'ajax',
    '#commands' =&gt; $commands
  ));
}


Note that if your callback is called fom the Form API's #ajax['callback'] then it runs ajax_deliver on the value returned by the callback, so you shouldn't call it yourself.

On your script on the client side, your settings will be available as the second parameter of your behaviour attach method:

Drupal.behaviors.mymodule = {
  attach: function (context, settings) {
    // Here settings contains your settings
  }
};


(edit: sorry, previous answer was very wrong)