Integrating Yahoo! User Interface Library (YUI) with Moodle

Exclusive offer: get 80% off this eBook here
Moodle JavaScript Cookbook

Moodle JavaScript Cookbook — Save 80%

Over 50 recipes for making your Moodle system more dynamic and responsive with JavaScript

₨739.00    ₨147.80
by Alastair Hole | May 2011 | Cookbooks Moodle Open Source

Using JavaScript in Moodle is very useful for administrators and dynamic developers, as it uses built-in libraries, like YUI, to provide the modern and dynamic experience that is expected by web users today. This article explains how to integrate Yahoo! User Interface Library (YUI) with Moodle.

In this article by Alastair Hole, author of Moodle JavaScript Cookbook, we will learn the basics of working with YUI. We will learn how to initialize the YUI and make it ready for use within our code and load additional modules from both Version 2 and 3 of the YUI. We will also learn how to manage the execution of code by attaching events to our controls, and finally how to debug our code with YUI logging tools.

 

Moodle JavaScript Cookbook

Moodle JavaScript Cookbook

Over 50 recipes for making your Moodle system more dynamic and responsive with JavaScript

        Read more about this book      

(For more resources on this subject, see here.)

In this article, we will cover:

  • Initializing the YUI 3 library
  • Loading YUI 3 modules
  • Loading YUI 2 modules from YUI 3
  • Attaching basic event handlers
  • Attaching advanced DOM event handlers
  • Implementing Event Delegation
  • Debugging with the YUI console

Introduction

There are a lot of common tasks that need to be performed when writing JavaScript. A large proportion of this simply involves dealing with differences between web browsers. The need for a way to hide or abstract the specifics of each browser into a standard interface gave rise to sets of tools known as JavaScript libraries. One of the leading libraries in use on the web today is the Yahoo! User Interface Library (YUI).

Moodle includes a copy of the YUI as its preferred JavaScript library. YUI provides developers with access to a wide range of tools for enhancing their web applications:

The YUI Library is a set of utilities and controls, written with JavaScript and CSS, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX. YUI is available under a BSD license and is free for all uses. YUI is proven, scalable, fast, and robust. Built by frontend engineers at Yahoo! and contributors from around the world, it's an industrial-strength JavaScript library for professionals who love JavaScript.

Yahoo! Developer Network
http://developer.yahoo.com/yui/

In this article, we will learn the basics of working with YUI. We will learn how to initialize the YUI and make it ready for use within our code and load additional modules from versions 2 and 3 of the YUI. We will also learn how to manage the execution of code by attaching events to our controls, and finally how to debug our code with YUI logging tools.

Initializing the YUI 3 library

In this recipe, we will learn how to initialize the YUI 3 environment within Moodle, which will get us ready to start using YUI 3 features. Moodle takes care of most of the initial setup, namely loading the required CSS and JavaScript files, so all we need to be concerned with is activating the YUI environment.

This example will show how to execute JavaScript code from within the YUI environment. We will set up a small YUI script which will simply display a message including the version number of the active YUI environment in a JavaScript alert box.

This provides a simple view of what is required to get YUI up and running that we will build on further in the subsequent recipes.

Getting ready

We begin by setting up a new PHP file yui_init.php in the cook directory with the following content:

<?php
require_once(dirname(__FILE__) . '/../config.php');
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->set_url('/cook/yui_init.php');
$PAGE->requires->js('/cook/yui_init.js');
echo $OUTPUT->header();
echo $OUTPUT->footer();
?>

Notice that the preceding code references a JavaScript file yui_init.js, which has the following content:

YUI().use
(
function(Y)
{
alert('Hello from YUI ' + Y.version);
}
);

How to do it...

We have created a PHP file that sets up a Moodle programming environment and includes a JavaScript file, in a way now familiar to us from previous recipes.

What is new here is the content of the JavaScript file, which is where we will make ready the YUI 3 environment.

Moodle has already included all the JavaScript files required for YUI (this happened when we output the value returned from $OUTPUT->header();). This means we now have a global object named YUI available within our JavaScript code.

We create a new instance of the YUI object with the statement YUI() and then immediately call the use method.

