By tce on
I have an AJAX form. I'm using drupal_add_js() after AJAX calls to update the 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. Does anyone know of a good workaround for this?
Comments
The current workaround I'm
The current workaround I'm using is overriding (just for that page) Drupal.ajax.prototype.commands.settings in ajax.js so settings gets replaced rather than merged.
If anyone has a better way, please let me know.
it's messing up my Javascript
Are we supposed to guess what you mean by this?
Contact me to contract me for D7 -> D10/11 migrations.
I'm marking this as solved.
Not to worry Jaypan. I'm marking this as solved.
This is definitely an
This is definitely an interesting topic and the same issue cropped up on me while using ajax to render Google maps. In my case, if I rendered a map with more than one marker and then tried to render a map with only one marker, the other markers showed up on the map that should only have one marker. Definitely not the desired result. I fixed this by adding the following lines with a '+' character in the first column under the settings section of ajax.js below:
While I shamefully admit this is very hackish since I'm modifying a core file, I have yet to figure out a more elegant way. It seems to me there should be a way to replace, rather than simply merge, Drupal.settings.
Settings are merged on
Settings are merged on purpose. To ensure you aren't overrwriting things, you should use $.once(). This will ensure that code is only run once on a given setting.
Contact me to contract me for D7 -> D10/11 migrations.
I think if there was ever a
I think if there was ever a case where you didn't want the settings merged, you could use ajax_command_settings()
https://api.drupal.org/api/drupal/includes%21ajax.inc/function/ajax_comm...
I recall having a similar problem with Google maps where when I updated my object with new markers, it was merging with old markers so using ajax_command_settings() was the way I ensured that only new markers were passed to JS via Drupal.settings.
"Settings are merged on
"Settings are merged on purpose." This is a narrow view of the issue. Sometimes when settings get merged instead of replaced, everything is overwrote correctly but then you have residual data that should be removed. In my case, I had extra map markers on my Google map display.
@tce Thanks for the
@tce Thanks for the suggestion, however, that doesn't work for me either. Apparently, the $merge value is never sent to ajax.js as FALSE. The response.merge value is always TRUE. Even if I explicitly set the value to FALSE or comment out all the merge lines so that only the ajax.settings = response.settings line exists as you suggested in your first comment, it still won't work (meaning the map won't render at all). Do you have any other possible suggestions or maybe I'm just not calling ajax_command_settings correctly? Do you mind sharing your code on how you solved the Google map marker issue?
I would do something like
I would do something like this:
@tce Thanks for sharing. I
@tce Thanks for sharing. I don't understand the $settings = call_user_func_array('array_merge_recursive', $js['settings']['data']); line. Why not just use $settings = $js['settings']['data']? What arrays are you merging? I tried a variation of your code in my callback function without success as shown below:
Is there anything I missed here?
Thanks
What does your code look like
What does your code look like, that you are using to generate the maps?
Contact me to contract me for D7 -> D10/11 migrations.
That's what the detach method
That's what the detach method of Drupal.behaviors, and the $.once() method are for, so you don't end up with this 'residual' behaviors.
Contact me to contract me for D7 -> D10/11 migrations.
After struggling for a while
After struggling for a while with a similar failure behaviour to get altered settings from back- to frontend, I found this method working best for me. :
Backend ajax (load more) callback :
Frontend wise :
If you just need to preserve
If you just need to preserve the idempotency of a single key (perhaps from a custom module), then do something like this: