J3.x

Adding JavaScript and CSS to the page

From Joomla! Documentation

Revision as of 02:57, 1 July 2014 by Cppl (talk | contribs) (→‎JHtml::stylesheet: Changed code sample to actually use JHtml::stylesheet() rather than JHtml::script())
Info non-talk.png
API Change

The API of the JHtml::script() and JHtml::stylesheet() method changed after Joomla 1.5 - it worked but was deprecated in Joomla 2.5 and support for the old API was removed in Joomla 3.x

Inserting from a File[edit]

To have a well-formed HTML document, you must put all references to Javascript and CSS files within the <head> portion. Since Joomla! generates all the HTML that makes up a page before output, it is possible to add these references within the <head> tags from your extension. The simplest way to do this is to make use of the functionality built in to Joomla!

JDocument[edit]

This is a much less flexible option. However it is more efficient for a large number of scenarios such as including a stylesheet in a template. Of course, you will also need to manually code some of the steps that would be done automatically using the JHtml method below.

First, get a reference to the current document object:

$document = JFactory::getDocument();

Then for a stylesheet, use this code:

$document->addStyleSheet($url);

To add a Javascript file, use this code:

$document->addScript($url);

where $url is the variable containing the full path to the javascript or CSS file for example: JUri::base() . 'templates/custom/js/sample.js'

Note this will **NOT** include Mootools or jQuery. If your script requires Mootools or jQuery see Javascript_Frameworks for full details on how to include them (note jQuery can only be included natively on Joomla 3.0+).

JHtml[edit]

JHtml offers much more flexibility than JDocument, whilst using the same base functionality - indeed at the end of the day JHtml will call JFactory::getDocument()->addStyleSheet() or JFactory::getDocument()->addScript().

If you wish to just include a straight file path, in a template for example, then you are better using JDocument. However if you wish to take into account whether debug is enabled to include a compressed script or take advantage of template overridable scripts and stylesheets then using JHtml is generally better. It is recommended all 3rd Party Developers use JHtml to allow template overrides of their CSS and javascript for template designers.

JHtml::script[edit]

Using JHtml to include a javascript file can bring you several benefits. The first of these is if your javascript file has a mootools dependency then you can automatically include it by setting the second parameter of this method to true as below

<?php
JHtml::script(JUri::base() . 'templates/custom/js/sample.js', true);
?>

The third parameter of this method allows template overridable javascript files to allow greater customization of extensions. The first parameter is now assumes you are starting in the JPATH_BASE/media folder - within here you specify your extension name followed by the name of your javascript file. The path searched is then JPATH_BASE/media/com_search/js/search.js for the following JHtml snippet

<?php
JHtml::script('com_search/search.js', false, true);
?>

Note the js subdirectory that is searched in the com_search directory shouldn't be specified in the JHtml method.

However on top of this if a file exists in js/com_search/search.js then this will be included instead. For example say a extension has a mootools dependent file but the user only wants jQuery to be loaded. This means that a user could override the file with a jQuery version.

By default Joomla will automatically include a compressed and uncompressed version of any scripts depending on whether debug mode is turned off or on. Call your compressed script search.min.js and the uncompressed version script-uncompressed.js to use this functionality and aid with debugging of any scripts.

Furthermore you can include browser specific files. Joomla can look for the files of the following types

  • filename.ext
  • filename_browser.ext
  • filename_browser_major.ext
  • filename_browser_major_minor.ext

This can allow you to include internet explorer 6 specific files for example. By having a search.js for general use with a search_msie_6.js for a file with extra internet explorer 6 fixes.

JHtml::stylesheet[edit]

Using JHtml to include a CSS file can bring you several benefits. The first of these is allowing template overridable CSS files to allow greater customization of extensions. Setting the third parameter to true now assumes you are starting in the JPATH_BASE/media folder - within here you specify your extension name followed by the name of your CSS file. The path searched is then JPATH_BASE/media/com_search/css/search.css for the following JHtml snippet

<?php
JHtml::stylesheet('com_search/search.css', array(), true);
?>

