Modal registry

As of Totara 12 (Evergreen TBC), there has been the inheritance of a modal registry library. This can allow for additional modal types to use the basic Modal templates.

To create a new Modal type, both a mustache template file and a JavaScript AMD module need to be created.

Template file

This needs to reference the template core/modal and have the following variables set:

  • title: This should be relatively short and is the heading for the modal.
  • body: The main content of the modal.
  • footer: The footer for the modal. This should contain any action buttons required.

An example mustache template can be found below:

modal_registry_template.mustache
{{< core/modal }}
    {{$title}} Title text {{/title}}
    {{$body}}
		Body content
    {{/body}}
    {{$footer}}
		Footer content - this should contain your action buttons
    {{/footer}}
{{/ core/modal }}

AMD module

The AMD module needs core/modal and core/modal_registry. To add event listeners, the library core/custom_interaction_events must also be included. As the modal library uses jQuery extensively it may also be beneficial to include it.

The object returned from the AMD module needs to have all the functionality of core/modal (it would make sense to inherit it) with Type specified (mod_module-type recommended), and it must be registered with the modal registry (using ModalRegistry.register(modal.TYPE, template) ). Any events that the modal requires needs to listen to (e.g. from buttons in the footer) will need to be placed in a "registerEventListeners" function (on the activate event provided by core/custom_interaction_events).

An example of AMD module is below

modal_registry.js
define(['core/custom_interaction_events', 'core/modal', 'core/modal_registry'],
        function(CustomEvents, Modal, ModalRegistry) {
 
    var registered = false;
    var SELECTORS = {
        OK_BUTTON: '[data-action="ok"]',
        CANCEL_BUTTON: '[data-action="cancel"]',
    };
 
    /**
     * Constructor for the Modal.
     *
     * @param {object} root The root jQuery element for the modal
     */
    var NewModal = function(root) {
        Modal.call(this, root);
     };
 
    NewModal.TYPE = 'your_module-type';
    NewModal.prototype = Object.create(Modal.prototype);
    NewModal.prototype.constructor = NewModal;
 
    /**
     * Set up all of the event handling for the modal.
     *
     * @method registerEventListeners
     */
    NewModal.prototype.registerEventListeners = function() {
        // Apply parent event listeners.
        Modal.prototype.registerEventListeners.call(this);
 
        this.getModal().on(CustomEvents.events.activate, SELECTORS.OK_BUTTON, function(e, data) {
            // Code to handle the OK button (probably should include hiding the modal and the like
        }.bind(this));
 
        this.getModal().on(CustomEvents.events.activate, SELECTORS.CANCEL_BUTTON, function(e, data) {
            // Code to handle the cancel 
        }.bind(this));
    };
 
    // Automatically register with the modal registry the first time this module is imported so that you can create modals
    // of this type using the modal factory.
    if (!registered) {
        ModalRegistry.register(NewModal.TYPE, NewModal, '<your_module>/<template>');
        registered = true;
    }
 
    return NewModal;
});

Using a modal

Once a modal type has been registered with the modal registry, it can be used through the modal factory using the type that was defined e.g.:

calling.js
define(['jquery', 'core/modal_factory', '<AMD module containing your new modal>'], function($, ModalFactory, Modal) {
	var trigger = $('#triggerelement');


	ModalFactory.create({type: Modal.TYPE}, trigger);
});