Using JavaScript Effects with Joomla!

Exclusive offer: get 50% off this eBook here
Learning Joomla! 1.5 Extension Development

Learning Joomla! 1.5 Extension Development — Save 50%

A practical tutorial for creating your first Joomla! 1.5 extensions with PHP, written and tested against the final release of Joomla! 1.5

£16.99    £8.50
by | November 2008 | Joomla! MySQL Content Management Open Source PHP

Although Joomla! has all of the basic content management tools you need to build a website, it is also designed to run custom-built extensions written in PHP. This article steps through working examples of PHP code written to work seamlessly in Joomla!. Modern websites use JavaScript-driven effects to aid navigation, reduce on-screen clutter, and provide interactive features that are not possible with static HTML.

Joomla! has several built-in elements that you can use without writing a single line of JavaScript. The MooTools framework powers many elements seen throughout the Joomla! backend UI; these can be reused in both the frontend and the backend of your Joomla! component. In this article by Joseph L. LeBlanc, we will learn to use JavaScript effects through these topics:

  • Customizing Google Maps

Customizing Google Maps

Google Maps has a comprehensive API for interacting with maps on your website. MooTools can be used to load the Google Maps engine at the correct time. It can also act as a bridge between the map and other HTML elements on your site.

To get started, you will first need to get an API key to use Google Maps on your domain. You can sign up for a free key at http://code.google.com/apis/maps/signup.html. Even if you are working on your local computer, you still need the key. For instance, if the base URL of your Joomla installation is http://localhost/joomla, you will enter localhost as the domain for your API key.

Once you have an API key ready, create the file basicmap.js in the /components/com_js folder, and fill it with the following code:

window.addEvent('domready', function() 
{
if (GBrowserIsCompatible())
{
var map = new GMap2($('map_canvas'));
map.setCenter(new GLatLng(38.89, -77.04), 12);
window.onunload=function()
{
GUnload();
};
}
});

The entire script is wrapped within a call to the MooTools-specific addEvent() member function of window. Because we want this code to execute once the DOM is ready, the first parameter is the event name 'domready'. The second parameter is an anonymous function containing our code.

What does the call to function() do?
Using function() in JavaScript is a way of creating an anonymous function. This way, you can create functions that are used in only one place (such as event handlers) without cluttering the namespace with a needless function name. Also, the code within the anonymous function operates within its own scope; this is referred to as a closure. Closures are very frequently used in modern JavaScript frameworks, for event handling and other distinct tasks.

Once inside of the function, GBrowserIsCompatible() is used to determine if the browser is capable of running Google Maps. If it is, a new instance of GMap2() is declared and bound to the HTML element that has an id of 'map_canvas' and is stored into map. The call to $('map_canvas') is a MooTools shortcut for document.GetElementById().

Next, the setCenter() member function of map is called to tell Google Maps where to center the map and how far to zoom in. The first parameter is a GLatLng() object, which is used to set the specific latitude and longitude of the map's center. The other parameter determines the zoom level, which is set to 12 in this case. Finally, the window.onunload event is set to a function that calls GUnload(). When the user navigates away from the page, this function removes Google Maps from memory, to prevent memory leaks.

With our JavaScript in place, it is now time to add a function to the controller in /components/com_js/js.php that will load it along with some HTML. Add the following basicMap() function to this file:

