Modules With Mura.js - Mura Docs v7.1

Modules With Mura.js

As introduced in the Anatomy of a Module section, developers may choose to render their modules using purely JavaScript. When doing so, the module's index.cfm file should only contain the following line of code, which informs Mura it has nothing to render via server-side processing, and all rendering will occur via the "client" or browser.

<cfset objectparams.render="client">

Then, in order to load your script(s), you'll need to use a custom event handler, and register the onRenderStart event to dynamically load your script file(s), as illustrated below.

// ../yourmodule/model/handlers/yourhandler.cfc

component extends='mura.cfobject' {

  function onRenderStart(m) {
    // if script should be included in the <head>
    arguments.m.addToHTMLHeadQueue('<script src="/path/to/script.js"></script>');

    // OR

    // if script should be included before closing </body> tag
    arguments.m.addToHTMLFootQueue('<script src="/path/to/script.js"></script>');
  }

}

By using addToHTMLHeadQueue and/or addToHTMLFootQueue, your scripts will only be loaded once, regardless of how many times your module has been applied to the layout.

The Custom JavaScript File

Assuming you've followed the instructions above to get your custom script file included into either the "head" portion of your theme, or before the closing "body" tag, you will most likely want to control when your script(s) are executed. However, you may also simply allow your scripts to run at all times.

Running Scripts on Every Request

If you merely wish for your script(s) to execute, regardless of whether or not your module has been applied to the layout, then you may simply include any JavaScript you wish. In other words, since your script files are being added on every request via your custom event handler's onRenderStart method, your scripts will automatically execute. This is useful for merely adding a utility script, such as a tracking script, etc.

The content of your script file may look as simple as the following example.

// your-script.js
console.log('Hello from your module!');

Running Scripts Only If Your Module Has Been Applied

Unless your scripts are utilities, such as tracking scripts, developers will most often wish their scripts to execute only when the module has been applied to the layout. In addition, when the module includes a configurator, each instance of the module will have access to its own configuration information.

First, it's important to understand that modules rendered via the client, are automatically registered to Mura's namespace under Mura.Module.YourModuleDirectoryName. Also, Mura will automatically invoke a "render" method via Mura.UI, on each request. By defining your own "render" method, you're able to pretty much do whatever you want.

The example below illustrates a skeleton script. You should substitute "yourModuleDirectoryName" with the actual directory name of your display object.

// your-script.js
Mura.Module.YourModuleDirectoryName = Mura.UI.extend({
  render: function() {
    // Your code goes here ...
    return this;
  }
});

this.context

When using JavaScript to render a Mura "Module" via the client, developers are most interested in two (2) primary pieces of information:

  1. How to target the container element of where the module has been applied to the layout.
  2. How to access "objectparams", or the data collected via a configurator.

You can easily access either of these by using "this.context" in your custom script.

  • this.context.targetEl
    • Use this to target the container element of where the module has been applied to the layout. Keep in mind, each instance of the module in the layout will have its own, unique container element.
  • this.context.{yourObjectParam}
    • Use this to access any "objectparams", or data collected via a configurator. Each instance of the module will have access to its own, unique configuration data.

The example below illustrates how to use the above information, and may be used as a starter file in your own projects.

// your-script.js
Mura.Module.YourModuleDirectoryName = Mura.UI.extend({

  render: function() {
    // reference to the container element
    this.container = Mura(this.context.targetEl);
    
    // assuming you have an objectparam named 'mytext'
    var txt = this.context.mytext || 'mytext is empty';

    // Having fun by replacing the content of the container
    // Remember, using Mura.js, we can do jQuery-esque DOM manipulation
    this.container.html('<h3>Hello from yourDisplayObject</h3>');
    this.container.append('<h4>' + txt + '</h4>');

    // The rest of your code goes here ...
    return this;
  }

});

If you're interested in seeing what else is available via Mura.UI, feel free to review the code found at https://github.com/blueriver/MuraJS/blob/master/src/core/ui.js.

To see an example of how to use Mura.js along with Mura ORM, Grunt, and Handlebars, visit https://github.com/stevewithington/muracontacts/tree/js.