Note the css subdirectory that is searched in the com_search directory shouldn't be specified in the JHtml method.

However on top of this if a file exists in css/com_search/search.css then this will be included instead. This allows people to customize the appearance of an extension to better match their templates styling.

Furthermore you can include browser specific files. Joomla can look for the files of the following types

  • filename.ext
  • filename_browser.ext
  • filename_browser_major.ext
  • filename_browser_major_minor.ext

This can allow you to include internet explorer 6 specific files for example. By having a search.css for general use with a search_msie_6.css for a file with extra internet explorer 6 fixes.

Inserting inline scripts from within a PHP file[edit]

If your Javascript or CSS are generated using PHP, you can add the script or stylesheet directly into the head of your document:

$document = JFactory::getDocument();

// Add Javascript
$document->addScriptDeclaration('
    window.event("domready", function() {
        alert("An inline JavaScript Declaration");
    });
');

// Add styles
$style = 'body {'
        . 'background: #00ff00;'
        . 'color: rgb(0,0,255);'
        . '}'; 
$document->addStyleDeclaration($style);

Javascript Example[edit]

For example, the following code is used to define a custom tool tip that takes advantage of mootools.

function getToolTipJS($toolTipVarName, $toolTipClassName){
    $javascript = 'window.addEvent(\"domready\", function(){' ."\n";
    $javascript .= "\t"  .'var $toolTipVarName = new Tips($$("' . $toolTipVarName .'"), {' ."\n";
    $javascript .= "\t\t"   .'className: "' .$toolTipClassName .'",' ."\n";
    $javascript .= "\t\t"   .'initialize: function(){' ."\n";
    $javascript .= "\t\t\t"    .'this.fx = new Fx.Style(this.toolTip, "opacity", {duration: 500, wait: false}).set(0);' ."\n";
    $javascript .= "\t\t"   .'},' ."\n";
    $javascript .= "\t\t"   .'onShow: function(toolTip){' ."\n";
    $javascript .= "\t\t\t"    .'this.fx.start(1);' ."\n";
    $javascript .= "\t\t"   .'},' ."\n";
    $javascript .= "\t\t"   .'onHide: function(toolTip) {' ."\n";
    $javascript .= "\t\t\t"    .'this.fx.start(0);' ."\n";
    $javascript .= "\t\t"   .'}' ."\n";
    $javascript .= "\t"  .'});' ."\n";
    $javascript .= '});' ."\n\n";
    return $javascript;
}

$document = JFactory::getDocument();
$document->addStyleSheet("/joomla/components/com_mycustomcomponent/css/mytooltip.css",'text/css',"screen");
$document->addScriptDeclaration(getToolTipJS("mytool","MyToolTip"));

Note that in order for this Javascript to be functionally useful, it would be necessary to include the appropriate class name in the HTML, as well as providing the mytooltip.css file. Both are outside the scope of this article.

CSS Examples[edit]

This is also useful if your inserting a form field of CSS into your code. For example in a module, you might want a user to choose to call the colour of the border. After calling the form fields value and assigning it a variable $bordercolor in mod_example.php. Then in tmpl/default.php you can include the following

$document = JFactory::getDocument();
$document->addStyleSheet('mod_example/mod_example.css', array(), true);
$style = '#example {
	border-color:#' . $bordercolor . ';
	}';
$document->addStyleDeclaration( $style );

Here mod_example.css contains the CSS file of any non-parameter based styles. Then the bordercolor parameter/form field is added in separately

Add Custom Tag[edit]

There will be some occasions where even these functions are not flexible enough, as they are limited to writing the contents of <script /> or <style /> tags, and cannot add anything outside those tags. One example would be the inclusion of a stylesheet link within conditional comments, so that it is picked up only by Internet Explorer 6 and earlier. To do this, use $document->addCustomTag:

$stylelink = '<!--[if lte IE 6]>' ."\n";
$stylelink .= '<link rel="stylesheet" href="../css/IEonly.css" />' ."\n";
$stylelink .= '<![endif]-->' ."\n";

$document = JFactory::getDocument();
$document->addCustomTag($stylelink);