This guide will walk you through creating, localizing, and building asynchronous module definition (AMD) JavaScript modules in Moodle, as well as how to pull in core Moodle services (like the notification system) from your AMD code.

1. What is AMD in Moodle?

Moodle uses RequireJS to load JavaScript modules asynchronously. An AMD module is a JavaScript file that:

  1. Declares its dependencies via a define([…], function(…) { … }) call.

  2. Exports one or more functions (often a single init entry point).

  3. Can be minified and concatenated into production-ready code.

By using AMD, modules only load when needed and avoid polluting the global namespace.

2. Folder Layout

Inside your plugin (e.g. mod/assessmentform/), you should have:

mod/assessmentform/
├── amd/
│ ├── src/ ← Your unbuilt source files
│ │ └── survey_init.js
│ └── build/ ← Moodle's build step will place minified files here
│ └── survey_init.min.js
└── view.php ← Calls your AMD module via js_call_amd()
  • amd/src/
    Place your human-readable modules here.

  • amd/build/
    After running the build, minified code will live here. Commit the build outputs so your plugin works without requiring Node on the production server.

3. Writing Your AMD Module

In amd/src/survey_init.js, you might have:

define([
'jquery',
'core/notification',
'core/str', // for translations
'survey-core',
'survey-js-ui'
], function($, notification, str, Survey) {
return {
init: function(args) {
// 1. Localization
var texts = args.str || {};
// str.get_string('key','mod_yourplugin') can also be
used.
// 2. Load and render your SurveyJS
$.getJSON(args.jsonUrl).done(function(def) {
var survey = new
Survey.Model(def);
survey.render(document.getElementById(args.containerId;
survey.onComplete.add(function(sender) {
// Build payload...
$.ajax({
url: args.postUrl,
method: 'POST',
data: JSON.stringify({ /* ... */ }),
contentType: 'application/json',
dataType: 'json',
}).done(function(response) {
notification.addNotification({
message: texts.responsesavedsuccess || 'Saved successfully!',
type: 'success'
});
// redirect ...
}).fail(function() {
notification.addNotification({
message: texts.responsefailed || 'Save failed.',
type: 'error'
});
});
});
}).fail(function() {
$('#'+args.containerId)
.html('<div class="alert alert-danger">Error loading
form.</div>');
});
}
};
});

Key points

  • define([...], function(...) { ... })
    List the module IDs you depend on. Moodle's loader will map these to the
    right files.
  • core/notification
    Exposes notification.addNotification({message, type}).

  • core/str
    Offers str.get_string(key, component) for on-the-fly translations.

  • js_call_amd() in PHP
    Pass an associative array of arguments from PHP into your JS
    entry-point.

4. Injecting Moodle Services

Just list them in your dependency array:

define([
'jquery',
'core/notification',
'core/str',
'core/ajax',
// ...your other libraries...
], function($, notification, str, Ajax) {
// You now have `notification`, `str` and `Ajax.call()`
available.
});
  • core/ajax
    Use Moodle’s AJAX wrapper:

  • Ajax.call([{
    methodname: 'mod_yourplugin_do_something',
    args: { foo: 1 }
    }])[0]
    .then(function(result){ ... })
    .catch(function(err){ notification.exception(err);
    });

5. Localization

  1. In your language file (lang/en/mod_assessmentform.php):

  • $string[‘responsesavedsuccess’] = ‘Assessment saved successfully for {$a->fullname}.’;
    $string[‘responsefailed’] = ‘Error saving assessment.’;

  1. Pass them into JS when you call your AMD module:

  • $PAGE->requires->js_call_amd(
    'mod_assessmentform/survey_init',
    'init', [
    'str' => [
    'responsesavedsuccess' =>
    get_string('responsesavedsuccess','mod_assessmentform'),
    'responsefailed' =>
    get_string('responsefailed','mod_assessmentform'),
    ],
    // ...other args...
    ]
    );
  1. In JS, access args.str.responsesavedsuccess.

6. Building (Minifying) Your AMD

Moodle provides a Grunt setup out of the box. At your plugin root:

  1. Install tools (one-time per project):

  • npm install --global grunt-cli
    npm install
  1. Build all AMD modules (including yours):

  • grunt amd
    • This reads every amd/src/*.js in all plugins, minifies them, and writes to amd/build/*.min.js.

    • You can also target just your plugin:

    grunt amd:mod_assessmentform
  1. Commit the contents of amd/build/ into your plugin’s repository.

If you prefer a standalone build, you can drop a Gruntfile.js at your plugin root that only references your AMD folder. Moodle’s core Gruntfile already handles this; there’s no extra setup needed.

7. Summary Checklist

  1. Create amd/src/yourmodule.js with a define([…], …).

  2. Load it in PHP with:

$PAGE->requires->js_call_amd('mod_yourplugin/yourmodule','init',[$args]);
  1. Use injected services:

    • core/notification → notification.addNotification(…)

    • core/str → str.get_string(…)

    • core/ajax → Ajax.call(…)

  2. Build with npm install && grunt amd and commit amd/build/*.min.js.

  3. Test on your dev site, then deploy.

With this workflow in place, you can rapidly iterate your JS in amd/src/ and then generate production-ready, minified AMD modules via Moodle’s standard Grunt toolchain.

Solin develops Moodle front-end behaviour with maintainable AMD modules, build tooling, and platform-aware debugging. Need help? Contact us.

Contact us