Long story short:
We’ve had errors being logged concerning a JQuery/JQueryUI based system for some time. At it’s core we’re doing a pretty basic click link -> JQuery AJAX GET -> Open JQueryUI modal pattern.
The error we were getting appeared simple – “Object doesn’t support property or method ‘dialog'” – leading us to believe there was an error with JQueryUI. After expending a lot of time ruling out browser incompatibilities, bad code on JQuery’s end, bad code on our end, angry code gods… we caught a lucky break. A 100% repro on one of the machines in the office.
Turns out the thing was riddled with adware – specifically [an older version of] easyinline – http://www.easyinline.com. When the user clicked any link a cascade of javascript files would be loaded, including reloading JQuery from Google’s CDN.
For most links this isn’t really a problem – they take you off the page anyway and everything reloads. But for our modals it meant that every modal link would stamp over our JQuery at the point the request was sent, resulting in the response trying to make use of the ‘new’ $ which would now be missing JQueryUI and any other plugins.
Initially we thought about making another global var ($$ or something) for ‘our’ JQuery and explicitly using that in our code instead of just $. The issue with that is that we were using a few other 3rd party tools which rely on $ and the adware-loaded $ is a different (older) version. So it’s important that we preserve $ correctly.
Any ideas? I’m aware of JQuery’s noConflict() method but after a cursory glance don’t think it fits the bill.
Ultimately we’ve decided to re-establish our JQuery integrity when we receive any ajax responses (i.e. just before the open modal code is executed). All our ajax stuff is wrapped in our own handler so this was fairly easy to inject across the board.
Basically;
We have the original JQuery ‘saved’ – we’ve got it in-scope thanks to our handler but it could be easily put into a separate global (like $$) just after it is loaded. In our ajax response handler we’ve got a fairly straightforward check;
This will reset the global jquery back to what it should be.