Hi all fellow Moodle developers,
Here's a little conundrum for those who have nothing better to do during this end-of-year festive season. 😵💫
I am developing a new question type, 'guessit' which involves a few JavaScript scripts. I can get 2 functions running OK if I put them inside the same JS file. But I would like to write more then one JS file, in order to extend and debug them more easily. And I'm having problems with importing functions from one script to another. This is related to using AMD vs ES6. The Moodle dev. doc. states that new JS modules should be written ES6 syntax, not AMD. So why do my scripts require AMD syntax? Here's a simplified illustration.
Case #1 works OK
script gapsnavigation.js/** * Initialize the auto-grow input functionality. */export function init() { document.querySelectorAll('input[class*="auto-grow-input"]').forEach(function (element) { element.addEventListener("keydown", (event) => { if (event.keyCode === 32) { event.preventDefault(); // Prevent space from being entered } }); });}
---
Case #2 does not work:
script gapsnavigation.js
import { handleKeydownEvent } from './keydownHandler.js';/** * Initialize the auto-grow input functionality. */export function init() { document.querySelectorAll('input[class*="auto-grow-input"]').forEach(function (element) { handleKeydownEvent(element); }); window.console.log('Hello, world!');}
script keydownHandler.js/** * Handles the "keydown" event to prevent spaces from being entered. * @param {HTMLElement} element - The input element. */export function handleKeydownEvent(element) { element.addEventListener("keydown", (event) => { if (event.keyCode === 32) { event.preventDefault(); // Prevent space from being entered } });}
ChatGPT told me "If your environment uses RequireJS (AMD module loader) instead of ES modules, the import/export syntax will not work directly. Instead, you need to use define to define modules and require to load them." So this is what I"ve done:
Case #3 works OK
script gapsnavigation.js
define(['./keydownHandler'], function (keydownHandler) { return { init: function () { document.querySelectorAll('input[class*="auto-grow-input"]').forEach(function (element) { keydownHandler.handleKeydownEvent(element); }); } };});
script keydownHandler.js
define(function () { return { handleKeydownEvent: function (element) { element.addEventListener("keydown", (event) => { if (event.keyCode === 32) { event.preventDefault(); // Prevent space from being entered } }); } };});
OK, but... I don't understand why "my environment uses RequireJS (AMD module loader) instead of ES modules".😵💫
Explanations welcome and ... do enjoy the festive season anyway!