The only parameter we will pass to the use method is an anonymous function. This is just like a regular JavaScript function, except that it has no name specified; hence it is "anonymous". A name is not required, as it is not referred to again, but it is simply passed directly to the use method. This function itself accepts a single input parameter Y, which will be a reference to the new instance of the YUI object. (Note that the use method is also used to load additional YUI modules; this is the subject of the next recipe.)

The anonymous function just created is the most important part of the code to take note of as this is where we will be putting our entire code that will be making use of the YUI features. In this example, you can see that we are just creating a JavaScript alert with a short message including the value of Y.version, which is simply a string containing the version number of YUI that has been loaded as seen in the following screenshot:

Integrating Yahoo! User Interface Library (YUI) with Moodle

Here, we can see that our code has successfully initialized the YUI 3.2.0 environment and is ready for us to start using the features available within the YUI and its additional modules.

How it works...

We have created a new instance of the global object YUI, and called the use method, passing in an anonymous function that contains the code we wish to run. When the new instance of the YUI object is fully loaded, it makes a call to our anonymous function, and our code is executed.

In this example, our code displays a short message containing the version number of the YUI instance we created, confirming that we have a fully functional YUI 3 environment as a basis to implement further YUI features.

Loading additional YUI modules

YUI has a whole host of additional modules providing a very wide range of functionalities. Some examples of commonly used functionalities provided by additional modules include:

  • Animation
  • Drag and drop
  • Manipulating DOM elements
  • Handling DOM events (that is an input button's "click" event)
  • Handling data (JSON/XML)

For a current list of all the modules available, please refer to the Yahoo! Developer Network website for YUI 3 at the URL: http://developer.yahoo.com/yui/3/

How to do it...

The loading of additional modules is achieved via the use method of the YUI object. In the previous recipe we learned how to run code via the use method with the following syntax:

YUI().use
( function(Y) { /* <code to execute> */ } );

Note that the use method takes an arbitrarily long number of arguments (one or more) and only the last argument must be the anonymous function described in the previous recipe. The preceding arguments are a list of one or more modules you wish to load. So for example, to load the Animation module (anim) and the DOM Event Utility module (event), we would use the following syntax in place of the preceding one:

YUI().use
( "anim", "event", function(Y) { /* <code to execute> */ } );

Now all of the features of these two additional modules (anim and event) will be available within the anonymous function that contains the code we want to execute.

This technique will be used to load the modules we require in the examples contained in the subsequent recipes.

Moodle JavaScript Cookbook Over 50 recipes for making your Moodle system more dynamic and responsive with JavaScript
Published: April 2011
eBook Price: ₨739.00
Book Price: ₨1,232.00
See more
Select your format and quantity:
        Read more about this book      

(For more resources on this subject, see here.)

Loading YUI 2 modules from YUI 3

There can be several reasons why we would want to load YUI 2 modules from within YUI 3. We may have a substantial amount of pre-written YUI 2 code that we wish to use straight away, saving us the trouble of rewriting it from scratch. Another reason may be we wish to use features of the YUI 2 that have not yet been re-implemented as native YUI 3 modules.

In this recipe, we will learn how to load YUI 2 modules from within YUI 3 by loading the Calendar widget from YUI 2, inside a native YUI 3 script.

Getting ready

We begin by creating a new PHP file yui_cal.php in the cook directory with the following content:

<?php

require_once(dirname(__FILE__) . '/../config.php');

$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->set_url('/cook/yui_cal.php');
$PAGE->requires->js('/cook/yui_cal.js');

echo $OUTPUT->header();

?>
<div id="calContainer"></div>
<?php
echo $OUTPUT->footer();
?>

You will notice that yui_cal.php links to a JavaScript file yui_cal.js, also in the cook directory, with the following content:

YUI().use("yui2-calendar", function(Y)
{
var YAHOO = Y.YUI2;
var cal = new YAHOO.widget.Calendar("calContainer");
cal.render();
});

How to do it...

First, we created a PHP file, yui_cal.php in which we set up the Moodle programming environment and included our JavaScript file, yui_cal.js. Also, in this PHP file we have included a container <div> tag to which we have assigned the ID calContainer. As you may have guessed, this will be where we will render the YUI 2 calendar control.

Moving on to the JavaScript portion of this recipe contained in yui_cal.js, we have first loaded the module named yui2-calendar. All available YUI 2 modules are referenced using their original names prefixed with yui2-. So calendar becomes yui2-calendar.

The next step is to recreate the YAHOO object from YUI 2. This is available as part of the YUI 3 object Y, in the form of Y.YUI2. For convenience, we will copy this into a new object named YAHOO. As this now matches the YUI 2 coding style, it makes it easy for us to reuse existing YUI 2 code here.

Finally, we create a new instance of the YUI 2 calendar widget YAHOO.widget.Calendar, passing in the ID of the container <div> we created earlier, and then call the render method to display the calendar.

Our page should now have a new calendar control rendered inside our <div> container as seen in the following screenshot:

Integrating Yahoo! User Interface Library (YUI) with Moodle

How it works...

When we load yui_cal.php in a web browser, our page is rendered including the container <div> for our calendar. When the page has finished downloading, our JavaScript is executed.

From our JavaScript, the YUI 2 Calendar module is loaded first by YUI 3 in the same way it loads YUI 3 modules, the difference being we have used the name of a YUI 2 module prefixed with yui2-, that is, yui2-calendar.

Next, we have obtained a copy of the YUI 2 object YAHOO by copying it from the YUI 3 object Y.YUI2.

Finally, we can use the new YAHOO object to create a new instance of the Calendar widget, attaching it to our container <div> and calling the render method to have it built and displayed.

Attaching basic event handlers

Events are the basis for managing how the user interface responds to particular actions taken by the user, primarily with the keyboard and/or mouse. An event is a particular action taken in the context of a particular DOM element. The following are two common examples:

  • An input button element has a click event, which occurs when the user clicks the mouse while the mouse pointer is hovering over the button
  • An input text box has a focus event, which occurs when the text box has gained focus, meaning the user has moved the cursor into the text box either with the mouse cursor or using the Tab key

Therefore, an event handler is a specific block of code (callback function) that we have registered (attached) to a particular element and event combination, that is, the input button and its click event.

In this recipe, we will learn how to attach a click event handler to an HTML input button as per the first example. We will set up the code such that an alert is displayed when the button is clicked.

Getting ready

We begin by creating a new PHP file yui_eventbasic.php in the cook directory, with the following content:

<?php
require_once(dirname(__FILE__) . '/../config.php');
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->set_url('/cook/yui_event.php');
$PAGE->requires->js('/cook/yui_eventbasic.js');
echo $OUTPUT->header();
?>
<form>
<input type="button" id="btn1" value="Button 1" />
</form>
<?php
echo $OUTPUT->footer();
?>

You will notice that yui_eventbasic.php links to a JavaScript file yui_eventbasic.js, also in the cook directory, with the following content:

YUI().use("node-base", function(Y) {
var btn1_Click = function(e)
{
alert('Button clicked');
};
Y.on("click", btn1_Click, "#btn1");
});

How to do it...

We have set up the Moodle programming environment in the way now familiar in yui_eventbasic.php, with the addition of a form with an input button labeled Button 1 with the ID btn1 as seen in the following screenshot:

Integrating Yahoo! User Interface Library (YUI) with Moodle

This is the button to which we shall register a click event, referring to it by its ID later on. This PHP file also includes the JavaScript file yui_eventbasic.js from where we will set up the event.

The JavaScript in yui_eventbasic.js begins by loading the module we require —node-base.

Next, we have defined a function btn1_Click which will serve as the click event handler. This function simply displays an alert to demonstrate that the event has fired correctly.

Lastly, we use the on method of the Y object to register the event, passing three parameters as detailed in the following table:

Integrating Yahoo! User Interface Library (YUI) with Moodle

Now we can load our PHP page in a web browser, and when we click on Button 1, we will see the JavaScript alert pop up, letting us know that the click event has fired correctly and called our event handler as seen in the following screenshot:

Integrating Yahoo! User Interface Library (YUI) with Moodle

How it works...

When we built the PHP page including our input button, we assigned an ID to that button via the id attribute. This is what allows us to later refer to that button specifically from the JavaScript code.

When our page is loaded in the browser, our JavaScript file is also loaded and executed, initializing the YUI environment. Next, our function btn1_Click is defined.

Lastly, we used the Y.on method to assign this function to the click event of the button. The name of the event is simply "click" which all browsers understand. Our event handler is simply referenced by name, that is, btn1_Click. Lastly, we told Y.on to apply the event handler to the element with ID btn1 by passing the ID prefixed with a #, that is, #btn1.

Y.on uses a CSS selector syntax to refer to elements; hence the ID is prefixed with a # in the same way it would be if we were defining a CSS selector. This is a powerful and flexible method for registering events as we could alternatively use the identifier .btn which would then register this event handler for all elements with the class attribute set to btn.

Attaching advanced DOM event handlers

Sometimes we simply want to run JavaScript code when the page loads, rather than in response to an action taken by the user (as in the previous example).

A simple way to achieve this would be to put our code directly in the JavaScript file outside of any functions or event handlers. Using this method, our code would just be executed straight after it is loaded. If we are following the best practice technique of loading our script files at the end of the body tag, our code will be executed after the main body content of the page has loaded.

Note that Moodle implements this best practice for us automatically when we load a JavaScript file unless we specify otherwise in the <head>. Using this latter technique of loading a script file from the <head>, our code would be executed before the rest of the page had finished loading.

This simple technique is sufficient for cases where the code we wish to execute does not depend upon certain DOM elements being loaded, and to a limited extent loading a script file at the end of the body tag does ensure that the page's DOM elements will be fully loaded and available to our code. However, this method cannot be relied upon across all web browsers. In some cases, our attempts to access a DOM element that is not fully loaded may cause the rest of our script to fail, and in the worst case, it may even cause an inferior web browser to crash! Obviously, this is far from ideal—enter YUI.

The YUI 3 library offers a set of significantly more robust solutions to this problem, which can be relied upon across all web browsers that the YUI supports. It is these offerings which we will investigate in this recipe, and they take the form of the events described in the following table:

Integrating Yahoo! User Interface Library (YUI) with Moodle

We will implement each of these four events in order to gain greater understanding of when they are fired, both relative to the page load lifecycle as a whole, and relative to each other. For each element, we will print a message numbered from one to four, reflecting the order in which they were fired. Note that this order varies from browser to browser.

Getting ready

We begin by creating a new PHP file yui_eventdom.php in the cook directory, with the following content:

<?php
require_once(dirname(__FILE__) . '/../config.php');
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->set_url('/cook/yui_event.php');
$PAGE->requires->js('/cook/yui_eventdom.js');
echo $OUTPUT->header();
?>
<div id="container">
<h1>Events called, in order:</h1>
</div>
<?php
echo $OUTPUT->footer();
?>

You will notice that yui_eventdom.php links to a JavaScript file yui_eventdom.js, also in the cook directory, with the following content:

YUI().use("node-base", function(Y)
{
Y.on
(
"available",
function()
{
printMessage("Element #container 'available'");
},
"#container"
);
Y.on
(
"contentready",
function()
{
printMessage("Elememt #container 'contentready'");
},
"#container"
);
Y.on
(
"domready",
function()
{
printMessage("Page 'domready'");
}
);
Y.on
(
"load",
function(e)
{
printMessage("Window 'load'");
},
Y.config.win
);
var order = 1;
var container = Y.one('#container');
function printMessage(message)
{
container.append('<p>' + order++ + '. ' + message + '</p>');
}
});

How to do it...

In the PHP file yui_eventdom.php, we set up the standard Moodle programming environment as usual, and included a <div> tag, inside which we will print messages from each of the four event handlers. Note that we have set an ID container for this <div> tag, ensuring that we can reference it later on in our JavaScript.

Moving on to our JavaScript file yui_eventdom.js, we begin by loading the node-base module which gives us access to the Y.on method, which we will use to register the event handlers. Next, we set up the four event handlers we are demonstrating, beginning with available and contentready, which are registered in our container <div>. The next event handler is domready, which is not applied to any particular element as the DOM is intrinsic to the page. Finally, we register the load event to Y.config.win, which is YUI's browser-independent reference to the page's window object.

Inside each of these event handlers we have made a call to the function printMessage, which prints the message passed to it, along with a numbered prefix reflecting the order in which the call was made.

Now when we load our page in a web browser, we will see the order in which the events have been called. The order generally corresponds to the "safest" one first. That is, the order that allows the respective events to be called as early as possible in the page load lifecycle without running into any browser-specific issues such as crashes due to attempts to access DOM elements that have not been loaded.

In the following screenshots we can see how the order changes between three common web browsers:

  • Safari 5

    Integrating Yahoo! User Interface Library (YUI) with Moodle

  • Firefox 3

    Integrating Yahoo! User Interface Library (YUI) with Moodle

  • Internet Explorer 8

    Integrating Yahoo! User Interface Library (YUI) with Moodle

Notice that Firefox 3 has the most intuitive order, with the container <div> tag first being available, and then contentready once its child elements have loaded. Next, the page is domready, and finally the window-load event is fired once all additional assets (scripts, stylesheets, and images) have loaded.

How it works...

We used the Y.on method to get YUI to assign the events to their respective elements. When the page is executed, YUI manages these in a browser-specific manner, firing our events at the earliest but safest possible opportunity.

When the events are fired, a call is made to our printMessage function, which prints that message, prefixed with a number indicating the order the event was fired in. This is achieved by keeping a count with the global variable order, which starts at 1. Every time we print a message, we include this number in the text, and increase its value by one, ready for the next message to be displayed.

Moodle JavaScript Cookbook Over 50 recipes for making your Moodle system more dynamic and responsive with JavaScript
Published: April 2011
eBook Price: ₨739.00
Book Price: ₨1,232.00
See more
Select your format and quantity:
        Read more about this book      

(For more resources on this subject, see here.)

Implementing event delegation

So far we have looked at a range of methods for registering single events to single elements. These techniques are very useful but it becomes inefficient and laborious when we wish to register events for multiple elements.

If we take the example of a navigation control in the form of a list of links, we could implement a click event for each link by manually registering the event against the ID of the element. While this may be fine for a handful of links, as soon as the list starts to get larger it becomes very cumbersome to manage these events. The more links there are, the more it becomes prone to mistakes and bugs. Would you want to write (and manage) code to register click events to 50 links by hand if you didn't have to?

Fortunately, it so happens that the YUI has a solution for just this type of problem, namely Event Delegation.

Event delegation is a technique whereby we can designate a parent element to hand down events to its child elements. Picking up our example of a list of links, this means we can use the element containing our list to manage the events of the links in that list.

In this recipe, we will use event delegation to implement a click event handler for each one of a list of links. In the click event handler we will simply display an alert showing which link was clicked. Using this method we can add as many links into the list as we want at any time later on, avoiding the need to add or change any of our JavaScript code when we do so.

Getting ready

We start by creating a PHP file yui_delegation.php with the following content:

<?php
require_once(dirname(__FILE__) . '/../config.php');

$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->set_url('/cook/yui_delegation.php');
$PAGE->requires->js('/cook/yui_delegation.js');

echo $OUTPUT->header();
?>
<div id="container">
<ul>
<li id="li-1"><a href="#">Item 1</a></li>
<li id="li-2"><a href="#">Item 2</a></li>
<li id="li-3"><a href="#">Item 3</a></li>
<li id="li-4"><a href="#">Item 4</a></li>
<li id="li-5"><a href="#">Item 5</a></li>
</ul>
</div>
<?php
echo $OUTPUT->footer();
?>

Next, we create the JavaScript file yui_delegation.js that was referenced in the yui_delegation.php file:

YUI().use("event-delegate", function(Y)
{
Y.delegate("click", function (e)
{
var item = this.one('a').get('text');
alert("You clicked " + item);
}, "#container", "li");
});

How to do it...

We created a PHP page and set up the Moodle programming environment as usual. We included an unordered list of links inside a <div> container. It is for these links that we will implement click events via delegation.

Next, we move on to the JavaScript code, beginning by loading the event-delegate module that we require for this technique. This makes available a new method, Y.delegate.

Using Y.delegate, we then delegate the click events for the list items within our container <div>.

Finally, when we load the page in a web browser and click on one of the links, we see our message pop up, including the name of the item that we actually clicked on as seen in the following screenshot:

Integrating Yahoo! User Interface Library (YUI) with Moodle

How it works...

After loading the event-delegate module, the Y.delegate method is available. Y.delegate takes four arguments:

Integrating Yahoo! User Interface Library (YUI) with Moodle

Y.delegate then sets up a click handler for all of the li elements within the #container element, and registers the function that we have passed.

Inside this function, the particular element that has fired the event is referred to as "this". In this case, "this" is an <li> object containing the <a> link tag. Here, we just read the text of the link tag and display it in a message to show which item was clicked.

Debugging with the YUI console

Debugging is one area where JavaScript has suffered in the past—there are a range of browser plugins available which help to some extent, but if we wish to debug an issue that occurs in a browser that doesn't have these usual features, we have a problem!

YUI's answer to this problem is the YUI Console, as shown in the following image:

Integrating Yahoo! User Interface Library (YUI) with Moodle

This is a widget that displays a log of all messages that have been written to the console log. These include messages from existing YUI widgets and plugins, but may also include customized messages logged from our own JavaScript code.

In this recipe, we will display the YIU console and log some example messages to it.

Getting ready

First, we create a PHP page yui_console.php to house the console, with the following content:

<?php
require_once(dirname(__FILE__) . '/../config.php');

$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->set_url('/cook/yui_console.php');
$PAGE->requires->js('/cook/yui_console.js');

echo $OUTPUT->header();
?>
<h1>YUI Console</h1>
<?php
echo $OUTPUT->footer();
?>

Next, we create the associated JavaScript file yui_console.js with the following content:

YUI().use("console", function(Y)
{
var myConsole = new Y.Console();
myConsole.render();

Y.log("I am an info message.", "info");
Y.log("I am a warning.", "warn");
Y.log("I am an error.", "error");
});

How to do it...

Our PHP page sets up the standard Moodle programming environment we have used throughout these recipes, linking to our JavaScript file yui_console.js.

In this JavaScript file we begin by loading the console module. We now have the Y.Console object available to us. We create a new instance of this object, and then call the render method on this new instance.

Finally, we use the Y.log method to write three example log messages to demonstrate how messages are logged.

Upon loading the page in a web browser, the console is displayed, along with our three log messages as seen in the following screenshot:

Integrating Yahoo! User Interface Library (YUI) with Moodle

How it works...

Upon loading the console module, we now have available Y.Console and Y.log.

The Y.Console object allows us to create a new instance of the YUI Console, and when we call its render method, it is displayed in the page.

Finally, we use the Y.log method to display messages of three different severities: Information, Warning, and Error. We can use these as we see fit to display any type of debugging information we want to render inside a normal string of text.

Summary

In this article, we will cover:

  • Initializing the YUI 3 library
  • Loading YUI 3 modules
  • Loading YUI 2 modules from YUI 3
  • Attaching basic event handlers
  • Attaching advanced DOM event handlers
  • Implementing Event Delegation
  • Debugging with the YUI console

Further resources on this subject:


About the Author :


Alastair Hole

Alastair Hole is a web software developer, currently specializing in educational software—particularly that which pertains to Further and Higher Education in the UK. His web development experience began in the post dot-com boom era, working on business-to-business e-commerce web applications in the publishing industry with a focus on back-office integration. He has since then transferred his talents to the educational sector, and has created projects that have gone on to receive awards from bodies such as The Times Educational Supplement and the IMS Global Learning Consortium.

Alastair is the author of the award-winning Moodle IMS Content Package repository plugin 'MrCUTE - Moodle Repository: Create, Upload, Tag & Embed' [http://www.mrcute.co.uk] which is an Open Source project commissioned by the Joint Information Systems Committee (JISC) that has seen significant usage in Moodle sites worldwide, from Scotland to Australia.

Alastair maintains an interest in free and open educational software, and is currently involved in a number of bids for JISC funding to further develop repositories to provide easy access to learning materials in the UK Further and Higher Education sectors.

Books From Packt


Object-Oriented JavaScript
Object-Oriented JavaScript

Moodle Security
Moodle Security

Moodle 1.9 for Design and Technology
Moodle 1.9 for Design and Technology

Moodle 2.0 for Business Beginner's Guide
Moodle 2.0 for Business Beginner's Guide

Moodle 2.0 Multimedia Cookbook: RAW
Moodle 2.0 Multimedia Cookbook: RAW

Moodle 1.9 Top Extensions Cookbook
Moodle 1.9 Top Extensions Cookbook

Moodle 1.9 Theme Design: Beginner's Guide
Moodle 1.9 Theme Design: Beginner's Guide

Moodle as a Curriculum and Information Management System
Moodle as a Curriculum and Information Management System


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