Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

jQuery: Difference between revisions

From MoodleDocs
No edit summary
No edit summary
(19 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Moodle 2.5}}


[[YUI]] is the recommended library for development of Moodle plugins or customisations. However due to significant demand it will be possible to use also jQuery in Moodle add-ons.
{{Moodle 2.9}}


Before Moodle 2.9 we used [[YUI]] to write javascript in Moodle. As of Moodle 2.9 we are transitioning to jQuery and [[Javascript Modules]] because Yahoo has ceased all new development on YUI (http://yahooeng.tumblr.com/post/96098168666/important-announcement-regarding-yui). 


==Examples==
This page explains the recommended way to use jQuery in core and plugins, although other [[jQuery pre2.9|older]] methods of including jQuery will still work.


===Basic jQuery in add-on theme===
== Why do we need JQuery? ==
JQuery is useful for handling browser inconsistencies, and for utility functions that would otherwise be duplicated all over the code. Some particular things that JQuery is good at are:
* DOM Manipulations
* Promises ($.Deferred)
* Ajax


# create /theme/sometheme/lib.php file if it does not exist yet
== How to use JQuery ==
# add new function theme_sometheme_page_init to the lib.php file (replace 'sometheme' with real name of your theme)
As of Moodle 2.9, the recommended way to write javascript is in AMD Modules. For more information on writing AMD modules in Moodle see [[ Javascript Modules ]].
# use jQuery JavaScript in theme layout files


<code php>
JQuery has been added as an AMD Module and is available to all AMD javascript.  
<?php
// file: /theme/sometheme/lib.php
function theme_sometheme_page_init(moodle_page $page) {
    $page->requires->jquery();
}
</code>
 
<code html4strict>
// near the end of file: /theme/sometheme/layout/general.php
<script>
  $('.headermain').mouseover(function() {
    alert('yoopee');
  });
</script>
</code>


===jQuery UI in add-on activity module===
To make use of JQuery, either list it as a dependency of your module, or use a require call to load it.
# optionally add more jQuery plugins (not recommended because the same plugins in different add-ons may collide)
# add necessary $PAGE->requires
# use jQuery


<code php>
=== As a dependency of a module ===
 
<code>
<?php
    define(['jquery'], function($) {
require('../../config.php');
        // Private functions.
 
        var privateFunc = function(a) {
// ... normal PAGE setup and access control
            // JQuery is available via $ if I want it
 
            return a + 1;
$PAGE->requires->jquery();
        };
$PAGE->requires->jquery_plugin('ui');
      
$PAGE->requires->jquery_plugin('ui-css');
        // Public functions.
 
        return {
echo $OUTPUT->header();
            publicFunc: function(b) {
?>
                // JQuery is available via $ if I want it
     <button>A button element</button>
                return privateFunc(b) + 1;
 
            }
<div id="dialog" title="Basic dialog">
         }
  <p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
     });
</div>
    <script>
        $(function() {
            $( "#dialog" ).dialog();
         });
     </script>
<?php
echo $OUTPUT->footer();
</code>
</code>


===jQuery UI in add-on block===
=== With a require call ===
# add necessary requires in get_required_javascript() method in your block, do not forget to call it in parent too
<code>
# use jQuery in blok html output
     require(['jquery'], function($) {
 
         // JQuery is available via $
<code php>
 
 
class block_html extends block_base {
 
     function get_required_javascript() {
        parent::get_required_javascript();
 
        $this->page->requires->jquery();
        $this->page->requires->jquery_plugin('ui');
        $this->page->requires->jquery_plugin('ui-css');
    }
 
    function get_content() {
 
         // ....
 
        $this->content->text .= '
<div id="progressbar"></div>
<script>
  $(function() {
    $( "#progressbar" ).progressbar({
      value: 37
     });
     });
  });
    // JQuery is not in scope and cannot be used.
</script>';
 
 
        // ....
    }
</code>
</code>


=== Including your own plugins ===
== What about JQuery UI ? ==
'''Note:''' Your plugin your have a filename which includes its version number. This is the same as in the core jQuery project. This enables you to increment the version of your plugin when you make changes to it.
JQuery UI is a separate project containing a library of reusable widgets that relies on JQuery. JQuery UI is available for plugins to use, but it should not be used in core code.  


# Place your jQuery plugin into mod/yourplugin/jquery/jquerymodule/
The problems with JQuery UI are:
# Add the plugin information to the plugins.php file
* It uses an entirely different themeing system for CSS that does not work well with Moodle themes
# Use the plugin in your code
* It introduces CSS conflicts with bootstrap
* The widgets have some accessibility features - but only if used in a very specific way which is not well documented


==== Add the plugin information to the plugins.php file ====
Over time we will build up a library of widgets in core either by wrapping a suitable library or implementing from scratch.
<code php>
// file: mod/yourplugin/jquery/plugins.php
$plugins = array(
    'yourplugin-jquerymodule' => array(
        'files' => array(
            'jquerymodule/jquery-somefilename-1.0.1.min.js',
        ),
    ),
);
</code>


==== Use the plugin in your code ====
If you STILL want to use JQuery UI in your plugin, it is available as an AMD module named 'jqueryui'.
<code php>
<?php
// file: /mod/yourplugin/lib.php
// ... rest of file ...
$PAGE->requires->jquery_plugin('yourplugin-jquerymodule', 'mod_yourplugin');
</code>


===Overriding base jQuery UI theme===
<code>
# download new jQuery UI theme and extract it into theme/sometheme/jquery/custom-1.0
     require(['jquery', 'jqueryui'], function($, jqui) {
# define new jQuery theme ui css plugin in theme/sometheme/jquery/plugins.php
        // JQuery is available via $
# overrider core 'ui-css' with 'yourtheme-ui-css'
        // JQuery UI is available via $.ui
 
     });
<code php>
    // JQuery is not in scope and cannot be used.
<?php
    // JQuery UI is not in scope and cannot be used.
// file: theme/sometheme/jquery/plugins.php
$plugins = array(
     'sometheme-ui-css' => array('files' => array('custom-1.0/jquery-ui-1.10.2.custom.min.css')),
);
</code>
 
<code php>
<?php
// file: /theme/sometheme/lib.php
function theme_sometheme_page_init(moodle_page $page) {
    // There is no need to $page->requires->jquery() if the theme does not use jQuery.
    $page->requires->jquery_plugin('sometheme-ui-css', 'theme_sometheme');
     $page->requires->jquery_override_plugin('ui-css', 'sometheme-ui-css');
}
</code>
 
===Backwards compatibility for scripts written for legacy jQuery versions===
 
See [https://github.com/jquery/jquery-migrate/ jQuery Migrate plugin]
 
<code php>
$PAGE->requires->jquery();
$PAGE->requires->jquery_plugin('migrate');
 
// Incompatible code designed for 1.8.x jQuery should work now...
</code>
</code>


===mymobile theme===
{{Moodle 3.2}}
 
In Moodle 3.2 we upgraded jQuery to 3.1 and removed the jQuery migrate plugin. You should not have to change your code unless you have been ignoring jQuery deprecation notices for many many years (but it's recommended to test it in 3.2).
See mymobile theme for more examples including custom jQuery plugin and integration with jQuery Mobile.
 
==More information==
 
===Bundled plugins===
 
Official Moodle distribution contains jQuery, jQuery UI and jQuery Migrate plugins.
 
===jQuery plugin collisions===
 
The loading order of plugins is defined by order of $PAGE->requires. If there are plugins with the same name the first $PAGE->require wins.
 
It is recommended to use plugin overrides only in themes because multiple overrides of the same plugin result in undefined behaviour. In general themes should have more freedom to add extra jQuery plugins, other Moodle plugins should ideally use only basic jQuery or jQuery UI.
 
===jQuery plugin modifications===
 
Files in jQuery plugins MUST NOT be changed, always create a new file with different name and update CSS and plugins.php if necessary and delete the old file.
 
===jQuery versions===
 
Only minor jQuery version updates can be done in STABLE branches. Add-on developers must revalidate compatibility after every major upgrade. Use official 'migrate' plugin if necessary, see example above.
 
==Frequently asked questions==
 
; Can I serve jQuery from CDN? : No, because CDNs do not include all plugins and some do not support https. Use proxy caching such as Cloudflare instead.
 
; I edited some file but the change is ignored, why? : Moodle and your browser caches Javascript, to circumvent this rename your Javascript file as shown [https://docs.moodle.org/dev/jQuery#Including_your_own_plugins here]. Additionally you can use the developer console on [https://developer.chrome.com/devtools/docs/settings Chrome] or [https://developer.mozilla.org/en-US/docs/Tools/Tools_Toolbox Firefox] to disable caching for Javascript.
 
See above, files MUST NOT be updated in jQuery plugins, always create new files or directories. Moodle cache purging does not have any effect on jQuery plugins.
 
; Can we remove YUI now? : No! YUI is the only recommended JS library in Moodle add-ons and core.
 
; Can I use different jQuery version? : No. (Theoretically you might try jQuery plugin override to include some later minor revision.)
 
; Could we have jQuery plugin dependencies? : No, order your $PAGE->requires manually.
 
; Are there any performance costs when using jQuery? : Yes. Please consider using SimpleYUI for simple DOM manipulations or standard YUI widgets.
 
; Can I use YUI loader to include jQuery? : No. Moodle jQuery support is not compatible with sandboxing.
 
; Moodle complains when I disable slasharguments setting, why? : Please fix your server to be compatible with slasharguments, even IIS can support it now!
 
; Why is jQuery UI split into two plugins? : This allows Moodle themes to override the jQuery UI CSS and images.


==See also==
==See also==
* [[Javascript Modules]]
* [[Useful core Javascript modules]]
* [[jQuery pre2.9]]
* [http://jquery.com jQuery]
* [http://jquery.com jQuery]
* [http://jqueryui.com jQuery User Interface]
* [http://jqueryui.com jQuery User Interface]


[[Category:Javascript]]
[[Category:Javascript]]

Revision as of 11:49, 19 May 2017

Moodle 2.9


Before Moodle 2.9 we used YUI to write javascript in Moodle. As of Moodle 2.9 we are transitioning to jQuery and Javascript Modules because Yahoo has ceased all new development on YUI (http://yahooeng.tumblr.com/post/96098168666/important-announcement-regarding-yui).

This page explains the recommended way to use jQuery in core and plugins, although other older methods of including jQuery will still work.

Why do we need JQuery?

JQuery is useful for handling browser inconsistencies, and for utility functions that would otherwise be duplicated all over the code. Some particular things that JQuery is good at are:

  • DOM Manipulations
  • Promises ($.Deferred)
  • Ajax

How to use JQuery

As of Moodle 2.9, the recommended way to write javascript is in AMD Modules. For more information on writing AMD modules in Moodle see Javascript Modules .

JQuery has been added as an AMD Module and is available to all AMD javascript.

To make use of JQuery, either list it as a dependency of your module, or use a require call to load it.

As a dependency of a module

   define(['jquery'], function($) {
       // Private functions.
       var privateFunc = function(a) {
           // JQuery is available via $ if I want it
           return a + 1;
       };
   
       // Public functions.
       return {
           publicFunc: function(b) {
               // JQuery is available via $ if I want it
               return privateFunc(b) + 1;
           }
       }
   });

With a require call

   require(['jquery'], function($) {
       // JQuery is available via $
   });
   // JQuery is not in scope and cannot be used.

What about JQuery UI ?

JQuery UI is a separate project containing a library of reusable widgets that relies on JQuery. JQuery UI is available for plugins to use, but it should not be used in core code.

The problems with JQuery UI are:

  • It uses an entirely different themeing system for CSS that does not work well with Moodle themes
  • It introduces CSS conflicts with bootstrap
  • The widgets have some accessibility features - but only if used in a very specific way which is not well documented

Over time we will build up a library of widgets in core either by wrapping a suitable library or implementing from scratch.

If you STILL want to use JQuery UI in your plugin, it is available as an AMD module named 'jqueryui'.

   require(['jquery', 'jqueryui'], function($, jqui) {
       // JQuery is available via $
       // JQuery UI is available via $.ui
   });
   // JQuery is not in scope and cannot be used.
   // JQuery UI is not in scope and cannot be used.

Moodle 3.2

In Moodle 3.2 we upgraded jQuery to 3.1 and removed the jQuery migrate plugin. You should not have to change your code unless you have been ignoring jQuery deprecation notices for many many years (but it's recommended to test it in 3.2).

See also