function basicMap()
{
$key = 'DoNotUseThisKeyGetOneFromCodeDotGoogleDotCom';
JHTML::_('behavior.mootools');
$document =& JFactory::getDocument();
$document->addScript('http://maps.google.com/maps?file=api&v=
2&key=' . $key);
$document->addScript(
JURI::base() . 'components/com_js/basicmap.js');
?>
<div id="map_canvas" style="width: 500px; height: 300px"></div>
<?php
}

The basicMap() function starts off by setting $key to the API key received from Google. You should replace this value with the one you receive at http://code.google.com/apis/maps/signup.html. Next, JHTML::_('behavior.mootools'); is called to load MooTools into the <head> tag of the HTML document. This is followed by getting a reference to the current document object through the getDocument() member function of JFactory. The addScript() member function is called twice—once to load in the Google Maps API (using our key), then again to load our basicmap.js script. (The Google Maps API calls in all of the functions and class definitions beginning with a capital 'G'.)

Finally, a <div> with an id of 'map_canvas' is sent to the browser. Once this function is in place and js.php has been saved, load index.php?option=com_js&task=basicMap in the browser. Your map should look like this:

Using JavaScript Effects with Joomla!

We can make this map slightly more interesting by adding a marker to a specific address. To do so, add the highlighted code below to the basicmap.js file:

window.addEvent('domready', function() 
{
if (GBrowserIsCompatible())
{
var map = new GMap2($('map_canvas'));
map.setCenter(new GLatLng(38.89, -77.04), 12);

var whitehouse = new GClientGeocoder();
whitehouse.getLatLng('1600 Pennsylvania Ave NW',
function(latlng)
{
marker = new GMarker( latlng );
marker.bindInfoWindowHtml('<strong>The White
House</strong>');
map.addOverlay(marker);
});

window.onunload=function(){
GUnload();
};
}
});

This code sets whitehouse as an instance of the GClientGeocoder class. Next, the getLatLng() member function of GClientGeocoder is called. The first parameter is the street address to be looked up. The second parameter is an anonymous function where the GLatLng object is passed once the address lookup is complete. Within this function, marker is set as a new GMarker object, which takes the passed-in latlng object as a parameter. The bindInfoWindowHTML() member function of GMarker is called to add an HTML message to appear in a balloon above the marker. Finally, the maker is passed into the addOverlay() member function of GMap2, to place it on the map.

Save basicmap.js and then reload index.php?option=com_js&task=basicMap. You should now see the same map, only with a red pin. When you click on the red pin, your map should look like this:

Using JavaScript Effects with Joomla!

Interactive Maps

These two different maps show the basic functionality of getting Google Maps on your own website. These maps are very basic; you could easily create them at maps.google.com then embed them in a standard Joomla! article with the HTML code they provide you. However, you would not have the opportunity to add functions that interact with the other elements on your page. To do that, we will create some more HTML code and then write some MooTools-powered JavaScript to bridge our content with Google Maps.

Open the /components/com_js/js.php file and add the following selectMap() function to the controller:

function selectMap()
{
$key = 'DoNotUseThisKeyGetOneFromCodeDotGoogleDotCom';
JHTML::_('behavior.mootools');
$document =& JFactory::getDocument();
$document->addScript('http://maps.google.com/maps?file=api&v
=2&key=' . $key);
$document->addScript(
JURI::base() . 'components/com_js/selectmap.js');
?>
<div id="map_canvas" style="width: 500px; height: 300px"></div>
<select id="map_selections">
<option value="">(select...)</option>
<option value="1200 K Street NW">Salad Surprises</option>
<option value="1221 Connecticut Avenue NW">The Daily
Dish</option>
<option value="701 H Street NW">Sushi and Sashimi</option>
</select>
<?php
}

This function is almost identical to basicMap() except for two things—selectmap.js is being added instead of basicmap.js, and a <select> element has been added beneath the <div>. The <select> element has an id that will be used in the JavaScript. The options of the <select> element are restaurants, with different addresses as values. The JavaScript code will bind a function to the onChange event so that the marker will move as different restaurants are selected.

Learning Joomla! 1.5 Extension Development A practical tutorial for creating your first Joomla! 1.5 extensions with PHP, written and tested against the final release of Joomla! 1.5
Published: December 2008
eBook Price: £16.99
Book Price: £24.99
See more
Select your format and quantity:

To add this JavaScript, create a file named selectmap.js in the /components/com_js folder, and fill it with the following code:

window.addEvent('domready', function() 
{
if (GBrowserIsCompatible())
{
var map = new GMap2($('map_canvas'));
map.setCenter(new GLatLng(38.89, -77.04), 12);
var restaurant = new GClientGeocoder();
$('map_selections').addEvent('change', function(){
if(this.value != '')
{
name = this.options[this.selectedIndex].text;
restaurant.getLatLng(this.value, function(latlng){
map_marker = new GMarker( latlng );
map.clearOverlays();
map.addOverlay(map_marker);
map_marker.openInfoWindowHtml('<strong>' + name +
'</strong>');
});
}
});
window.onunload=function()
{
GUnload();
};
}
});

This script is similar to the one used for the first two maps, until we get past the call to map.setCenter(). The variable restaurant is first set as an instance of the GClientGeocoder() class. However, member functions are not called on it right away, as it was done in the previous example. This is because we want to wait for the <select> element to change before we do anything. The call to $('map_selections') finds the <select> element, and then addEvent() is used to assign a function to the onChange event; the string 'change' is passed as the first parameter.

The function passed in as the second parameter first checks to make sure that the element's value is not null by checking this.value. If the value is not null, this function proceeds by getting the option's text and storing it in name. Then the getLatLng() member function of GClientGeocoder is called on restaurant. The street address is passed in as the first parameter. Once the latitude and longitude of the address is found, the anonymous function in the second parameter accepts the GLatLng object that is returned, using it to set map_marker as a new GMarker object.

Before adding the marker to the map, the clearOverlays() function of the map object is called to remove any previously-placed marker. Then, the marker is passed into the addOverlay() function to be placed on the map. Although the marker is now set on the map, we can still interact with it. The openInfoWindowHtml() member function of GMarker allows us to do this and pass in some HTML with the name of the restaurant.

With the controller function and JavaScript in place and saved, load index.php?option=com_js&task=selectMap in your browser. The map should load again, this time with a dropdown box at the bottom. Select one of the restaurants, and then switch to another. If you select Sushi and Sashimi from the list, your map should look similar to the following:

Using JavaScript Effects with Joomla!

These examples scratch the surface of what is possible with the Google Maps API. You can manage layers, add shapes, use custom icons instead of the standard pins, and use many other features to build sophisticated custom maps. For more information, go to http://code.google.com/apis/maps/documentation/index.html where you can read more about the available features.

Using jQuery

Another popular JavaScript framework is jQuery. The jQuery framework has functionality that is similar to MooTools, but uses a different style of code. Although they are separate projects, extra care must be taken when using them together. By default, both frameworks automatically reserve $ to have a special meaning in JavaScript. If you do not take steps to avoid this behavior, one library will overwrite the other's assignments and the scripts will fail.

Fortunately, jQuery has strategies that you can use to avoid this conflict. There are three things that you must do to keep jQuery and MooTools out of each other's way:

  • Load jQuery only after MooTools has been loaded
  • Call jQuery.noConflict() to return control of $ to MooTools
  • Reference jQuery directly in your scripts instead of using $

Writing jQuery code

Before avoiding conflicts with MooTools, start by writing some jQuery without MooTools being present. First, go to jquery.com, download the latest version of jQuery, and then place it in the /components/com_js directory; the production version of the script will be fine. Then, create a file named jquery-test.js in the /components/com_js folder, and fill this new file with the following code:

$(document).ready(function() 
{
$('#message_box').click(function()
{
$(this).addClass('contentheading');
});
});

This is a simple application of jQuery—when the DOM is fully loaded in the browser, the code within the first call to function() executes. The code $('#message_box') finds the element in the DOM that has an id of 'message_box', and uses click() to assign an onClick JavaScript event to it. Finally, the addClass() method is used to add the CSS class 'contentheading' to the element.

With jquery-test.js in place, open the /components/com_js/js.php file, and add the following function task to the controller:

function useJquery()
{
$document =& JFactory::getDocument();
$document->addScript(
JURI::base() . 'components/com_js/jquery-1.2.6.min.js');
$document->addScript(
JURI::base() . 'components/com_js/jquery-test.js');
?>
<p id="message_box">This is a message</p>
<?php
}

First, a reference to the document object is stored in $document by using the getDocument() member function of JFactory. Next, the addScript() member function is used to add the jQuery framework and our test script. Finally, a paragraph tag with the id 'message_box', and containing a short message, is output. Load index.php?option=com_js&task=useJquery in your browser, and click on the This is a message link. Your screen should now look similar to this:

Using JavaScript Effects with Joomla!

Using jQuery with MooTools

The code that we just wrote works fine on its own, but will fail right now if we attempt to also use a MooTools-driven effect. To remedy this, we need to make an adjustment to our script and invoke jQuery's noConflict mode. Open the file /components/com_js/js.php and add the following function to the controller:

function useJqueryAndMooTools()
{
JHTML::_('behavior.tooltip');

$document =& JFactory::getDocument();
$document->addScript(
JURI::base() . 'components/com_js/jquery-1.2.6.min.js');

$document->addCustomTag('<script type="text/javascript">
jQuery.noConflict();
</script>');


$document->addScript(
JURI::base() . 'components/com_js/jquery-test.js');

?>

<p id="message_box">This is a message</p>
<span class="hasTip" title="Click here to go to the home page">
<a href="index.php">Homepage</a>
</span>


<?php
}

The highlighted portions of useJqueryAndMooTools() are the added pieces that differentiate it from useJquery(). The call to JHTML::_('behavior.tooltip'); loads the code necessary for the tooltip, including MooTools. Because MooTools is now being loaded, we use the addCustomHeadTag() member function of the document object to make a quick call to jQuery.noConflict(); so that $ is left for MooTools. Finally, an anchor tag wrapped in a <span> element has been added with the tooltip information.

If you save js.php and load index.php?option=com_js&task=useJqueryAndMooTools now, you will get an error; we have not yet adjusted jquery-test.js to account for the call to jQuery.noConflict();. Open jquery-test.js and make the highlighted adjustment:

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

$('#message_box').click(function() {

$(this).addClass('contentheading');
});
});

Because the $ shortcut is no longer available, we must call the jQuery function by name. However, we can regain control of the $ shortcut within our jQuery code. This is because the call to function() allows us to pass a reference to the jQuery function into the local scope, with any desired name. Because $ has been specified as the parameter of function(), the rest of the code can use it without further modification.

Load index.php?option=com_js&task=useJqueryAndMooTools in your browser, click on the This is a message link, then move and the mouse over the Homepage link. Your screen should look similar to this:

Using JavaScript Effects with Joomla!

Always load MooTools first

The trick to using jQuery and MooTools together in Joomla! is to make sure that MooTools loads before jQuery does. In the useJqueryAndMooTools() function, if you move the call to JHTML::_('behavior.tooltip'); any time after the call to addScript() that loads in jQuery, an error will occur. Instead, MooTools must load first and define $. Then jQuery.noConflict(); can be called to return $ back to its original assignment.

This is easily managed when you know and can control every instance where MooTools is used. However, if you are building a self-contained extension for others to use, it is quite possible that they are using other extensions that load MooTools. For instance, if someone has a module for a photo gallery that uses MooTools, the MooTools framework will be added to the <head> section of the HTML document after your component with jQuery loads. This will cause a JavaScript error.

The safest way of avoiding this situation is to force the MooTools library to load in your extension before you load jQuery. To do this, simply add JHTML::_('behavior.mootools'); in your extension before adding the jQuery framework to <head>. The call to JHTML::_('behavior.mootools'); detects whether MooTools has been loaded yet, and loads it now if it has not.

A downside to this workaround is that the MooTools framework will be included even if it is never used. This will slow down the load time of your site slightly and use resources in the JavaScript environment. If you are building an extension that will not be distributed or reused, you can hard-code the references to jQuery in your template after <jdoc:include type="head" />. In this scenario, jQuery will be loaded on every page and will eventually be used where you determine. If MooTools is loaded by another extension, it will happen before jQuery is initialized.

Summary

In this article, we have discussed how to customize Google Maps on our Joomla! component and how to use JQuery effectively to further enhance the component's functionality. Joomla! is ready for your latest JavaScript needs. By using the MooTools JavaScript framework, you can find elements and assign event handlers to them. You can also use pre-built functions within Joomla! to generate the JavaScript necessary for many typical effects.You can also use jQuery with MooTools in Joomla!, provided that you take precautions to make sure that the frameworks do not conflict.

 

Learning Joomla! 1.5 Extension Development A practical tutorial for creating your first Joomla! 1.5 extensions with PHP, written and tested against the final release of Joomla! 1.5
Published: December 2008
eBook Price: £16.99
Book Price: £24.99
See more
Select your format and quantity:

About the Author :


Joseph L. LeBlanc

Joseph L. LeBlanc started with computers at a very young age. His independent education gave him the flexibility to experiment and learn computer science. Joseph holds a bachelor’s degree in Management Information Systems from Oral Roberts University. Joseph is currently a freelance Joomla! extension developer. He released a component tutorial in May 2004, which was later translated into French, Polish, and Russian. Work samples and open-source extensions are available at www.jlleblanc.com. In addition to freelancing, he is a board member of the DC PHP Conference. He has also worked as a programmer for a web communications firm in Washington, DC.

Books From Packt

Building Websites with Joomla! 1.5
Building Websites with Joomla! 1.5

Drupal 6 Themes
Drupal 6 Themes

PHP 5 CMS Framework Development
PHP 5 CMS Framework Development

Mastering phpMyAdmin 2.11 for Effective MySQL Management
Mastering phpMyAdmin 2.11 for Effective MySQL Management

Building Powerful and Robust Websites with Drupal 6
Building Powerful and Robust Websites with Drupal 6

Learning Joomla! 1.5 Extension Development: Creating Modules, Components, and Plugins with PHP
Learning Joomla! 1.5 Extension Development: Creating Modules, Components, and Plugins with PHP

Joomla! Web Security
Joomla! Web Security

Learning Ext JS
Learning Ext JS

 


 

 

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software