J3.x

Adding JavaScript and CSS to the page: Difference between revisions

From Joomla! Documentation

MATsxm (talk | contribs)
Marked this version for translation
Robbiej (talk | contribs)
Added deprecation notice and link to Joomla Manual
 
(21 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{Warning|This page has been superseded and is no longer maintained. Please go to [https://manual.joomla.org/docs/general-concepts/javascript/adding-javascript/ Joomla Manual ] instead}}
<noinclude><languages /></noinclude>
<noinclude><languages /></noinclude>
{{notice|<translate><!--T:1-->
<translate>
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</translate>|title=<translate><!--T:2-->
<!--T:52-->
API Change</translate>}}
This is one of a series of [[API Guides]], which aim to help you understand how to use the Joomla APIs through providing detailed explanations and sample code which you can easily install and run.</translate>


<translate>
<translate>
== Inserting from a File == <!--T:3-->
== Inserting from a File == <!--T:3-->
</translate>
</translate>
<translate><!--T:4-->
To have a well-formed HTML document, you must put all references to Javascript and CSS files within the <code><head></code> 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.</translate>


<translate>
<translate>
===JDocument=== <!--T:5-->
<!--T:53-->
</translate>
Joomla allows you to add JavaScript and CSS files to your HTML document, and it puts the associated ''<script>'' and ''<link>'' elements within the HTML ''<head>'' section. To do this you call the ''addScript'' and ''addStyleSheet'' methods of the Joomla object which represents the HTML document. Since Joomla! buffers all the HTML-related data that makes up a page before output, it is possible to call these methods anywhere within your code. </translate>
<translate><!--T:6-->
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.</translate>


<translate><!--T:7-->
<translate><!--T:7-->
First, get a reference to the current document object:</translate>
First, get a reference to the current document object:</translate>


<source lang="php">
<syntaxhighlight lang="php">
$document = JFactory::getDocument();
use Joomla\CMS\Factory;
</source>
$document = Factory::getDocument();
// above 2 lines are equivalent to the older form: $document = JFactory::getDocument();
</syntaxhighlight>


<translate><!--T:8-->
<translate><!--T:8-->
Then for a stylesheet, use this code:</translate>
Then for a style sheet, use this code:</translate>


<source lang="php">
<syntaxhighlight lang="php">
$document->addStyleSheet($url);
$document->addStyleSheet($url);
</source>
</syntaxhighlight>


<translate><!--T:9-->
<translate><!--T:9-->
To add a Javascript file, use this code:</translate>
To add a JavaScript file, use this code:</translate>


<source lang="php">
<syntaxhighlight lang="php">
$document->addScript($url);
$document->addScript($url);
</source>
</syntaxhighlight>


<translate><!--T:10-->
<translate><!--T:10-->
where <code>$url</code> is the variable containing the full path to the javascript or CSS file for example:</translate>
where ''$url'' is the variable containing the full path to the JavaScript or CSS file. For example:</translate>
<code>JUri::base() . 'templates/custom/js/sample.js'</code>
''JUri::base() . 'templates/custom/js/sample.js'''


<translate><!--T:11-->
<translate><!--T:11-->
Note this will **NOT** include Mootools or jQuery. If your script requires Mootools or jQuery see [[S:MyLanguage/Javascript_Frameworks|Javascript Frameworks]] for full details on how to include them (note jQuery can only be included natively on Joomla! 3.0+).</translate>
Note this will '''not''' include Mootools or jQuery. If your script requires Mootools or jQuery see [[S:MyLanguage/Javascript_Frameworks|JavaScript Frameworks]] for full details on how to include them. (Note that jQuery can only be included natively on Joomla! 3.0+.)</translate>
<translate><!--T:6-->
It used to be possible to do this with JHTML, however, this was deprecated in Joomla 2.5 and removed in Joomla 3.x.
</translate>


<translate>
<translate>
===JHtml=== <!--T:12-->
=== $options and $attributes Parameters === <!--T:54--></translate>
</translate>
<translate>
<translate><!--T:13-->
<!--T:55-->
JHtml offers much more flexibility than JDocument, whilst using the same base functionality - indeed at the end of the day JHtml will call</translate> <code>JFactory::getDocument()->addStyleSheet()</code> <translate><!--T:14-->
You can add ''$options'' and ''$attributes'' parameters to the above methods. The ''$options'' control overall how the ''<script>'' and ''<link>'' elements are output while the ''$attributes'' get set as HTML attributes within those tags. (Note that although there are Deprecated markers against the addScript and addStyleSheet methods of the [https://api.joomla.org/cms-3/classes/Joomla.CMS.Document.Document.html#method_addScript Joomla Document API], these markers refer just to the signature of these methods; the form of the signature using ''$options'' and ''$attributes'' parameters is not deprecated).</translate>
or</translate> <code>JFactory::getDocument()->addScript()</code>.
<translate>
 
<!--T:56-->
<translate><!--T:15-->
The ''$options'' parameter should be an array and 2 different options are currently supported:</translate>
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.</translate>
<translate>
<!--T:57-->
* ''version => auto'' If this is set then a 'media version' is appended as a query parameter to the CSS or JavaScript URL within the ''<script>'' or ''<link>'' element. This is a string (an md5 hash) that is generated from factors including the Joomla version, your Joomla instance ''secret'' and the date/time at which the media version was generated. The media version is regenerated whenever anything is installed on the Joomla instance. Its purpose is to force browsers to reload the CSS and JavaScript files instead of using possibly outdated versions from cache.</translate>
<translate>
<!--T:58-->
For example</translate>
<syntaxhighlight lang="php">
$document->addStyleSheet("...demo.css", array('version'=>'auto'));
// leads to something like
// <link href="...demo.css?37e343bbb4073e0dfe5b1eb40b6" rel="stylesheet">
</syntaxhighlight>
<translate>
<!--T:59-->
The string of characters after the ''?'' is the md5 hash, which will change when extensions or Joomla itself are installed/upgraded/uninstalled. </translate>
<translate>
<!--T:60-->
* '''conditional' => 'lt IE 9''' (as an example). This outputs the ''<script>'' or ''<link>'' within a [https://en.wikipedia.org/wiki/Conditional_comment Conditional Comment] which earlier versions of Internet Explorer interpreted.</translate>
<translate>
<!--T:61-->
For example</translate>
<syntaxhighlight lang="php">
$document->addScript("...demo.js", array('conditional'=>'lt IE 9'));
// leads to
// <!--[if lt IE 9]><script src="...demo.js"></script><![endif]-->
</syntaxhighlight>
<translate>
<!--T:62-->
The ''$attributes'' parameter should also be an array, and these are mapped to be HTML attributes of the ''<script>'' or ''<link>'' element. For example,</translate>


<syntaxhighlight lang="php">
$document->addScript("...demo.js", array(), array('async'=>'async'));
// leads to
// <script src="...demo.js" async></script>
</syntaxhighlight>
<translate>
<translate>
====JHtml::script==== <!--T:16-->
== Adding the Options to Your JavaScript Code == <!--T:42-->
</translate>
</translate>
 
{{Joomla version|version=3.7|time=and after|comment=<translate><!--T:50-->
<translate><!--T:17-->
Only available in Joomla! 3.7 and higher</translate>|align=left}}
The following is the signature of this function, you can see more at [https://api.joomla.org/cms-3/classes/JHtml.html#method_script JHtml::script on api.joomla.org]:</translate>
 
<source lang="php">
script(string $file, boolean $framework = false, boolean $relative = false, boolean $path_only = false, boolean $detect_browser = true, boolean $detect_debug = true) : mixed</source>
 
<translate><!--T:18-->
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:</translate>
 
<source lang="php">
<?php
JHtml::script(JUri::base() . 'templates/custom/js/sample.js', true);
?>
</source>
 
<translate><!--T:19-->
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 <code>JPATH_BASE/media</code> folder - within here you specify your extension name followed by the name of your javascript file. The path searched is then <code>JPATH_BASE/media/com_search/js/search.js</code> for the following JHtml snippet.</translate>
 
<source lang="php">
<?php
JHtml::script('com_search/search.js', false, true);
?>
</source>
 
<translate><!--T:20-->
Note the js subdirectory that is searched in the com_search directory shouldn't be specified in the JHtml method.</translate>
 
<translate><!--T:21-->
However on top of this if a file exists in <code>js/com_search/search.js</code> 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.</translate>
 
<translate><!--T:22-->
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 or script.js to use this functionality and aid with debugging of any scripts. You should call the function with the compressed version, like this:</translate>
 
<source lang="php">
<?php
JHtml::script('com_search/search.min.js');
?>
</source>
 
<translate><!--T:23-->
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</translate>
 
<translate><!--T:24-->
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.</translate>
 
====JHtml::stylesheet====
 
<translate><!--T:25-->
The following is the signature of this function, you can see more at [https://api.joomla.org/cms-3/classes/JHtml.html#method_stylesheet JHtml::stylesheet on api.joomla.org]:</translate>
 
<translate><!--T:26-->
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 <code>JPATH_BASE/media</code> folder - within here you specify your extension name followed by the name of your CSS file. The path searched is then <code>JPATH_BASE/media/com_search/css/search.css</code> for the following JHtml snippet.</translate>
 
<source lang="php">
<?php
JHtml::stylesheet('com_search/search.css', array(), true);
?>
</source>
 
<translate><!--T:27-->
Note the <code>css</code> subdirectory that is searched in the <code>com_search</code> directory shouldn't be specified in the JHtml method.</translate>
 
<translate><!--T:28-->
However on top of this if a file exists in <code>css/com_search/search.css</code> then this will be included instead. This allows people to customize the appearance of an extension to better match their templates styling.</translate>
 
<translate><!--T:29-->
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</translate>
 
<translate><!--T:30-->
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.</translate>
 
<translate><!--T:31-->
Similarly as with JHtml::script, if $detect_debug is true and you pass it a minified stylesheet example.min.css, when debug mode is on, the unminified stylesheet will be used instead, if it exists.</translate>  
 
<translate>
<translate>
== Adding the options to your JavaScript code == <!--T:42-->
<!--T:63-->
</translate>
(Note that these Options are different from the ''$options'' parameter described above).</translate>


<translate><!--T:43-->
<translate><!--T:43-->
Beside adding inline scripts, Joomla! provide mechanism to store the options in the "optionsStorage".
Beside adding inline scripts, Joomla! provides a mechanism to store the options in the "optionsStorage".
This is allowed to nicely manage an existing options on the server side and on the client side. And allow to place all JavaScript logic to the JavaScript file, that will be cached by browser.</translate>
This allows you to nicely manage existing options on the server side and on the client side. It also allows you to place all JavaScript logic into the JavaScript file, which will be cached by browser.</translate>


<translate><!--T:44-->
<translate><!--T:44-->
Joomla! use special mechanism for "lazy loading" the options on the client side. It do not use inline JavaScript, that is good for page rendering speed, and make your site more friendly for the Speed Tester (eg Google).</translate>
Joomla! uses a special mechanism for "lazy loading" the options on the client side. It doesn't use inline JavaScript, which is good for page rendering speed, and makes your site more friendly to the Speed Testers (e.g. Google).</translate>


<translate><!--T:45-->
<translate><!--T:45-->
Thus use "optionsStorage" preferred, than use inline JavaScript to add the script options.</translate>
The use of "optionsStorage" is preferred over inline JavaScript for adding the script options.</translate>


<translate><!--T:46-->
<translate><!--T:46-->
'''Example of use'''</translate>
'''Example of Use'''</translate>


<translate><!--T:47-->
<translate><!--T:47-->
Add the script options to your module:</translate>
Add the script options to your module:</translate>
<source lang="php">
<syntaxhighlight lang="php">
$document = JFactory::getDocument();
$document = JFactory::getDocument();
$document->addScriptOptions('mod_example',
$document->addScriptOptions('mod_example', array(
     'colors' => array('selector' => 'body', 'color' => 'orange'),
     'colors' => array('selector' => 'body', 'color' => 'orange'),
     'sliderOptions' => array('selector' => '.my-slider', 'timeout' => 300, 'fx' => 'fade'),
     'sliderOptions' => array('selector' => '.my-slider', 'timeout' => 300, 'fx' => 'fade')
));
));
</source>
</syntaxhighlight>


<translate><!--T:48-->
<translate><!--T:48-->
Access to your options on the client side:</translate>
Access your options on the client side:</translate>
<source lang="javascript">
<syntaxhighlight lang="javascript">
var myOptions = Joomla.getOptions('mod_example');
var myOptions = Joomla.getOptions('mod_example');
console.log(myOptions.colors); // Print in the browser console your options
console.log(myOptions.colors); // Print your options in the browser console.
console.log(myOptions.sliderOptions);
console.log(myOptions.sliderOptions);
</source>
</syntaxhighlight>


<translate><!--T:49-->
<translate><!--T:49-->
Override the options on server side (possible until the head rendering):</translate>
Override the options on server side. (Possible until the head rendering.):</translate>
<source lang="php">
<syntaxhighlight lang="php">
$document  = JFactory::getDocument();
$document  = JFactory::getDocument();
// Get existing options
// Get existing options
Line 185: Line 139:
// Set new options
// Set new options
$document->addScriptOptions('mod_example', $myOptions);
$document->addScriptOptions('mod_example', $myOptions);
</source>
</syntaxhighlight>
 
<translate>
== Passing Language Strings to JavaScript == <!--T:64--></translate>
<translate>
<!--T:65-->
There are cases when you may want to output an error message in your JavaScript code and want to use the Joomla mechanism of language strings. You could manage this by using addScriptOptions to pass down each language string you need, but Joomla provides a more succinct solution. </translate>
<translate>
<!--T:66-->
To pass a language string to JavaScript do in your PHP code, for example,</translate>


''JText::script('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN');''
<translate>
<!--T:67-->
Then in your JavaScript code you can do:</translate>
''var message = Joomla.JText._('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN');''
<translate>
<!--T:68-->
to obtain in the user's language the text message associated with the language constant.</translate>
<translate>
<!--T:69-->
Obviously certain language strings have embedded %s characters, so in your JavaScript code you will have to handle that, eg using an external JavaScript sprintf library or string replace, etc.</translate>


<translate>
<translate>
== Inserting inline scripts from within a PHP file == <!--T:32-->
== Inserting Inline Scripts from Within a PHP File == <!--T:32-->
</translate>
</translate>
<translate><!--T:33-->
<translate><!--T:33-->
If your Javascript or CSS are generated using PHP, you can add the script or stylesheet directly into the head of your document:</translate>
If your JavaScript or CSS are generated using PHP, you can add the script or style sheet directly into the head of your document:</translate>


<source lang="php">
<syntaxhighlight lang="php">
$document = JFactory::getDocument();
$document = JFactory::getDocument();


Line 208: Line 183:
         . 'background: #00ff00;'
         . 'background: #00ff00;'
         . 'color: rgb(0,0,255);'
         . 'color: rgb(0,0,255);'
         . '}';  
         . '}';
$document->addStyleDeclaration($style);
$document->addStyleDeclaration($style);
</source>
</syntaxhighlight>


<translate>
<translate>
=== Javascript Example === <!--T:34-->
=== JavaScript Example === <!--T:34--></translate>
For example, the following code is used to define a custom tool tip that takes advantage of mootools.</translate>
<translate>
<!--T:70-->
For example, the following code is used to define a custom tool tip that takes advantage of Mootools.</translate>


<source lang="php">
<syntaxhighlight lang="php">
function getToolTipJS($toolTipVarName, $toolTipClassName){
function getToolTipJS($toolTipVarName, $toolTipClassName){
     $javascript = 'window.addEvent(\"domready\", function(){' ."\n";
     $javascript = 'window.addEvent(\"domready\", function(){' ."\n";
Line 238: Line 215:
$document->addStyleSheet("/joomla/components/com_mycustomcomponent/css/mytooltip.css",'text/css',"screen");
$document->addStyleSheet("/joomla/components/com_mycustomcomponent/css/mytooltip.css",'text/css',"screen");
$document->addScriptDeclaration(getToolTipJS("mytool","MyToolTip"));
$document->addScriptDeclaration(getToolTipJS("mytool","MyToolTip"));
</source>
</syntaxhighlight>


<translate><!--T:35-->
<translate><!--T:35-->
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 <code>mytooltip.css</code> file. Both are outside the scope of this article.</translate>
Note that in order for this JavaScript to be useful, it is 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.</translate>


<translate>
<translate>
Line 247: Line 224:
</translate>
</translate>
<translate><!--T:37-->
<translate><!--T:37-->
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:</translate>
This is also useful if you are inserting a form field of CSS into your code. For example, in a module you might want a user to choose the colour of the border. Call the form field's value and assign it a variable $bordercolor in mod_example.php. Then in tmpl/default.php you can include the following:</translate>


<source lang="php">
<syntaxhighlight lang="php">
$document = JFactory::getDocument();
$document = JFactory::getDocument();
$document->addStyleSheet('mod_example/mod_example.css', array(), true);
$document->addStyleSheet('mod_example/mod_example.css');
$style = '#example {
$style = '#example {
border-color:#' . $bordercolor . ';
border-color:#' . $bordercolor . ';
}';
}';
$document->addStyleDeclaration( $style );
$document->addStyleDeclaration( $style );
</source>
</syntaxhighlight>
 
<translate><!--T:38-->
<translate><!--T:38-->
Here mod_example.css contains the CSS file of any non-parameter based styles. Then the bordercolor parameter/form field is added in separately.</translate>
Here mod_example.css contains the CSS file of any non-parameter based styles. Then the ''bordercolor'' parameter/form field is added in separately.</translate>
 
<translate>
<translate>==Add Custom Tag== <!--T:39--></translate>
==Add Custom Tag== <!--T:39-->
</translate>
<translate><!--T:40-->
<translate><!--T:40-->
There will be some occasions where even these functions are not flexible enough, as they are limited to writing the contents of <code><script /></code> or <code><style /></code> 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 <code>$document->addCustomTag</code>:</translate>
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 style sheet link within conditional comments, so that it is picked up only by Internet Explorer 6 and earlier. To do this, use ''$document->addCustomTag'':</translate>


<source lang="php">
<syntaxhighlight lang="php">
$stylelink = '<!--[if lte IE 6]>' ."\n";
$stylelink = '<!--[if lte IE 6]>' ."\n";
$stylelink .= '<link rel="stylesheet" href="../css/IEonly.css" />' ."\n";
$stylelink .= '<link rel="stylesheet" href="../css/IEonly.css" />' ."\n";
Line 272: Line 249:
$document = JFactory::getDocument();
$document = JFactory::getDocument();
$document->addCustomTag($stylelink);
$document->addCustomTag($stylelink);
</source>
</syntaxhighlight>
<translate><!--T:51-->
If it was necessary to include other conditional CSS, always include the ''addCustomTag'' method after it is declared.</translate>
 
<translate>
== Sample Module Code == <!--T:71--></translate>
<translate>
<!--T:72-->
Below is the code for a simple Joomla module which you can install and run to demonstrate adding CSS and JavaScript, and can adapt to experiment with the concepts above. If you are unsure about development and installing a Joomla module then following the tutorial at [[S:MyLanguage/J3.x:Creating a simple module/Introduction| Creating a simple module ]] will help.</translate>
<translate>
<!--T:73-->
In a folder mod_css_js_demo create the following 4 files:</translate>
 
''mod_css_js_demo.xml''
<syntaxhighlight lang="xml">
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
    <name>css js demo</name>
    <version>1.0.1</version>
    <description>Code for including JS and CSS links</description>
    <files>
        <filename module="mod_css_js_demo">mod_css_js_demo.php</filename>
<filename>demo.css</filename>
<filename>demo.js</filename>
    </files>
</extension>
</syntaxhighlight>
 
''mod_css_js_demo.php''
<syntaxhighlight lang="php">
<?php
defined('_JEXEC') or die('Restricted Access');
 
use Joomla\CMS\Factory;
 
$document = Factory::getDocument();
 
$options = array("version" => "auto");
$attributes = array("defer" => "defer");
$document->addScript(JURI::root() . "modules/mod_css_js_demo/demo.js", $options, $attributes);
$document->addStyleSheet(JURI::root() . "modules/mod_css_js_demo/demo.css", $options);
 
$document->addScriptOptions('my_vars', array('id' => "css-js-demo-id2"));
 
JText::script('JLIB_HTML_EDIT_MENU_ITEM_ID');
 
echo '<h1 id="css-js-demo-id1">Hello World!</h3>';
echo '<button id="css-js-demo-id2">Click here!</button>';
</syntaxhighlight>
 
''demo.css''
<syntaxhighlight lang="css">
#css-js-demo-id1 {
color: red;
}
</syntaxhighlight>
 
''demo.js''
 
<syntaxhighlight lang="javascript">
jQuery(document).ready(function() {
 
const params = Joomla.getOptions('my_vars');
console.log(params);
console.log("JS language constant: " + Joomla.JText._('JLIB_HTML_EDIT_MENU_ITEM_ID'));
 
var message = Joomla.JText._('JLIB_HTML_EDIT_MENU_ITEM_ID');
message = message.replace("%s", params.id);
document.getElementById(params.id).addEventListener("click", function() {alert(message);});
});
</syntaxhighlight>
<translate>
<!--T:74-->
Zip up the mod_css_js_demo directory to create ''mod_css_js_demo.zip''.</translate>
<translate>
<!--T:75-->
Within your Joomla Administrator go to Install Extensions and via the Upload Package File tab, select this zip file to install this sample mod_css_js_demo module.</translate>
<translate>
<!--T:76-->
Make this module visible by editing it (click on it within the Modules page) then:
# making its status Published
# selecting a position on the page for it to be shown
# on the menu assignment tab specify the pages it should appear on</translate>
<translate>
<!--T:77-->
When you visit the web page, you should see the module in your selected position. It should display:
* a message ''Hello World!'' which the CSS file should change to display in red
* a button which when you click it will execute an ''alert()'' showing the language string and variable which were passed down from the PHP code.</translate>
<translate>
<!--T:78-->
Using your browser's development tools you can also view the ''<script>'' and ''<link>'' elements within the HTML and see the JavaScript output on the console. </translate>


<noinclude>
<noinclude>

Latest revision as of 10:34, 27 November 2024

Warning!

This page has been superseded and is no longer maintained. Please go to Joomla Manual instead


This is one of a series of API Guides, which aim to help you understand how to use the Joomla APIs through providing detailed explanations and sample code which you can easily install and run.

Inserting from a File

Joomla allows you to add JavaScript and CSS files to your HTML document, and it puts the associated <script> and <link> elements within the HTML <head> section. To do this you call the addScript and addStyleSheet methods of the Joomla object which represents the HTML document. Since Joomla! buffers all the HTML-related data that makes up a page before output, it is possible to call these methods anywhere within your code.

First, get a reference to the current document object:

use Joomla\CMS\Factory;
$document = Factory::getDocument();
// above 2 lines are equivalent to the older form: $document = JFactory::getDocument();

Then for a style sheet, 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 that jQuery can only be included natively on Joomla! 3.0+.) It used to be possible to do this with JHTML, however, this was deprecated in Joomla 2.5 and removed in Joomla 3.x.

$options and $attributes Parameters

You can add $options and $attributes parameters to the above methods. The $options control overall how the <script> and <link> elements are output while the $attributes get set as HTML attributes within those tags. (Note that although there are Deprecated markers against the addScript and addStyleSheet methods of the Joomla Document API, these markers refer just to the signature of these methods; the form of the signature using $options and $attributes parameters is not deprecated). The $options parameter should be an array and 2 different options are currently supported:

  • version => auto If this is set then a 'media version' is appended as a query parameter to the CSS or JavaScript URL within the <script> or <link> element. This is a string (an md5 hash) that is generated from factors including the Joomla version, your Joomla instance secret and the date/time at which the media version was generated. The media version is regenerated whenever anything is installed on the Joomla instance. Its purpose is to force browsers to reload the CSS and JavaScript files instead of using possibly outdated versions from cache.

For example

$document->addStyleSheet("...demo.css", array('version'=>'auto'));
// leads to something like
// <link href="...demo.css?37e343bbb4073e0dfe5b1eb40b6" rel="stylesheet">

The string of characters after the ? is the md5 hash, which will change when extensions or Joomla itself are installed/upgraded/uninstalled.

  • conditional' => 'lt IE 9 (as an example). This outputs the <script> or <link> within a Conditional Comment which earlier versions of Internet Explorer interpreted.

For example

$document->addScript("...demo.js", array('conditional'=>'lt IE 9'));
// leads to
// <!--[if lt IE 9]><script src="...demo.js"></script><![endif]-->

The $attributes parameter should also be an array, and these are mapped to be HTML attributes of the <script> or <link> element. For example,

$document->addScript("...demo.js", array(), array('async'=>'async'));
// leads to
// <script src="...demo.js" async></script>

Adding the Options to Your JavaScript Code

Joomla! 
≥ 3.7
Only available in Joomla! 3.7 and higher

(Note that these Options are different from the $options parameter described above).

Beside adding inline scripts, Joomla! provides a mechanism to store the options in the "optionsStorage". This allows you to nicely manage existing options on the server side and on the client side. It also allows you to place all JavaScript logic into the JavaScript file, which will be cached by browser.

Joomla! uses a special mechanism for "lazy loading" the options on the client side. It doesn't use inline JavaScript, which is good for page rendering speed, and makes your site more friendly to the Speed Testers (e.g. Google).

The use of "optionsStorage" is preferred over inline JavaScript for adding the script options.

Example of Use

Add the script options to your module:

$document = JFactory::getDocument();
$document->addScriptOptions('mod_example', array(
    'colors' => array('selector' => 'body', 'color' => 'orange'),
    'sliderOptions' => array('selector' => '.my-slider', 'timeout' => 300, 'fx' => 'fade')
));

Access your options on the client side:

var myOptions = Joomla.getOptions('mod_example');
console.log(myOptions.colors); // Print your options in the browser console.
console.log(myOptions.sliderOptions);

Override the options on server side. (Possible until the head rendering.):

$document  = JFactory::getDocument();
// Get existing options
$myOptions = $document->getScriptOptions('mod_example');
// Change the value
$myOptions['colors'] = array('selector' => 'body', 'color' => 'green');
// Set new options
$document->addScriptOptions('mod_example', $myOptions);

Passing Language Strings to JavaScript

There are cases when you may want to output an error message in your JavaScript code and want to use the Joomla mechanism of language strings. You could manage this by using addScriptOptions to pass down each language string you need, but Joomla provides a more succinct solution. To pass a language string to JavaScript do in your PHP code, for example,

JText::script('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'); Then in your JavaScript code you can do:

var message = Joomla.JText._('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'); to obtain in the user's language the text message associated with the language constant. Obviously certain language strings have embedded %s characters, so in your JavaScript code you will have to handle that, eg using an external JavaScript sprintf library or string replace, etc.

Inserting Inline Scripts from Within a PHP File

If your JavaScript or CSS are generated using PHP, you can add the script or style sheet 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

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 useful, it is 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

This is also useful if you are inserting a form field of CSS into your code. For example, in a module you might want a user to choose the colour of the border. Call the form field's value and assign 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');
$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

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 style sheet 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);

If it was necessary to include other conditional CSS, always include the addCustomTag method after it is declared.

Sample Module Code

Below is the code for a simple Joomla module which you can install and run to demonstrate adding CSS and JavaScript, and can adapt to experiment with the concepts above. If you are unsure about development and installing a Joomla module then following the tutorial at Creating a simple module will help. In a folder mod_css_js_demo create the following 4 files:

mod_css_js_demo.xml

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
    <name>css js demo</name>
    <version>1.0.1</version>
    <description>Code for including JS and CSS links</description>
    <files>
        <filename module="mod_css_js_demo">mod_css_js_demo.php</filename>
		<filename>demo.css</filename>
		<filename>demo.js</filename>
    </files>
</extension>

mod_css_js_demo.php

<?php
defined('_JEXEC') or die('Restricted Access');

use Joomla\CMS\Factory;

$document = Factory::getDocument();

$options = array("version" => "auto");
$attributes = array("defer" => "defer");
$document->addScript(JURI::root() . "modules/mod_css_js_demo/demo.js", $options, $attributes);
$document->addStyleSheet(JURI::root() . "modules/mod_css_js_demo/demo.css", $options);

$document->addScriptOptions('my_vars', array('id' => "css-js-demo-id2"));

JText::script('JLIB_HTML_EDIT_MENU_ITEM_ID');

echo '<h1 id="css-js-demo-id1">Hello World!</h3>';
echo '<button id="css-js-demo-id2">Click here!</button>';

demo.css

#css-js-demo-id1 {
color: red;
}

demo.js

jQuery(document).ready(function() {

	const params = Joomla.getOptions('my_vars');
	console.log(params);
	console.log("JS language constant: " + Joomla.JText._('JLIB_HTML_EDIT_MENU_ITEM_ID'));

	var message = Joomla.JText._('JLIB_HTML_EDIT_MENU_ITEM_ID');
	message = message.replace("%s", params.id);
	document.getElementById(params.id).addEventListener("click", function() {alert(message);});
});

Zip up the mod_css_js_demo directory to create mod_css_js_demo.zip. Within your Joomla Administrator go to Install Extensions and via the Upload Package File tab, select this zip file to install this sample mod_css_js_demo module. Make this module visible by editing it (click on it within the Modules page) then:

  1. making its status Published
  2. selecting a position on the page for it to be shown
  3. on the menu assignment tab specify the pages it should appear on

When you visit the web page, you should see the module in your selected position. It should display:

  • a message Hello World! which the CSS file should change to display in red
  • a button which when you click it will execute an alert() showing the language string and variable which were passed down from the PHP code.

Using your browser's development tools you can also view the <script> and <link> elements within the HTML and see the JavaScript output on the console.