<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Patrickthibaudeau</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Patrickthibaudeau"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Patrickthibaudeau"/>
	<updated>2026-08-11T19:58:03Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=54694</id>
		<title>Javascript Modules</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=54694"/>
		<updated>2018-09-04T12:03:51Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Javascript Modules =&lt;br /&gt;
&lt;br /&gt;
== What is a Javascript module and why do I care? ==&lt;br /&gt;
&lt;br /&gt;
A Javascript module is nothing more than a collection of Javascript code that can be used (reliably) from other pieces of Javascript. &lt;br /&gt;
&lt;br /&gt;
== Why should I package my code as a module? ==&lt;br /&gt;
&lt;br /&gt;
By packaging your code as a module you break your code up into smaller reusable pieces. This is good because:&lt;br /&gt;
&lt;br /&gt;
a) Each smaller piece is simpler to understand / debug&lt;br /&gt;
&lt;br /&gt;
b) Each smaller piece is simpler to test&lt;br /&gt;
&lt;br /&gt;
c) You can re-use common code instead of duplicating it&lt;br /&gt;
&lt;br /&gt;
= How do I write a Javascript module in Moodle? =&lt;br /&gt;
&lt;br /&gt;
Since version 2.9, Moodle supports Javascript modules written using the Asynchronous Module Definition ([https://github.com/amdjs/amdjs-api/wiki/AMD AMD]) API. This is a standard API for creating Javascript modules and you will find many useful third party libraries that are already using this format. &lt;br /&gt;
&lt;br /&gt;
To edit or create an AMD module in Moodle you need to do a couple of things. &lt;br /&gt;
&lt;br /&gt;
== Install grunt ==&lt;br /&gt;
&lt;br /&gt;
The AMD modules in Moodle must be processed by some build tools before they will be visible to your web browser. We use &amp;quot;[[grunt]]&amp;quot; as a build tool to wrap our different processes. Grunt is a build tool written in Javascript that runs in the &amp;quot;[http://nodejs.org/ nodejs]&amp;quot; environment.&lt;br /&gt;
&lt;br /&gt;
This means you first have to &#039;&#039;&#039;install nodejs&#039;&#039;&#039; - and its package manager [https://www.npmjs.com/ npm]. The details of how to install those packages will vary by operating system, but on Linux it&#039;s probably similar to &amp;quot;sudo apt-get install nodejs npm&amp;quot;. There are downloadable packages for other operating systems here: http://nodejs.org/download/. Moodle currently requires node &amp;quot;lts/carbon&amp;quot; (&amp;gt;=8.9 &amp;lt;9). &lt;br /&gt;
&lt;br /&gt;
Once this is done, you can &#039;&#039;&#039;run the command&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 npm install&lt;br /&gt;
 npm install -g grunt-cli&lt;br /&gt;
&lt;br /&gt;
from the top of the Moodle directory to install all of the required tools. (You may need extra permissions to use the -g option.)&lt;br /&gt;
&lt;br /&gt;
== Development mode ==&lt;br /&gt;
&lt;br /&gt;
To avoid having to constantly run grunt, make sure you set the following in your config.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Prevent JS caching&lt;br /&gt;
$CFG-&amp;gt;cachejs = false;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Moodle will now run your module from the amd/src module. Don&#039;t forget to switch this off and run &#039;grunt&#039; before deploying the new version!&lt;br /&gt;
&lt;br /&gt;
In this mode - if you get a strange message in your javascript console like &amp;quot;No define call for core/first&amp;quot; it means you have a syntax error in the javascript you are developing. &lt;br /&gt;
Or, &amp;quot;No define call for theme_XXX/loader&amp;quot; as you are probably missing the &#039;src&#039; folder with relevant JS files. which might happen when you turn debugging ON on a theme that was bought, without &#039;src&#039; folder :-(&lt;br /&gt;
&lt;br /&gt;
== Running grunt ==&lt;br /&gt;
&lt;br /&gt;
You can run grunt in your plugin&#039;s &#039;amd&#039; directory and it will only operate on your modules. If you&#039;re having problems or just want to check your work it is worth running for the &#039;lint&#039; feature. This can find basic problems. This sub-directory support wont work on Windows unfortunately but there is an alternative: Run grunt from the top directory with the --root=path/to/dir to limit execution to a sub-directory.&lt;br /&gt;
&lt;br /&gt;
See [[Grunt#Running_grunt]] for more details of specific grunt commands which can be used.&lt;br /&gt;
&lt;br /&gt;
If you get the error message&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/env: node: No such file or directory&lt;br /&gt;
&lt;br /&gt;
Then see the thread https://github.com/nodejs/node-v0.x-archive/issues/3911&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 14.04 this fixed it for me:&lt;br /&gt;
&lt;br /&gt;
 sudo ln -fs /usr/bin/nodejs /usr/local/bin/node&lt;br /&gt;
&lt;br /&gt;
Note: Once you have run grunt and built your code, you will then need to purge Moodle caches otherwise the changes made to your minified files may not be picked up by Moodle.&lt;br /&gt;
&lt;br /&gt;
== Minimum (getting started) module for plugins ==&lt;br /&gt;
&lt;br /&gt;
This shows the absolute minimum module you need to get started adding modules to your plugins. It&#039;s actually quite simple...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// Put this file in path/to/plugin/amd/src&lt;br /&gt;
// You can call it anything you like&lt;br /&gt;
&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function() {&lt;br /&gt;
&lt;br /&gt;
            // Put whatever you like here. $ is available&lt;br /&gt;
            // to you as normal.&lt;br /&gt;
            $(&amp;quot;.someclass&amp;quot;).change(function() {&lt;br /&gt;
                alert(&amp;quot;It changed!!&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code passes the jquery module into our function (parameter $). There are a number of other useful modules available in Moodle, some of which you&#039;ll probably need in a practical application. See [[Useful_core_Javascript_modules]]. Simply list them in both the define() first parameter and the function callback. E.g.,&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    define([&#039;jquery&#039;, &#039;core/str&#039;, &#039;core/ajax&#039;], function($, str, ajax) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea here is that we will run the &#039;init&#039; function from our (PHP) code to set things up. This is called from PHP like this...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;frankenstyle_path/your_js_filename&#039;, &#039;init&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to supply the complete &#039;[[Frankenstyle]]&#039; path. The .js is not needed. &lt;br /&gt;
&lt;br /&gt;
js_call_amd takes a third parameter which is an &#039;&#039;array&#039;&#039; of parameters. These will translate to individual parameters in the &#039;init&#039; function call. For example...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;block_iomad_company_admin/department_select&#039;, &#039;init&#039;, array($first, $last));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...calls&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    return {&lt;br /&gt;
        init: function(first, last) {&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A more comprehensive explanation follows...&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Hello World&amp;quot; I am a Javascript Module ==&lt;br /&gt;
Lets now create a simple Javascript module so we can see how to lay things out. &lt;br /&gt;
&lt;br /&gt;
Each Javascript module is contained in a single source file in the &amp;lt;componentdir&amp;gt;/amd/src folder. The final name of the module is taken from the file name and the component name. E.g. block_overview/amd/src/helloworld.js would be a module named &amp;quot;block_overview/helloworld&amp;quot;. the name of the module is important when you want to call it from somewhere else in the code. &lt;br /&gt;
&lt;br /&gt;
After running grunt - the minified Javascript files are stored in the &amp;lt;componentdir&amp;gt;/amd/build folder. The javascript files are renamed to show that they are minified (helloworld.js becomes helloworld.min.js). &lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to add the built files (the ones in amd/build) to your git commits, or in production no-one will see your changes. &lt;br /&gt;
&lt;br /&gt;
Lets create a simple module now:&lt;br /&gt;
&lt;br /&gt;
blocks/overview/amd/src/helloworld.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// Standard license block omitted.&lt;br /&gt;
/*&lt;br /&gt;
 * @package    block_overview&lt;br /&gt;
 * @copyright  2015 Someone cool&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * @module block_overview/helloworld&lt;br /&gt;
  */&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&lt;br /&gt;
     /** &lt;br /&gt;
      * Give me blue.&lt;br /&gt;
      * @access private&lt;br /&gt;
      * @return {string}&lt;br /&gt;
      */&lt;br /&gt;
     var makeItBlue = function() {&lt;br /&gt;
          // We can use our jquery dependency here.&lt;br /&gt;
          return $(&#039;.blue&#039;).show();&lt;br /&gt;
     };&lt;br /&gt;
      &lt;br /&gt;
    /**&lt;br /&gt;
     * @constructor&lt;br /&gt;
     * @alias module:block_overview/helloworld&lt;br /&gt;
     */&lt;br /&gt;
    var greeting = function() {&lt;br /&gt;
        /** @access private */&lt;br /&gt;
        var privateThoughts = &#039;I like the colour blue&#039;;&lt;br /&gt;
        &lt;br /&gt;
        /** @access public */&lt;br /&gt;
        this.publicThoughts = &#039;I like the colour orange&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * A formal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.formal = function() {&lt;br /&gt;
        return &#039;How do you do?&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * An informal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.informal = function() {&lt;br /&gt;
        return &#039;Wassup!&#039;;&lt;br /&gt;
    };&lt;br /&gt;
    return greeting;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The most interesting line above is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All AMD modules must call &amp;quot;define()&amp;quot; as the first and only global scoped piece of code. This ensures the javascript code contains no global variables and will not conflict with any other loaded module. The name of the module does not need to be specified because it is determined from the filename and component (but it can be listed in a comment for JSDoc as shown here). &lt;br /&gt;
&lt;br /&gt;
The first argument to &amp;quot;define&amp;quot; is the list of dependencies for the module. This argument must be passed as an array, even if there is only one. In this example &amp;quot;jquery&amp;quot; is a dependency. &amp;quot;jquery&amp;quot; is shipped as a core module is available to all AMD modules. &lt;br /&gt;
&lt;br /&gt;
The second argument to &amp;quot;define&amp;quot; is the function that defines the module. This function will receive as arguments, each of the requested dependencies in the same order they were requested. In this example we receive JQuery as an argument and we name the variable &amp;quot;$&amp;quot; (it&#039;s a JQuery thing). We can then access JQuery normally through the $ variable which is in scope for any code in our module. &lt;br /&gt;
&lt;br /&gt;
The rest of the code in this example is a standard way to define a Javascript module with public/private variables and methods. There are many ways to do this, this is only one.&lt;br /&gt;
&lt;br /&gt;
It is important that we are returning &#039;greeting&#039;. If there is no return then your module will be declared as undefined.&lt;br /&gt;
&lt;br /&gt;
== Loading modules dynamically ==&lt;br /&gt;
What do you do if you don&#039;t know in advance which modules will be required? Stuffing all possible required modules in the define call is one solution, but it&#039;s ugly and it only works for code that is in an AMD module (what about inline code in the page?). AMD lets you load a dependency any time you like. &lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Load a new dependency.&lt;br /&gt;
require([&#039;mod_wiki/timer&#039;], function(timer) {&lt;br /&gt;
   // timer is available to do my bidding.&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Including an external javascript/jquery library ==&lt;br /&gt;
If you want to include a javascript / jquery library downloaded from the internet you can do so as follows:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning: if the library you download, supports AMD but is already &amp;quot;named&amp;quot; you will not be able to include it directly&#039;&#039;&#039;&lt;br /&gt;
e.g. &lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
        define(&amp;quot;typeahead.js&amp;quot;, *[ &amp;quot;jquery&amp;quot; ], function(a0) {&lt;br /&gt;
            return factory(a0);&lt;br /&gt;
        });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
will not work, as moodle injects it&#039;s own define name when loading the library.&lt;br /&gt;
&lt;br /&gt;
If the library is in AMD format and has a define:&lt;br /&gt;
e.g. i want to include the jquery final countdown timer on my page ( hilios.github.io/jQuery.countdown/ )&lt;br /&gt;
* download the module in both normal and minified versions&lt;br /&gt;
* place the modules in your moodle install e.g. your custom theme dir, or plugin dir&lt;br /&gt;
* /theme/mytheme/amd/src/jquery.countdown.js&lt;br /&gt;
&lt;br /&gt;
you can now include the module and initialise it (there are multiple ways to do this)&lt;br /&gt;
php:&lt;br /&gt;
&lt;br /&gt;
1. Create your own AMD module and initialise it:&lt;br /&gt;
&lt;br /&gt;
In your PHP file:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_call_amd(&#039;theme_mytheme/countdowntimer&#039;, &#039;initialise&#039;, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Javascript module:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// /theme/mytheme/amd/src/countdowntimer.js&lt;br /&gt;
define([&#039;jquery&#039;, &#039;theme_mytheme/jquery.countdown&#039;], function($, c) {&lt;br /&gt;
    return {&lt;br /&gt;
        initialise: function ($params) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Put the javascript into a mustache template:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// /theme/mytheme/templates/countdowntimer.mustache&lt;br /&gt;
&amp;lt;span id=&amp;quot;clock&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require([&#039;jquery&#039;, &#039;theme_mytheme/jquery.countdown&#039;], function($) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Call the javascript directly from php (although who would want to put javascript into php? ergh):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_amd_inline(&#039;&lt;br /&gt;
require([&#039;theme_mytheme/jquery.countdown&#039;], function(min) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
});&lt;br /&gt;
&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Embedding AMD code in a page ==&lt;br /&gt;
So you have created lots of cool Javascript modules. Great. How do we actually call them? Any javascript code that calls an AMD module must execute AFTER the requirejs module loader has finished loading. We have provided a function &amp;quot;js_call_amd&amp;quot; that will call a single function from an AMD module with parameters.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_call_amd($modulename, $functionname, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
that will &amp;quot;do the right thing&amp;quot; with your block of AMD code and execute it at the end of the page, after our AMD module loader has loaded. &lt;br /&gt;
Notes:&lt;br /&gt;
* the $modulename is the &#039;componentname/modulename&#039; discussed above&lt;br /&gt;
* the $functionname is the name of a public function exposed by the amd module. &lt;br /&gt;
* the $params is an array of params passed as arguments to the function. These should be simple types that can be handled by json_encode (no recursive arrays, or complex classes please). &lt;br /&gt;
* if the size of the params array is too large (&amp;gt; 1Kb), this will produce a developer warning. Do not attempt to pass large amounts of data through this function, it will pollute the page size. A preferred approach is to pass css selectors for DOM elements that contain data-attributes for any required data, or fetch data via ajax in the background.&lt;br /&gt;
&lt;br /&gt;
AMD / JS code can also be embedded on a page via mustache templates&lt;br /&gt;
see here: https://docs.moodle.org/dev/Templates#What_if_a_template_contains_javascript.3F&lt;br /&gt;
&lt;br /&gt;
== But I have a mega JS file I don&#039;t want loaded on every page? ==&lt;br /&gt;
Loading all JS files at once and stuffing them in the browser cache is the right choice for MOST js files, there are probably some exceptions. For these files, you can rename the javascript file to end with the suffix &amp;quot;-lazy.js&amp;quot; which indicates that the module will not be loaded by default, it will be requested the first time it is used. There is no difference in usage for lazy loaded modules, the require() call looks exactly the same, it&#039;s just that the module name will also have the &amp;quot;-lazy&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [https://assets.moodlemoot.org/sites/15/20171004085436/JavaScript-AMD-with-RequireJS-presented-by-Daniel-Roperto-Catalyst.pdf JavaScript AMD with RequireJS] presented by Daniel Roperto, Catalyst. (MoodleMOOT AU 2017)&lt;br /&gt;
* [[Useful_core_Javascript_modules]]&lt;br /&gt;
*[[Guide_to_adding_third_party_jQuery_for_AMD]] by Patrick Thibaudeau&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=54592</id>
		<title>Javascript Modules</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=54592"/>
		<updated>2018-08-03T19:35:08Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Javascript Modules =&lt;br /&gt;
&lt;br /&gt;
== What is a Javascript module and why do I care? ==&lt;br /&gt;
&lt;br /&gt;
A Javascript module is nothing more than a collection of Javascript code that can be used (reliably) from other pieces of Javascript. &lt;br /&gt;
&lt;br /&gt;
== Why should I package my code as a module? ==&lt;br /&gt;
&lt;br /&gt;
By packaging your code as a module you break your code up into smaller reusable pieces. This is good because:&lt;br /&gt;
&lt;br /&gt;
a) Each smaller piece is simpler to understand / debug&lt;br /&gt;
&lt;br /&gt;
b) Each smaller piece is simpler to test&lt;br /&gt;
&lt;br /&gt;
c) You can re-use common code instead of duplicating it&lt;br /&gt;
&lt;br /&gt;
= How do I write a Javascript module in Moodle? =&lt;br /&gt;
&lt;br /&gt;
Since version 2.9, Moodle supports Javascript modules written using the Asynchronous Module Definition ([https://github.com/amdjs/amdjs-api/wiki/AMD AMD]) API. This is a standard API for creating Javascript modules and you will find many useful third party libraries that are already using this format. &lt;br /&gt;
&lt;br /&gt;
To edit or create an AMD module in Moodle you need to do a couple of things. &lt;br /&gt;
&lt;br /&gt;
== Install grunt ==&lt;br /&gt;
&lt;br /&gt;
The AMD modules in Moodle must be processed by some build tools before they will be visible to your web browser. We use &amp;quot;[[grunt]]&amp;quot; as a build tool to wrap our different processes. Grunt is a build tool written in Javascript that runs in the &amp;quot;[http://nodejs.org/ nodejs]&amp;quot; environment.&lt;br /&gt;
&lt;br /&gt;
This means you first have to &#039;&#039;&#039;install nodejs&#039;&#039;&#039; - and its package manager [https://www.npmjs.com/ npm]. The details of how to install those packages will vary by operating system, but on Linux it&#039;s probably similar to &amp;quot;sudo apt-get install nodejs npm&amp;quot;. There are downloadable packages for other operating systems here: http://nodejs.org/download/. Moodle currently requires node &amp;quot;lts/carbon&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Once this is done, you can &#039;&#039;&#039;run the command&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 npm install&lt;br /&gt;
 npm install -g grunt-cli&lt;br /&gt;
&lt;br /&gt;
from the top of the Moodle directory to install all of the required tools. (You may need extra permissions to use the -g option.)&lt;br /&gt;
&lt;br /&gt;
== Development mode ==&lt;br /&gt;
&lt;br /&gt;
To avoid having to constantly run grunt, make sure you set the following in your config.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Prevent JS caching&lt;br /&gt;
$CFG-&amp;gt;cachejs = false;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Moodle will now run your module from the amd/src module. Don&#039;t forget to switch this off and run &#039;grunt&#039; before deploying the new version!&lt;br /&gt;
&lt;br /&gt;
In this mode - if you get a strange message in your javascript console like &amp;quot;No define call for core/first&amp;quot; it means you have a syntax error in the javascript you are developing. &lt;br /&gt;
Or, &amp;quot;No define call for theme_XXX/loader&amp;quot; as you are probably missing the &#039;src&#039; folder with relevant JS files. which might happen when you turn debugging ON on a theme that was bought, without &#039;src&#039; folder :-(&lt;br /&gt;
&lt;br /&gt;
== Running grunt ==&lt;br /&gt;
&lt;br /&gt;
You can run grunt in your plugin&#039;s &#039;amd&#039; directory and it will only operate on your modules. If you&#039;re having problems or just want to check your work it is worth running for the &#039;lint&#039; feature. This can find basic problems. This sub-directory support wont work on Windows unfortunately but there is an alternative: Run grunt from the top directory with the --root=path/to/dir to limit execution to a sub-directory.&lt;br /&gt;
&lt;br /&gt;
See [[Grunt#Running_grunt]] for more details of specific grunt commands which can be used.&lt;br /&gt;
&lt;br /&gt;
If you get the error message&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/env: node: No such file or directory&lt;br /&gt;
&lt;br /&gt;
Then see the thread https://github.com/nodejs/node-v0.x-archive/issues/3911&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 14.04 this fixed it for me:&lt;br /&gt;
&lt;br /&gt;
 sudo ln -fs /usr/bin/nodejs /usr/local/bin/node&lt;br /&gt;
&lt;br /&gt;
Note: Once you have run grunt and built your code, you will then need to purge Moodle caches otherwise the changes made to your minified files may not be picked up by Moodle.&lt;br /&gt;
&lt;br /&gt;
== Minimum (getting started) module for plugins ==&lt;br /&gt;
&lt;br /&gt;
This shows the absolute minimum module you need to get started adding modules to your plugins. It&#039;s actually quite simple...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// Put this file in path/to/plugin/amd/src&lt;br /&gt;
// You can call it anything you like&lt;br /&gt;
&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function() {&lt;br /&gt;
&lt;br /&gt;
            // Put whatever you like here. $ is available&lt;br /&gt;
            // to you as normal.&lt;br /&gt;
            $(&amp;quot;.someclass&amp;quot;).change(function() {&lt;br /&gt;
                alert(&amp;quot;It changed!!&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code passes the jquery module into our function (parameter $). There are a number of other useful modules available in Moodle, some of which you&#039;ll probably need in a practical application. See [[Useful_core_Javascript_modules]]. Simply list them in both the define() first parameter and the function callback. E.g.,&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    define([&#039;jquery&#039;, &#039;core/str&#039;, &#039;core/ajax&#039;], function($, str, ajax) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea here is that we will run the &#039;init&#039; function from our (PHP) code to set things up. This is called from PHP like this...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;frankenstyle_path/your_js_filename&#039;, &#039;init&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to supply the complete &#039;[[Frankenstyle]]&#039; path. The .js is not needed. &lt;br /&gt;
&lt;br /&gt;
js_call_amd takes a third parameter which is an &#039;&#039;array&#039;&#039; of parameters. These will translate to individual parameters in the &#039;init&#039; function call. For example...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;block_iomad_company_admin/department_select&#039;, &#039;init&#039;, array($first, $last));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...calls&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    return {&lt;br /&gt;
        init: function(first, last) {&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A more comprehensive explanation follows...&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Hello World&amp;quot; I am a Javascript Module ==&lt;br /&gt;
Lets now create a simple Javascript module so we can see how to lay things out. &lt;br /&gt;
&lt;br /&gt;
Each Javascript module is contained in a single source file in the &amp;lt;componentdir&amp;gt;/amd/src folder. The final name of the module is taken from the file name and the component name. E.g. block_overview/amd/src/helloworld.js would be a module named &amp;quot;block_overview/helloworld&amp;quot;. the name of the module is important when you want to call it from somewhere else in the code. &lt;br /&gt;
&lt;br /&gt;
After running grunt - the minified Javascript files are stored in the &amp;lt;componentdir&amp;gt;/amd/build folder. The javascript files are renamed to show that they are minified (helloworld.js becomes helloworld.min.js). &lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to add the built files (the ones in amd/build) to your git commits, or in production no-one will see your changes. &lt;br /&gt;
&lt;br /&gt;
Lets create a simple module now:&lt;br /&gt;
&lt;br /&gt;
blocks/overview/amd/src/helloworld.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// Standard license block omitted.&lt;br /&gt;
/*&lt;br /&gt;
 * @package    block_overview&lt;br /&gt;
 * @copyright  2015 Someone cool&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * @module block_overview/helloworld&lt;br /&gt;
  */&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&lt;br /&gt;
     /** &lt;br /&gt;
      * Give me blue.&lt;br /&gt;
      * @access private&lt;br /&gt;
      * @return {string}&lt;br /&gt;
      */&lt;br /&gt;
     var makeItBlue = function() {&lt;br /&gt;
          // We can use our jquery dependency here.&lt;br /&gt;
          return $(&#039;.blue&#039;).show();&lt;br /&gt;
     };&lt;br /&gt;
      &lt;br /&gt;
    /**&lt;br /&gt;
     * @constructor&lt;br /&gt;
     * @alias module:block_overview/helloworld&lt;br /&gt;
     */&lt;br /&gt;
    var greeting = function() {&lt;br /&gt;
        /** @access private */&lt;br /&gt;
        var privateThoughts = &#039;I like the colour blue&#039;;&lt;br /&gt;
        &lt;br /&gt;
        /** @access public */&lt;br /&gt;
        this.publicThoughts = &#039;I like the colour orange&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * A formal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.formal = function() {&lt;br /&gt;
        return &#039;How do you do?&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * An informal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.informal = function() {&lt;br /&gt;
        return &#039;Wassup!&#039;;&lt;br /&gt;
    };&lt;br /&gt;
    return greeting;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The most interesting line above is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All AMD modules must call &amp;quot;define()&amp;quot; as the first and only global scoped piece of code. This ensures the javascript code contains no global variables and will not conflict with any other loaded module. The name of the module does not need to be specified because it is determined from the filename and component (but it can be listed in a comment for JSDoc as shown here). &lt;br /&gt;
&lt;br /&gt;
The first argument to &amp;quot;define&amp;quot; is the list of dependencies for the module. This argument must be passed as an array, even if there is only one. In this example &amp;quot;jquery&amp;quot; is a dependency. &amp;quot;jquery&amp;quot; is shipped as a core module is available to all AMD modules. &lt;br /&gt;
&lt;br /&gt;
The second argument to &amp;quot;define&amp;quot; is the function that defines the module. This function will receive as arguments, each of the requested dependencies in the same order they were requested. In this example we receive JQuery as an argument and we name the variable &amp;quot;$&amp;quot; (it&#039;s a JQuery thing). We can then access JQuery normally through the $ variable which is in scope for any code in our module. &lt;br /&gt;
&lt;br /&gt;
The rest of the code in this example is a standard way to define a Javascript module with public/private variables and methods. There are many ways to do this, this is only one.&lt;br /&gt;
&lt;br /&gt;
It is important that we are returning &#039;greeting&#039;. If there is no return then your module will be declared as undefined.&lt;br /&gt;
&lt;br /&gt;
== Loading modules dynamically ==&lt;br /&gt;
What do you do if you don&#039;t know in advance which modules will be required? Stuffing all possible required modules in the define call is one solution, but it&#039;s ugly and it only works for code that is in an AMD module (what about inline code in the page?). AMD lets you load a dependency any time you like. &lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Load a new dependency.&lt;br /&gt;
require([&#039;mod_wiki/timer&#039;], function(timer) {&lt;br /&gt;
   // timer is available to do my bidding.&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Including an external javascript/jquery library ==&lt;br /&gt;
If you want to include a javascript / jquery library downloaded from the internet you can do so as follows:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning: if the library you download, supports AMD but is already &amp;quot;named&amp;quot; you will not be able to include it directly&#039;&#039;&#039;&lt;br /&gt;
e.g. &lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
        define(&amp;quot;typeahead.js&amp;quot;, *[ &amp;quot;jquery&amp;quot; ], function(a0) {&lt;br /&gt;
            return factory(a0);&lt;br /&gt;
        });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
will not work, as moodle injects it&#039;s own define name when loading the library.&lt;br /&gt;
&lt;br /&gt;
If the library is in AMD format and has a define:&lt;br /&gt;
e.g. i want to include the jquery final countdown timer on my page ( hilios.github.io/jQuery.countdown/ )&lt;br /&gt;
* download the module in both normal and minified versions&lt;br /&gt;
* place the modules in your moodle install e.g. your custom theme dir, or plugin dir&lt;br /&gt;
* /theme/mytheme/amd/src/jquery.countdown.js&lt;br /&gt;
&lt;br /&gt;
you can now include the module and initialise it (there are multiple ways to do this)&lt;br /&gt;
php:&lt;br /&gt;
&lt;br /&gt;
1. Create your own AMD module and initialise it:&lt;br /&gt;
&lt;br /&gt;
In your PHP file:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_call_amd(&#039;theme_mytheme/countdowntimer&#039;, &#039;initialise&#039;, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Javascript module:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// /theme/mytheme/amd/src/countdowntimer.js&lt;br /&gt;
define([&#039;jquery&#039;, &#039;theme_mytheme/jquery.countdown&#039;], function($, c) {&lt;br /&gt;
    return {&lt;br /&gt;
        initialise: function ($params) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Put the javascript into a mustache template:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// /theme/mytheme/templates/countdowntimer.mustache&lt;br /&gt;
&amp;lt;span id=&amp;quot;clock&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require([&#039;jquery&#039;, &#039;theme_mytheme/jquery.countdown&#039;], function($) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Call the javascript directly from php (although who would want to put javascript into php? ergh):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_amd_inline(&#039;&lt;br /&gt;
require([&#039;theme_mytheme/jquery.countdown&#039;], function(min) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
});&lt;br /&gt;
&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Embedding AMD code in a page ==&lt;br /&gt;
So you have created lots of cool Javascript modules. Great. How do we actually call them? Any javascript code that calls an AMD module must execute AFTER the requirejs module loader has finished loading. We have provided a function &amp;quot;js_call_amd&amp;quot; that will call a single function from an AMD module with parameters.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_call_amd($modulename, $functionname, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
that will &amp;quot;do the right thing&amp;quot; with your block of AMD code and execute it at the end of the page, after our AMD module loader has loaded. &lt;br /&gt;
Notes:&lt;br /&gt;
* the $modulename is the &#039;componentname/modulename&#039; discussed above&lt;br /&gt;
* the $functionname is the name of a public function exposed by the amd module. &lt;br /&gt;
* the $params is an array of params passed as arguments to the function. These should be simple types that can be handled by json_encode (no recursive arrays, or complex classes please). &lt;br /&gt;
* if the size of the params array is too large (&amp;gt; 1Kb), this will produce a developer warning. Do not attempt to pass large amounts of data through this function, it will pollute the page size. A preferred approach is to pass css selectors for DOM elements that contain data-attributes for any required data, or fetch data via ajax in the background.&lt;br /&gt;
&lt;br /&gt;
AMD / JS code can also be embedded on a page via mustache templates&lt;br /&gt;
see here: https://docs.moodle.org/dev/Templates#What_if_a_template_contains_javascript.3F&lt;br /&gt;
&lt;br /&gt;
== But I have a mega JS file I don&#039;t want loaded on every page? ==&lt;br /&gt;
Loading all JS files at once and stuffing them in the browser cache is the right choice for MOST js files, there are probably some exceptions. For these files, you can rename the javascript file to end with the suffix &amp;quot;-lazy.js&amp;quot; which indicates that the module will not be loaded by default, it will be requested the first time it is used. There is no difference in usage for lazy loaded modules, the require() call looks exactly the same, it&#039;s just that the module name will also have the &amp;quot;-lazy&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [https://assets.moodlemoot.org/sites/15/20171004085436/JavaScript-AMD-with-RequireJS-presented-by-Daniel-Roperto-Catalyst.pdf JavaScript AMD with RequireJS] presented by Daniel Roperto, Catalyst. (MoodleMOOT AU 2017)&lt;br /&gt;
* [[Useful_core_Javascript_modules]]&lt;br /&gt;
*[[Guide_to_adding_third_party_jQuery_for_AMD]] by Patrick Thibaudeau (Oohoo.biz)&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54591</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54591"/>
		<updated>2018-08-03T17:34:04Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Using your third party plugins in your custom java-script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Finding it hard to find good documentation, I decided to share the steps I used to add third party jQuery libraries to my plugin. There may be other ways to do this, however, this is the way I found that worked for my projects. Throughout this tutorial, I will be referring to the jQuery plugin called [https://fullcalendar.io/ FullCalendar]. I use FullCalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
== Create the folder structure ==&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
== Configure the shim file ==&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== File definitions ==&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using your third party plugins in your custom java-script ==&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
== But wait! The CSS is not loaded ==&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css in php. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=54588</id>
		<title>Javascript Modules</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=54588"/>
		<updated>2018-08-03T12:30:54Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Javascript Modules =&lt;br /&gt;
&lt;br /&gt;
== What is a Javascript module and why do I care? ==&lt;br /&gt;
&lt;br /&gt;
A Javascript module is nothing more than a collection of Javascript code that can be used (reliably) from other pieces of Javascript. &lt;br /&gt;
&lt;br /&gt;
== Why should I package my code as a module? ==&lt;br /&gt;
&lt;br /&gt;
By packaging your code as a module you break your code up into smaller reusable pieces. This is good because:&lt;br /&gt;
&lt;br /&gt;
a) Each smaller piece is simpler to understand / debug&lt;br /&gt;
&lt;br /&gt;
b) Each smaller piece is simpler to test&lt;br /&gt;
&lt;br /&gt;
c) You can re-use common code instead of duplicating it&lt;br /&gt;
&lt;br /&gt;
= How do I write a Javascript module in Moodle? =&lt;br /&gt;
&lt;br /&gt;
Since version 2.9, Moodle supports Javascript modules written using the Asynchronous Module Definition ([https://github.com/amdjs/amdjs-api/wiki/AMD AMD]) API. This is a standard API for creating Javascript modules and you will find many useful third party libraries that are already using this format. &lt;br /&gt;
&lt;br /&gt;
To edit or create an AMD module in Moodle you need to do a couple of things. &lt;br /&gt;
&lt;br /&gt;
== Install grunt ==&lt;br /&gt;
&lt;br /&gt;
The AMD modules in Moodle must be processed by some build tools before they will be visible to your web browser. We use &amp;quot;[[grunt]]&amp;quot; as a build tool to wrap our different processes. Grunt is a build tool written in Javascript that runs in the &amp;quot;[http://nodejs.org/ nodejs]&amp;quot; environment.&lt;br /&gt;
&lt;br /&gt;
This means you first have to &#039;&#039;&#039;install nodejs&#039;&#039;&#039; - and its package manager [https://www.npmjs.com/ npm]. The details of how to install those packages will vary by operating system, but on Linux it&#039;s probably similar to &amp;quot;sudo apt-get install nodejs npm&amp;quot;. There are downloadable packages for other operating systems here: http://nodejs.org/download/. Moodle currently requires node &amp;quot;lts/carbon&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Once this is done, you can &#039;&#039;&#039;run the command&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 npm install&lt;br /&gt;
 npm install -g grunt-cli&lt;br /&gt;
&lt;br /&gt;
from the top of the Moodle directory to install all of the required tools. (You may need extra permissions to use the -g option.)&lt;br /&gt;
&lt;br /&gt;
== Development mode ==&lt;br /&gt;
&lt;br /&gt;
To avoid having to constantly run grunt, make sure you set the following in your config.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Prevent JS caching&lt;br /&gt;
$CFG-&amp;gt;cachejs = false;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Moodle will now run your module from the amd/src module. Don&#039;t forget to switch this off and run &#039;grunt&#039; before deploying the new version!&lt;br /&gt;
&lt;br /&gt;
In this mode - if you get a strange message in your javascript console like &amp;quot;No define call for core/first&amp;quot; it means you have a syntax error in the javascript you are developing. &lt;br /&gt;
Or, &amp;quot;No define call for theme_XXX/loader&amp;quot; as you are probably missing the &#039;src&#039; folder with relevant JS files. which might happen when you turn debugging ON on a theme that was bought, without &#039;src&#039; folder :-(&lt;br /&gt;
&lt;br /&gt;
== Running grunt ==&lt;br /&gt;
&lt;br /&gt;
You can run grunt in your plugin&#039;s &#039;amd&#039; directory and it will only operate on your modules. If you&#039;re having problems or just want to check your work it is worth running for the &#039;lint&#039; feature. This can find basic problems. This sub-directory support wont work on Windows unfortunately but there is an alternative: Run grunt from the top directory with the --root=path/to/dir to limit execution to a sub-directory.&lt;br /&gt;
&lt;br /&gt;
See [[Grunt#Running_grunt]] for more details of specific grunt commands which can be used.&lt;br /&gt;
&lt;br /&gt;
If you get the error message&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/env: node: No such file or directory&lt;br /&gt;
&lt;br /&gt;
Then see the thread https://github.com/nodejs/node-v0.x-archive/issues/3911&lt;br /&gt;
&lt;br /&gt;
On Ubuntu 14.04 this fixed it for me:&lt;br /&gt;
&lt;br /&gt;
 sudo ln -fs /usr/bin/nodejs /usr/local/bin/node&lt;br /&gt;
&lt;br /&gt;
Note: Once you have run grunt and built your code, you will then need to purge Moodle caches otherwise the changes made to your minified files may not be picked up by Moodle.&lt;br /&gt;
&lt;br /&gt;
== Minimum (getting started) module for plugins ==&lt;br /&gt;
&lt;br /&gt;
This shows the absolute minimum module you need to get started adding modules to your plugins. It&#039;s actually quite simple...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// Put this file in path/to/plugin/amd/src&lt;br /&gt;
// You can call it anything you like&lt;br /&gt;
&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function() {&lt;br /&gt;
&lt;br /&gt;
            // Put whatever you like here. $ is available&lt;br /&gt;
            // to you as normal.&lt;br /&gt;
            $(&amp;quot;.someclass&amp;quot;).change(function() {&lt;br /&gt;
                alert(&amp;quot;It changed!!&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code passes the jquery module into our function (parameter $). There are a number of other useful modules available in Moodle, some of which you&#039;ll probably need in a practical application. See [[Useful_core_Javascript_modules]]. Simply list them in both the define() first parameter and the function callback. E.g.,&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    define([&#039;jquery&#039;, &#039;core/str&#039;, &#039;core/ajax&#039;], function($, str, ajax) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea here is that we will run the &#039;init&#039; function from our (PHP) code to set things up. This is called from PHP like this...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;frankenstyle_path/your_js_filename&#039;, &#039;init&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to supply the complete &#039;[[Frankenstyle]]&#039; path. The .js is not needed. &lt;br /&gt;
&lt;br /&gt;
js_call_amd takes a third parameter which is an &#039;&#039;array&#039;&#039; of parameters. These will translate to individual parameters in the &#039;init&#039; function call. For example...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $PAGE-&amp;gt;requires-&amp;gt;js_call_amd(&#039;block_iomad_company_admin/department_select&#039;, &#039;init&#039;, array($first, $last));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...calls&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    return {&lt;br /&gt;
        init: function(first, last) {&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A more comprehensive explanation follows...&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Hello World&amp;quot; I am a Javascript Module ==&lt;br /&gt;
Lets now create a simple Javascript module so we can see how to lay things out. &lt;br /&gt;
&lt;br /&gt;
Each Javascript module is contained in a single source file in the &amp;lt;componentdir&amp;gt;/amd/src folder. The final name of the module is taken from the file name and the component name. E.g. block_overview/amd/src/helloworld.js would be a module named &amp;quot;block_overview/helloworld&amp;quot;. the name of the module is important when you want to call it from somewhere else in the code. &lt;br /&gt;
&lt;br /&gt;
After running grunt - the minified Javascript files are stored in the &amp;lt;componentdir&amp;gt;/amd/build folder. The javascript files are renamed to show that they are minified (helloworld.js becomes helloworld.min.js). &lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to add the built files (the ones in amd/build) to your git commits, or in production no-one will see your changes. &lt;br /&gt;
&lt;br /&gt;
Lets create a simple module now:&lt;br /&gt;
&lt;br /&gt;
blocks/overview/amd/src/helloworld.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// Standard license block omitted.&lt;br /&gt;
/*&lt;br /&gt;
 * @package    block_overview&lt;br /&gt;
 * @copyright  2015 Someone cool&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * @module block_overview/helloworld&lt;br /&gt;
  */&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&lt;br /&gt;
     /** &lt;br /&gt;
      * Give me blue.&lt;br /&gt;
      * @access private&lt;br /&gt;
      * @return {string}&lt;br /&gt;
      */&lt;br /&gt;
     var makeItBlue = function() {&lt;br /&gt;
          // We can use our jquery dependency here.&lt;br /&gt;
          return $(&#039;.blue&#039;).show();&lt;br /&gt;
     };&lt;br /&gt;
      &lt;br /&gt;
    /**&lt;br /&gt;
     * @constructor&lt;br /&gt;
     * @alias module:block_overview/helloworld&lt;br /&gt;
     */&lt;br /&gt;
    var greeting = function() {&lt;br /&gt;
        /** @access private */&lt;br /&gt;
        var privateThoughts = &#039;I like the colour blue&#039;;&lt;br /&gt;
        &lt;br /&gt;
        /** @access public */&lt;br /&gt;
        this.publicThoughts = &#039;I like the colour orange&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * A formal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.formal = function() {&lt;br /&gt;
        return &#039;How do you do?&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * An informal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.informal = function() {&lt;br /&gt;
        return &#039;Wassup!&#039;;&lt;br /&gt;
    };&lt;br /&gt;
    return greeting;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The most interesting line above is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All AMD modules must call &amp;quot;define()&amp;quot; as the first and only global scoped piece of code. This ensures the javascript code contains no global variables and will not conflict with any other loaded module. The name of the module does not need to be specified because it is determined from the filename and component (but it can be listed in a comment for JSDoc as shown here). &lt;br /&gt;
&lt;br /&gt;
The first argument to &amp;quot;define&amp;quot; is the list of dependencies for the module. This argument must be passed as an array, even if there is only one. In this example &amp;quot;jquery&amp;quot; is a dependency. &amp;quot;jquery&amp;quot; is shipped as a core module is available to all AMD modules. &lt;br /&gt;
&lt;br /&gt;
The second argument to &amp;quot;define&amp;quot; is the function that defines the module. This function will receive as arguments, each of the requested dependencies in the same order they were requested. In this example we receive JQuery as an argument and we name the variable &amp;quot;$&amp;quot; (it&#039;s a JQuery thing). We can then access JQuery normally through the $ variable which is in scope for any code in our module. &lt;br /&gt;
&lt;br /&gt;
The rest of the code in this example is a standard way to define a Javascript module with public/private variables and methods. There are many ways to do this, this is only one.&lt;br /&gt;
&lt;br /&gt;
It is important that we are returning &#039;greeting&#039;. If there is no return then your module will be declared as undefined.&lt;br /&gt;
&lt;br /&gt;
== Loading modules dynamically ==&lt;br /&gt;
What do you do if you don&#039;t know in advance which modules will be required? Stuffing all possible required modules in the define call is one solution, but it&#039;s ugly and it only works for code that is in an AMD module (what about inline code in the page?). AMD lets you load a dependency any time you like. &lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Load a new dependency.&lt;br /&gt;
require([&#039;mod_wiki/timer&#039;], function(timer) {&lt;br /&gt;
   // timer is available to do my bidding.&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Including an external javascript/jquery library ==&lt;br /&gt;
If you want to include a javascript / jquery library downloaded from the internet you can do so as follows:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning: if the library you download, supports AMD but is already &amp;quot;named&amp;quot; you will not be able to include it directly&#039;&#039;&#039;&lt;br /&gt;
e.g. &lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
        define(&amp;quot;typeahead.js&amp;quot;, *[ &amp;quot;jquery&amp;quot; ], function(a0) {&lt;br /&gt;
            return factory(a0);&lt;br /&gt;
        });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
will not work, as moodle injects it&#039;s own define name when loading the library.&lt;br /&gt;
&lt;br /&gt;
If the library is in AMD format and has a define:&lt;br /&gt;
e.g. i want to include the jquery final countdown timer on my page ( hilios.github.io/jQuery.countdown/ )&lt;br /&gt;
* download the module in both normal and minified versions&lt;br /&gt;
* place the modules in your moodle install e.g. your custom theme dir, or plugin dir&lt;br /&gt;
* /theme/mytheme/amd/src/jquery.countdown.js&lt;br /&gt;
&lt;br /&gt;
you can now include the module and initialise it (there are multiple ways to do this)&lt;br /&gt;
php:&lt;br /&gt;
&lt;br /&gt;
1. Create your own AMD module and initialise it:&lt;br /&gt;
&lt;br /&gt;
In your PHP file:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_call_amd(&#039;theme_mytheme/countdowntimer&#039;, &#039;initialise&#039;, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Javascript module:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// /theme/mytheme/amd/src/countdowntimer.js&lt;br /&gt;
define([&#039;jquery&#039;, &#039;theme_mytheme/jquery.countdown&#039;], function($, c) {&lt;br /&gt;
    return {&lt;br /&gt;
        initialise: function ($params) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Put the javascript into a mustache template:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// /theme/mytheme/templates/countdowntimer.mustache&lt;br /&gt;
&amp;lt;span id=&amp;quot;clock&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require([&#039;jquery&#039;, &#039;theme_mytheme/jquery.countdown&#039;], function($) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Call the javascript directly from php (although who would want to put javascript into php? ergh):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_amd_inline(&#039;&lt;br /&gt;
require([&#039;theme_mytheme/jquery.countdown&#039;], function(min) {&lt;br /&gt;
           $(&#039;#clock&#039;).countdown(&#039;2020/10/10&#039;, function(event) {&lt;br /&gt;
             $(this).html(event.strftime(&#039;%D days %H:%M:%S&#039;));&lt;br /&gt;
           });&lt;br /&gt;
});&lt;br /&gt;
&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Embedding AMD code in a page ==&lt;br /&gt;
So you have created lots of cool Javascript modules. Great. How do we actually call them? Any javascript code that calls an AMD module must execute AFTER the requirejs module loader has finished loading. We have provided a function &amp;quot;js_call_amd&amp;quot; that will call a single function from an AMD module with parameters.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_call_amd($modulename, $functionname, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
that will &amp;quot;do the right thing&amp;quot; with your block of AMD code and execute it at the end of the page, after our AMD module loader has loaded. &lt;br /&gt;
Notes:&lt;br /&gt;
* the $modulename is the &#039;componentname/modulename&#039; discussed above&lt;br /&gt;
* the $functionname is the name of a public function exposed by the amd module. &lt;br /&gt;
* the $params is an array of params passed as arguments to the function. These should be simple types that can be handled by json_encode (no recursive arrays, or complex classes please). &lt;br /&gt;
* if the size of the params array is too large (&amp;gt; 1Kb), this will produce a developer warning. Do not attempt to pass large amounts of data through this function, it will pollute the page size. A preferred approach is to pass css selectors for DOM elements that contain data-attributes for any required data, or fetch data via ajax in the background.&lt;br /&gt;
&lt;br /&gt;
AMD / JS code can also be embedded on a page via mustache templates&lt;br /&gt;
see here: https://docs.moodle.org/dev/Templates#What_if_a_template_contains_javascript.3F&lt;br /&gt;
&lt;br /&gt;
== But I have a mega JS file I don&#039;t want loaded on every page? ==&lt;br /&gt;
Loading all JS files at once and stuffing them in the browser cache is the right choice for MOST js files, there are probably some exceptions. For these files, you can rename the javascript file to end with the suffix &amp;quot;-lazy.js&amp;quot; which indicates that the module will not be loaded by default, it will be requested the first time it is used. There is no difference in usage for lazy loaded modules, the require() call looks exactly the same, it&#039;s just that the module name will also have the &amp;quot;-lazy&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [https://assets.moodlemoot.org/sites/15/20171004085436/JavaScript-AMD-with-RequireJS-presented-by-Daniel-Roperto-Catalyst.pdf JavaScript AMD with RequireJS] presented by Daniel Roperto, Catalyst. (MoodleMOOT AU 2017)&lt;br /&gt;
* [[Useful_core_Javascript_modules]]&lt;br /&gt;
*[[Guide_to_adding_third_party_jQuery_for_AMD]] by Patrick Thibaudeau&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54587</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54587"/>
		<updated>2018-08-03T12:27:10Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Finding it hard to find good documentation, I decided to share the steps I used to add third party jQuery libraries to my plugin. There may be other ways to do this, however, this is the way I found that worked for my projects. Throughout this tutorial, I will be referring to the jQuery plugin called [https://fullcalendar.io/ FullCalendar]. I use FullCalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
== Create the folder structure ==&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
== Configure the shim file ==&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== File definitions ==&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using your third party plugins in your custom java-script ==&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
== But wait! The CSS is not loaded ==&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css in php. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54586</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54586"/>
		<updated>2018-08-03T12:26:56Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Finding it hard to find good documentation, I decided to share the steps I used to add third party jQuery libraries to my plugin. There may be other ways to do this, however, this is the way I found that worked for my projects. Throughout this tutorial, I will be referring to the jQuery plugin called [https://fullcalendar.io/ FullCalendar]. I use FullCalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
== Configure the shim file ==&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== File definitions ==&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using your third party plugins in your custom java-script ==&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
== But wait! The CSS is not loaded ==&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css in php. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54585</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54585"/>
		<updated>2018-08-03T12:25:51Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Finding it hard to find good documentation, I decided to share the steps I used to add third party jQuery libraries to my plugin. There may be other ways to do this, however, this is the way I found that worked for my projects. Throughout this tutorial, I will be referring to the jQuery plugin called [https://fullcalendar.io/ FullCalendar]. I use FullCalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css in php. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54584</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54584"/>
		<updated>2018-08-03T12:25:09Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Finding it hard to find good documentation, I decided to share the steps I used to add third party jQuery libraries to my plugin. There may be other ways to do this, however, this is the way I found that worked for my projects. Throughout this tutorial, I will be referring to the jQuery plugin called [https://fullcalendar.io/ FullCalendar]. I use FullCalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css in php. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54583</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54583"/>
		<updated>2018-08-03T12:22:03Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* But wait! The CSS is not loaded */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css in php. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54582</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54582"/>
		<updated>2018-08-03T12:21:39Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* But wait! The CSS is not loaded */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css in php. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54581</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54581"/>
		<updated>2018-08-03T12:20:54Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Using your third party plugins in your custom java-script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do so, see the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54580</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54580"/>
		<updated>2018-08-03T12:19:58Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Using your third party plugins in your custom java-script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;##IMPORTANT##&#039;&#039;&#039;&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54579</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54579"/>
		<updated>2018-08-03T12:18:31Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Using your third party plugins in your custom java-script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54578</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54578"/>
		<updated>2018-08-03T12:17:14Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* File definitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,shim_export_value) {&lt;br /&gt;
      return shim_export_value;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54577</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54577"/>
		<updated>2018-08-03T12:16:03Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Configure the shim file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,&#039;shim_export_value&#039;) {&lt;br /&gt;
      return &#039;shim_export_value&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54576</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54576"/>
		<updated>2018-08-03T12:15:23Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Configure the shim file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
The final code looks like this.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,&#039;shim_export_value&#039;) {&lt;br /&gt;
      return &#039;shim_export_value&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54575</id>
		<title>Guide to adding third party jQuery for AMD</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Guide_to_adding_third_party_jQuery_for_AMD&amp;diff=54575"/>
		<updated>2018-08-03T12:12:26Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: Created page with &amp;quot;== Step by step guide to adding third party jQuery for AMD ==  Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here ar...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array. The final code looks like this.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,&#039;shim_export_value&#039;) {&lt;br /&gt;
      return &#039;shim_export_value&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54574</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54574"/>
		<updated>2018-08-03T12:06:48Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54573</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54573"/>
		<updated>2018-08-03T12:05:17Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array. The final code looks like this.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,&#039;shim_export_value&#039;) {&lt;br /&gt;
      return &#039;shim_export_value&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: While working on this plugin, I noticed that jQueryUI css was not loading, so I downloaded jQueryUI and added the css to my plugin.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/css/jquery-ui.min.css&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54572</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54572"/>
		<updated>2018-08-03T12:02:02Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array. The final code looks like this.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,&#039;shim_export_value&#039;) {&lt;br /&gt;
      return &#039;shim_export_value&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now you are ready to use the third party libraries. Here is a sample of how I used fullCalendar. Note that this is not the complete java-script file, only a small portion of the code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       $(&#039;#calendar&#039;).fullCalendar({&lt;br /&gt;
            header: {&lt;br /&gt;
                left: &#039;prev,next today&#039;,&lt;br /&gt;
                center: &#039;title&#039;,&lt;br /&gt;
                right: &#039;agendaWeek,agendaDay&#039;&lt;br /&gt;
            },&lt;br /&gt;
            businessHours: {&lt;br /&gt;
                start: opentime, // a start time (10am in this example)&lt;br /&gt;
                end: closetime, // an end time (6pm in this example)&lt;br /&gt;
            },&lt;br /&gt;
            handleWindowResize: true,&lt;br /&gt;
            contentHeight: &#039;auto&#039;,&lt;br /&gt;
            minTime: opentime + &#039;:00&#039;,&lt;br /&gt;
            maxTime: closetime + &#039;:00&#039;,&lt;br /&gt;
            slotDuration: &#039;00:10:00&#039;,&lt;br /&gt;
            slotEventOverlap: true,&lt;br /&gt;
            events: &lt;br /&gt;
                {&lt;br /&gt;
                    url: wwwroot + &#039;/local/writingcentre/events.php?servicetype=&#039; + serviceType,&lt;br /&gt;
                    type: &#039;POST&#039;,&lt;br /&gt;
                    data: function () {&lt;br /&gt;
                        var fecha = $(&#039;#calendar&#039;).fullCalendar(&#039;getDate&#039;);&lt;br /&gt;
                        return {&lt;br /&gt;
                            month: fecha.format(&amp;quot;MM&amp;quot;),&lt;br /&gt;
                            year: fecha.format(&amp;quot;YYYY&amp;quot;)&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    error: function(err) {&lt;br /&gt;
                        console.log(err);&lt;br /&gt;
                        alert(&#039;An error occured trying to retrieve the calendar events&#039;);&lt;br /&gt;
                        &lt;br /&gt;
                    }&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            weekends: false,&lt;br /&gt;
            defaultView: &#039;agendaWeek&#039;,&lt;br /&gt;
            dayClick: function (date, jsEvent, view) {&lt;br /&gt;
                var hour = date.format(&#039;HHmm&#039;);&lt;br /&gt;
                var alldaydate = date.format(&#039;YYYYMMDD&#039;);&lt;br /&gt;
                if ($(&#039;#allday-&#039; + alldaydate).val() != &#039;true&#039;) {&lt;br /&gt;
                    window.location.href = wwwroot + &amp;quot;/local/writingcentre/appointment.php?defaultdate=&amp;quot; + date.format() + &amp;quot;&amp;amp;servicetype=&amp;quot; + serviceType;&lt;br /&gt;
                } else {&lt;br /&gt;
                    alert(&#039;It is not passible to book an appointment on this day. Please select another time&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            },&lt;br /&gt;
            eventClick: function (event) {&lt;br /&gt;
                var appointment = &#039;&#039;;&lt;br /&gt;
                if (event.firstvisit) {&lt;br /&gt;
                    appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Remaining seats: &amp;quot; + event.remaining + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            &amp;quot;Registered users: &amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                            event.registeredusers;&lt;br /&gt;
&lt;br /&gt;
                    $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                    $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                        resizable: false,&lt;br /&gt;
                        width: 600,&lt;br /&gt;
                        height: &#039;auto&#039;,&lt;br /&gt;
                        modal: true,&lt;br /&gt;
                        buttons: [&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Ok&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-default&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                }&lt;br /&gt;
                            },&lt;br /&gt;
                            {&lt;br /&gt;
                                text: &amp;quot;Delete&amp;quot;,&lt;br /&gt;
                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                click: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                    $(&#039;#delete&#039;).dialog({&lt;br /&gt;
                                        resizable: false,&lt;br /&gt;
                                        height: 400,&lt;br /&gt;
                                        modal: true,&lt;br /&gt;
                                        buttons: [&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Confirm&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-danger&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    delete_event(event.id, wwwroot);&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            },&lt;br /&gt;
                                            {&lt;br /&gt;
                                                text: &amp;quot;Cancel&amp;quot;,&lt;br /&gt;
                                                class: &amp;quot;btn btn-warning&amp;quot;,&lt;br /&gt;
                                                click: function () {&lt;br /&gt;
                                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
                                                }&lt;br /&gt;
                                            }&lt;br /&gt;
                                        ]&lt;br /&gt;
&lt;br /&gt;
                                    });&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        ]&lt;br /&gt;
                    });&lt;br /&gt;
                } else if (event.event == &#039;true&#039;) {&lt;br /&gt;
                    if (event.closed == 1) {&lt;br /&gt;
                        alert(&#039;Sorry the Writing centre is closed during this time.&#039;)&lt;br /&gt;
                    } else {&lt;br /&gt;
                        appointment = event.title + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                event.start.format(&#039;YYYY-MM-DD HH:mm&#039;) + &amp;quot;&amp;lt;br&amp;gt;&amp;quot; +&lt;br /&gt;
                                &amp;quot;&amp;lt;br&amp;gt;Remaing seats: &amp;quot; + event.remaining;&lt;br /&gt;
                        $(&#039;#dialog_content&#039;).html(appointment);&lt;br /&gt;
                        $(&#039;#dialog&#039;).dialog({&lt;br /&gt;
                            resizable: false,&lt;br /&gt;
                            width: 600,&lt;br /&gt;
                            height: 300,&lt;br /&gt;
                            modal: true,&lt;br /&gt;
                            buttons: {&lt;br /&gt;
                                &amp;quot;Register&amp;quot;: function () {&lt;br /&gt;
                                    if (event.remaining == 0) {&lt;br /&gt;
                                        alert(&#039;Sorry, this is event is full&#039;);&lt;br /&gt;
                                    } else {&lt;br /&gt;
                                        $.ajax({&lt;br /&gt;
                                            url: &amp;quot;register.php?id=&amp;quot; + event.id,&lt;br /&gt;
                                            dataType: &amp;quot;text&amp;quot;,&lt;br /&gt;
                                            success: function (result) {&lt;br /&gt;
                                                alert(result);&lt;br /&gt;
                                                window.location.href = wwwroot + &amp;quot;/local/writingcentre/index.php?defaultdate=&amp;quot; + event.start.format(&#039;YYYY-MM-DD HH:mm&#039;);&lt;br /&gt;
                                            }&lt;br /&gt;
                                        });&lt;br /&gt;
                                    }&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;Close&amp;quot;: function () {&lt;br /&gt;
                                    $(this).dialog(&amp;quot;close&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                                }&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember, in order for your java-script to work, you must use grunt to compile your java-script and you must include your java-script in your templates or php files. For more information on how to do the section &amp;quot;Including an external javascript/jquery library&amp;quot; at [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&lt;br /&gt;
=== But wait! The CSS is not loaded ===&lt;br /&gt;
The above steps only load the java-script. If your third party plugin also has CSS, you must load the CSS using $PAGE-&amp;gt;requires-&amp;gt;css. Here is how I added the CSS for fullCalendar.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min.css&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54571</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54571"/>
		<updated>2018-08-03T11:50:47Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array. The final code looks like this.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,&#039;shim_export_value&#039;) {&lt;br /&gt;
      return &#039;shim_export_value&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Using your third party plugins in your custom java-script ===&lt;br /&gt;
So now that all is configured, you need to be able to use these third party plugins in your java-script files.&amp;lt;br /&amp;gt;&lt;br /&gt;
Let&#039;s start by creating a java-script file. In this case, it is the code for managing the writingcentre. So let&#039;s call the file manage.js.&amp;lt;br /&amp;gt;&lt;br /&gt;
This file must always start by defining the java-script that you require. In this case, we require jQuery, jQueryUI, moment and fullCalendar. I also add a variable wwwroot that I will use throughout the script. Note that this is not required, but it  is my preferred way of working. &amp;lt;br /&amp;gt;&lt;br /&gt;
For more information on what is required in this file, refer to [https://docs.moodle.org/dev/Javascript_Modules Javascript Modules]&amp;lt;br /&amp;gt;&lt;br /&gt;
Your file should look like the code below. &lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;, &#039;jqueryui&#039;, &#039;local_writingcentre/moment&#039;, &#039;local_writingcentre/fullcalendar&#039;], function ($, jqui, moment, fullCalendar) {&lt;br /&gt;
var wwwroot = M.cfg.wwwroot;&lt;br /&gt;
&lt;br /&gt;
    function initManage() {&lt;br /&gt;
       //Do your java-script magic here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            initManage();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54570</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54570"/>
		<updated>2018-08-03T11:35:38Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array. The final code looks like this.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;your_plugin_type_and_name&#039;/&#039;name_of_your_config_file&#039;, &#039;shim_name&#039;], function(unused,&#039;shim_export_value&#039;) {&lt;br /&gt;
      return &#039;shim_export_value&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the fullcalender.js file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;fullcalendar&#039;], function(unused,fullCalendar) {&lt;br /&gt;
      return fullCalendar;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54569</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54569"/>
		<updated>2018-08-03T11:33:06Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin called writingcentre that I developed for Moodle 2.8. I needed to upgrade the plugin for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array. The final code looks like this.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Note: You must enter the paths and shim in the order that the files must load. In this case, moment.js must load before fullcalendar.js&#039;&#039;&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=== File definitions ===&lt;br /&gt;
You must now define the third party files as AMD. For each shim in your configuration file, create a java-script file in the amd-&amp;gt;src folder. In the above case, we would create two files: moment.js and fullcalendar.js&lt;br /&gt;
Within each file, you will enter the following code.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;&#039;&#039;your_plugin_type_and_name&#039;&#039;&#039;&#039;/name_of_your_config_file&#039;&#039;&#039;, &#039;&#039;&#039;shim_name&#039;&#039;&#039;], function(unused,&#039;&#039;shim_export_value&#039;&#039;) {&lt;br /&gt;
      return &#039;&#039;shim_export_value&#039;&#039;;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here is an example of the moment file.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([&#039;local_writingcentre/config&#039;, &#039;moment&#039;], function(unused,moment) {&lt;br /&gt;
      return moment;&lt;br /&gt;
   }&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54568</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54568"/>
		<updated>2018-08-03T11:22:39Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Java-script AMD modules are best practice for inserting Java-script in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be referring to the jQuery plugin called Fullcalendar. I use Fullcalender for a local plugin that I developed for Moodle 2.8. I needed to upgrade for Moodle 3.5 and figured I should use the new AMD model to add the java-script.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Java-scripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;br /&gt;
&lt;br /&gt;
=== Configure the shim file ===&lt;br /&gt;
We need a file to configure requirejs so that the third party java-scripts can be used throughout our plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the  amd-&amp;gt;src folder create a file called config.js. Note that you can call this file what ever you want. Just remember that you will need to refer to it in later steps.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter the following code into the file&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
           //Enter the paths to your required java-script files  &lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
           //Enter the &amp;quot;names&amp;quot; that will be used to refer to your libraries&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the case of FullCalendar, there are two java-script files required for the plugin to work. Add the path to the two files within the paths array and then add the name to refer to these files in the shim array. The final code looks like this.&amp;lt;br /&amp;gt;&lt;br /&gt;
M.cfg.wwwroot is a java-script function provided by Moodle that returns the url of your site.&lt;br /&gt;
&amp;lt;code js&amp;gt;&lt;br /&gt;
define([], function () {&lt;br /&gt;
    window.requirejs.config({&lt;br /&gt;
        paths: {&lt;br /&gt;
            &amp;quot;moment&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/lib/moment.min&#039;,&lt;br /&gt;
            &amp;quot;fullcalendar&amp;quot;: M.cfg.wwwroot + &#039;/local/writingcentre/js/fullcalendar-3.9.0/fullcalendar.min&#039;,&lt;br /&gt;
        },&lt;br /&gt;
        shim: {&lt;br /&gt;
            &#039;moment&#039;: {exports: &#039;moment&#039;},&lt;br /&gt;
            &#039;fullcalendar&#039;: {exports: &#039;fullCalendar&#039;},&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54567</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54567"/>
		<updated>2018-08-03T11:04:49Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Javascript AMD modules are best practice for inserting Javascript in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be refering to the jQuery plugin called Fullcalendar. I used Fullcalender for a local plugin that I developed for Moodle 2.8. I needed to upgrade for Moodle 3.5 and figured I should use the new AMD model to add the javascript.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Javascripts&lt;br /&gt;
# Download the jQuery plugin and extract/copy it to your js folder.&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54566</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54566"/>
		<updated>2018-08-03T11:03:38Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Step by step guide to adding third party jQuery for AMD */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Javascript AMD modules are best practice for inserting Javascript in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be refering to the jQuery plugin called Fullcalendar. I used Fullcalender for a local plugin that I developed for Moodle 2.8. I needed to upgrade for Moodle 3.5 and figured I should use the new AMD model to add the javascript.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Javascripts&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:folderstructure1.png|caption]]&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=File:folderstructure1.png&amp;diff=54565</id>
		<title>File:folderstructure1.png</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=File:folderstructure1.png&amp;diff=54565"/>
		<updated>2018-08-03T11:01:14Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54564</id>
		<title>User:Patrick Thibaudeau</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Patrick_Thibaudeau&amp;diff=54564"/>
		<updated>2018-08-03T10:59:53Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: Created page with &amp;quot;== Step by step guide to adding third party jQuery for AMD ==  Since Moodle 2.9, Javascript AMD modules are best practice for inserting Javascript in Moodle plugins. Here are...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Step by step guide to adding third party jQuery for AMD ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.9, Javascript AMD modules are best practice for inserting Javascript in Moodle plugins. Here are the steps required to add third party jQuery libraries. Note that there may be other ways to do this, however, this is the way I found that worked for my projects.&lt;br /&gt;
Throughout this tutorial, I will be refering to the jQuery plugin called Fullcalendar. I used Fullcalender for a local plugin that I developed for Moodle 2.8. I needed to upgrade for Moodle 3.5 and figured I should use the new AMD model to add the javascript.&lt;br /&gt;
&lt;br /&gt;
=== Create the folder structure ===&lt;br /&gt;
Although you can use any folder structure you like, this is my preferred way of laying out my folder structure.&lt;br /&gt;
&lt;br /&gt;
# You &#039;&#039;&#039;must&#039;&#039;&#039; create an amd folder with two subfolders: src and build.&lt;br /&gt;
# Create a js folder. This folder will contain all third party jQuery/Javascripts&lt;br /&gt;
&lt;br /&gt;
The folder structure should be similar to the image below.&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38072</id>
		<title>Creating roles programmatically</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38072"/>
		<updated>2013-03-01T18:29:22Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* install.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You may find that the default roles do not answer the needs of your plugin. In that case, you want to create a role programmatically.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
We will use a plugin called myplugin.&lt;br /&gt;
&lt;br /&gt;
It is best to create capabilities for your plugin first as they will be used to create the role. You can also use default Moodle capabilities. For more information, please refer to [[Roles#Programming_Interface]]&lt;br /&gt;
===install.php===&lt;br /&gt;
The first step is to create an install.php file in the db folder of your plugin.&lt;br /&gt;
&amp;lt;pre&amp;gt;/mod/myplugin/db/install.php&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open this new file in your favorite editor and add the following function&lt;br /&gt;
&amp;lt;pre&amp;gt;defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_local_myplugin_install() {&lt;br /&gt;
    global $CFG, $DB, $OUTPUT;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to identify the context. So add the following code snippit.&lt;br /&gt;
&amp;lt;pre&amp;gt;$context = context_system::instance();&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now lets find out if the role already exists. We will also need the manager role in order to add managers to the role. This is not required, but I like to add managers so that they can assign the role to other users. Otherwise, only site administrators can add roles.&lt;br /&gt;
&amp;lt;pre&amp;gt;$manager_role = $DB-&amp;gt;get_record(&#039;role&#039;, array(&#039;shortname&#039; =&amp;gt; &#039;manager&#039;));&lt;br /&gt;
    $mwsync_superadmin_role = $DB-&amp;gt;get_record(&#039;role&#039;, array(&#039;shortname&#039; =&amp;gt; &#039;local_myplugin_admin&#039;));&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38071</id>
		<title>Creating roles programmatically</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38071"/>
		<updated>2013-03-01T18:28:47Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You may find that the default roles do not answer the needs of your plugin. In that case, you want to create a role programmatically.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
We will use a plugin called myplugin.&lt;br /&gt;
&lt;br /&gt;
It is best to create capabilities for your plugin first as they will be used to create the role. You can also use default Moodle capabilities. For more information, please refer to [[Roles#Programming_Interface]]&lt;br /&gt;
===install.php===&lt;br /&gt;
The first step is to create an install.php file in the db folder of your plugin.&lt;br /&gt;
&amp;lt;pre&amp;gt;/mod/myplugin/db/install.php&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open this new file in your favorite editor and add the following function&lt;br /&gt;
&amp;lt;pre&amp;gt;defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_local_myplugin_install() {&lt;br /&gt;
    global $CFG, $DB, $OUTPUT;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to identify the context. So add the following code snippit.&lt;br /&gt;
&amp;lt;pre&amp;gt;$context = context_system::instance();&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now lets find out if the role already exists. We will also need the manager role in order to add managers to the role. This is not required, but we like to add managers so that they can assign the role to other users. Otherwise, only site administrators can add roles.&lt;br /&gt;
&amp;lt;pre&amp;gt;$manager_role = $DB-&amp;gt;get_record(&#039;role&#039;, array(&#039;shortname&#039; =&amp;gt; &#039;manager&#039;));&lt;br /&gt;
    $mwsync_superadmin_role = $DB-&amp;gt;get_record(&#039;role&#039;, array(&#039;shortname&#039; =&amp;gt; &#039;local_myplugin_admin&#039;));&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38070</id>
		<title>Creating roles programmatically</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38070"/>
		<updated>2013-03-01T18:12:16Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: /* Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You may find that the default roles do not answer the needs of your plugin. In that case, you want to create a role programmatically.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
We will use a plugin called myplugin.&lt;br /&gt;
&lt;br /&gt;
It is best to create capabilities for your plugin first as they will be used to create the role. You can also use default Moodle capabilities. For more information, please refer to [[Roles#Programming_Interface]]&lt;br /&gt;
The first step is to create an install.php file in the db folder of your plugin.&lt;br /&gt;
&amp;lt;pre&amp;gt;/mod/myplugin/db/install.php&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38069</id>
		<title>Creating roles programmatically</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_roles_programmatically&amp;diff=38069"/>
		<updated>2013-03-01T18:05:19Z</updated>

		<summary type="html">&lt;p&gt;Patrickthibaudeau: Created page with &amp;quot;You may find that the default roles do not answer the needs of your plugin. In that case, you want to create a role programmatically.  ==Setup== The first step is to create an in...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You may find that the default roles do not answer the needs of your plugin. In that case, you want to create a role programmatically.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
The first step is to create an install.php file in the db folder of your plugin.&lt;br /&gt;
&amp;lt;pre&amp;gt;&#039;&#039;moodle root&#039;&#039;/mod/myplugin/db/install.php&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrickthibaudeau</name></author>
	</entry>
</feed>