Thu29Oct2015
Information
Print

Use jQuery in your Joomla! extensions: good practice and methodology

Information
jQuery
First published April 06, 2013
13624 hits -
 

More and more extensions built for the Joomla! framework are using the jQuery library. The library is getting more and more popular in those extensions and more issues arise from it. Problems of compatibility, not only with MooTools but with the multitude of templates, components or modules which try to load their own versions of the library and the most needed jQuery.noConflict(). Certainly, the jQuery Easy plugin has helped solve many problems in that sense. But what if we did not have to deal with these issues in the first place?

I have struggled in finding a solution for my own extensions. How can I make all of them work together seamlessly, while other templates, modules, components and/or Joomla! itself (starting version 3) may load jQuery for themselves?

The solution I finally came up with is a mix of good practice and feasibility. I gave it a lot of thought and hours of testing. This is not the ultimate solution but these are my 2 cents in trying to avoid jQuery issues on Joomla! websites.

The extensions

First off, if you are going to use jQuery in your extension, document which versions are compatible with it and are guaranteed to perform. The users of your work will make an educated guess when comes the time they have to decide which version of the library they can end up using on their sites.

  • Provide a way of de-activating jQuery from your extension. This is most needed to allow the users to shut off your library loading and allow another extension or template to provide that functionality. No matter how many extensions are loaded on a page, there is no need for more than one jQuery library.

  • Give the choice between local and CDN (Content Delivery Network) loading. The local loading will offer your users the ability to build their sites offline, while the loading from a CDN (like Google, Microsoft or the jQuery’s site itself) will give them the speed and reliability of those servers.
  • Create a list of all versions that the extension is compatible with (radio buttons or drop down). Users will be able to choose what version they want to use, especially if another extension (that is not your own) requires a specific version of the library which happens to be on your list (if not, these extensions will definitely won't work together), and use your extension to load the jQuery library.

Only use the latest versions of each major jQuery version, so you only offer a list with 1.5, 1.6, 1.7 and 1.8 for instance.  The version 1.8 would load jQuery 1.8.3.

Notes:

  • for all your extensions to work seamlessly together, they need at least one common version of the jQuery library. If you cannot find a common version, it is probably time for an update to some of the scripts you are using.
  • We could offer a strict ‘safe’ list of versions that are common to all your extensions but it is unlikely a user will use all of the extensions you provide and the more choices he has, the better the chances he will be able to make all the scripts on his page work together.



Do nothing!
Still, a message about the extension's jQuery compatibility is a good idea.
For instance, if web developers decide to use another version of jQuery that is not provided by the framework, they need to know that information.

The library 

Now, to allow all your extensions to work seamlessly together, you will need to create a library that will be the common 'engine' for the jQuery needs.

This unique library will need to be installed only once by your users. Set up a server update script that will trigger the automatic Joomla! update mechanism, making it easy for your users to update it if needed through the administration console (see the example file).

Set up an installation script in your extensions. It will allow you to test if the library is present and compatible with them. If the library is missing, provide a download link (see the example file).

It is possible to package the library with each extension but that can lead to incompatible versions of the library. Keeping the library out of your extensions will ensure you know they all work with the same version.

What will be included in the library:

  • The jQuery library files

Good practice in Joomla! is to use the /media folder to store all scripts, stylesheets and images that need to be web accessible. Not only you can reuse the same code and data for all your extensions, but it also allows the support of multi-sites and code separation.

Create your own folder in /media and include the versions of jQuery your extensions will use (in the library's xml file). Starting with Joomla! 3, the jQuery library is included in the package but you have no control over which version is available and you better watch for every update to make sure your extensions still work with it. So I suggest you keep your own versions. Your jQuery library file should contain the version number (for instance: jquery-1.8.3.min.js), which makes it easier for others to know what is used and will be easier to select through programming.

  • A version of the ‘no conflict’ code.

This code needs to be something specific and will be used in all your extensions, something like:

var myvariable = jQuery.noConflict();

Save it into a file that you will call myvariable.noconflict.js, the first part being the name of your variable. Add the file into the directory where your jQuery libraries are located.
Doing so will make your extensions work in the same namespace, without any risk of collision with other function calls. It will also ensure you do not add another jQuery.noConflict() declaration on to the page, which you have no control over.
Note: if some extensions are using third-party scripts, add them to the library. Create a new folder for each.

  • A PHP class with the necessary function calls

The library needs to provide calls to the jQuery library versions that are available (locally or not) and to the noConflict() code.

static function loadJQuery($local, $version)

will load jQuery locally or not and for which ever version,

static function loadJQueryNoConflict()

will load the noConflict() declaration.
Note that these functions are static and include static variables that will be checked. It will ensure that the jQuery library and noConflict() declaration will be included only once on the website page, even if your user mistakenly setup jQuery on more than one of the extensions .

Note:

  • Create other load functions for all the third party scripts added to the library.
  • Use the library to include code common to your extensions (custom fields, helpers...).

Back to the extensions

In the extensions, all javascript code requiring jQuery will need to be included in:

myvariable(document).ready(function($) {});

jQuery(document).ready(function($) {});

All jQuery functions need to be encapsulated in:

(function($) {})(jQuery);

The ‘$’ can be used in the function without any risk of colliding with any other library like MooTools.


Call the jQuery library if the user selected to do so (locally or not).
Always call the noConflict() script from your extensions, even if no jQuery is loaded from them. This way, it will ensure the first of your extensions will load the declaration, not the following ones and all script calls will be in order.


Call the jQuery library with:

JHtml::_('jquery.framework');

It will load jQuery, Migrate (starting with Joomla! 3.2) and the no conflict code locally from the framework. ONLY one library will be loaded, no matter how many calls to it are made.

Migrate is used to ensure all scripts remain backup compatible with the newest version of the jQuery library.

Good practice would be avoiding loading Migrate if your code does not require it.

JHtml::_('jquery.framework', true, null, false);

where the 1st parameter loads noConflict code, the 2nd deals with debugging and the 3rd loads Migrate.

And that's it!

From now on, all jQuery calls are made the right way and there is no risk of causing conflicting issues on your user’s sites, either with MooTools or other jQuery calls.