Note: You are currently viewing documentation for Moodle 3.3. Up-to-date documentation for the latest stable version of Moodle is probably available here: JavaScript guidelines.

Development:JavaScript guidelines: Difference between revisions

From MoodleDocs
Line 14: Line 14:
==Getting Moodle to load your JavaScript files==
==Getting Moodle to load your JavaScript files==


There is a function '''require_js''' in lib/weblib.php. It takes one argument, which is the URL of the JavaScript file you want, which will normally start with $CFG->wwwroot. For example:
There is a function '''require_js''' in lib/weblib.php. It takes one argument, which is the URL of the JavaScript file you want (which will normally start with $CFG->wwwroot). For example:


     require_js($CFG->wwwroot . '/question/qengine.js');
     require_js($CFG->wwwroot . '/question/qengine.js');

Revision as of 12:13, 19 September 2008

Template:Moodle 2.0 This page is currently just a brain-dump by Tim Hunt. Hopefully this is a useful starting point for discussion. If we can all agree on something, then they will become actual coding guidelines, and we can fix up some of the more horrific things Moodle currently does with JavaScript.

General principles

Everything in Moodle should work with JavaScript turned off. This is important for accessibility, and in line with the principles of unobtrusive JavaScript and Development:Progressive_enhancement|progressive enhancement]].

Almost all JavaScript code should be in separate .js files. There should be the smallest possible amount of JavaScript inline in the HTML code of pages.

The official JavaScript library for Moodle is YUI. That may not be your favourite, but it's the one that was chosen after careful research, so live with it.

The rest of this page explains how you can achieve these goals.

Getting Moodle to load your JavaScript files

There is a function require_js in lib/weblib.php. It takes one argument, which is the URL of the JavaScript file you want (which will normally start with $CFG->wwwroot). For example:

   require_js($CFG->wwwroot . '/question/qengine.js');

To simplify including the various YUI libraries, require_js recognises some short cuts like

   require_js('yui_yahoo');

The full list of recognised short cuts is in lib/ajax/ajaxlib.php. You can also call require_js with an array of libraries, to further save typing. For example:

   require_js(array('yui_yahoo','yui_event', 'yui_connection'));

Wherever possible, you should arrange your code so you call require_js before the call to print_header. If you can do that, then Moodle builds up a list of the required libraries, and puts all the <script src="..." ...> tags inside <head>. However, it is not a big problem if you have to call require_js later. If you call require_js later, then it just outputs a <script src="..." ...> tag in the body of the page. (In fact there is a tricky third case, where code executed in the middle of print_header calls require_js, and that works fine too.)

require_js also keeps track of which files have been included, and ensures that each one is only included once, like the PHP require_once directive.

What should go in your .js files

In almost every case, your .js files should simply define things like functions, classes and variables. When the file is loaded, no JavaScript code should actually be executed.

Activating your JavaScript

Since your .js files should not actually do anything when they are loaded, you need some way to trigger them into action. Normally the best way to do this is to put a simple inline script in the HTML that just calls an initialisation function. Typically, you want the HTML page you generate to look like this:

<!-- HTML code that will work with JavaScript disabled, perhaps with an id="mything" attribute on the main HTML tag. --> <script type="text/javascript"> init_my_script('perhaps_some_data', 'for_example', 'mything'); <script>

For an example of this, look at case QUESTION_FLAGSEDITABLE in the print_question_flag method in question/type/questiontype.php.

The arguments you pass to the initialisation function are a good way to get data from your PHP code to your JavaScript. Examples of the kind of thing you need to send are the id of an HTML element to change, language string, or values like $CFG->wwwroot. If you have more than a few values to pass however, this becomes a pain, so see the next section.

In weblib, this is a helpful function print_js_call that prints a simple script like this for you, given the function name and an array of arguments.

Getting more variables from PHP to JavaScript

When you have lots of values to pass from PHP to JavaScript, or when you have lots of initialisatoin function calls that all need the same values, a better way to handle the communication is to generate a small amount of JavaScript inline in the HTML of your page that sets up JavaScript variables for all the values you need. The sort of inline script you want is:

<script type="text/javascript">
qengine_config = {
    pixpath: 'http://tim.moodle.com/moodle/pix/smartpix.php/standardwhite'
    wwwroot: 'http://tim.moodle.com/moodle'
    flagtooltip: 'Click to flag this question'
    unflagtooltip: 'Click to un-flag this question'
    flaggedalt: 'Flagged'
    unflaggedalt: 'Not flagged'
}
</script>

That sets up a number of variables that can be accessed inside your JavaScript functions like qengine_config.pixpath.

The easiest way to generate a script like this is to use the print_js_config function in lib/weblib.php. To generate the above script, you would need to do:

$config = array(
    'pixpath' => $CFG->pixpath,
    'wwwroot' => $CFG->wwwroot,
    'flagtooltip' => get_string('clicktoflag', 'question'),
    'unflagtooltip' => get_string('clicktounflag', 'question'),
    'flaggedalt' => get_string('flagged', 'question'),
    'unflaggedalt' => get_string('notflagged', 'question'),
);
print_js_config($config, 'qengine_config');

See also