Improve this

Mod Components

Note: We are currently in the process of updating our docs. This document may not be complete or fully up-to-date yet. We apologize for any inconvenience.

Mod applications consist of a model layer that handles the data and a view layer that reads from the models. Components make up the view portion of a Mod application. As a rule, these components are stored in the ui directory of your Mod application (which has the benefit that you can use any Mod package and easily locate the user interface components it provides).

Mod components are encapsulated; the structure (HTML), appearance (CSS), and behavior (JavaScript) that power a user interface component are all located in the same directory, identified with a .mod suffix. For example, the foo-bar component is located in the ui directory of your Mod application at montageapp/ui/foo-bar.mod and encapsulates the following files: foo-bar.css, foo-bar.html, and foo-bar.js. Because components are self-contained, it’s easy to work on, rename, or even remove an individual component without having to find bits and pieces of it scattered across directories.

Mod components are modular; regardless of where a component is used, the same HTML, CSS, and JavaScript will control how that particular component is structured, looks, and behaves.

Note: Out of the box, Mod includes three prebuilt widget sets (or themes) for user interface components: Digit, Matte, and Native. Digit is a touch-friendly widget set optimzed for mobile device development. Matte contains desktop-optimized UI components. The Native package contains native UI components. This package lets you wrap HTML5 elements to give them access to Mod features such as data bindings and the Mod event handling model. All styling is left to the user-agent/browser or the author to apply.

Anatomy of a Component

Let’s take a closer look at some key features of the HTML, CSS, and JS files included in the FooBar component. First the HTML file.

Every component’s HTML file is a complete and valid HTML document. The head section includes the component’s CSS file and a script block, which contains all serialized Mod objects in the document.

<link rel="stylesheet" type="text/css" href="foo-bar.css">
<script type="text/montage-serialization">
{
    "owner": {
        "values": {
            "element": {"#": "foo-bar"}
        }
    }
}
</script>

For more details on the serialization format refer to Mod Serialization Format. For now, note the following:

  • The script type is set to text/montage-serialization.
  • The serialization format is JSON, with some enforced semantics.
  • "owner" is a special label in the serialization that refers to the current component. (Think of it as the equivalent of this in JavaScript.)
  • {"#": "foo-bar"} refers to the root element in the body of the HTML file, identified with the custom data-attribute data-mod-id of foo-bar:
<body>
    <div data-mod-id="foo-bar" class="FooBar">
    </div>
</body>

Note: In the object serialization JSON tree the “#” identifier refers to DOM elements (We also use the “@” identifier, which refers to template objects or other components defined in the object serialization).

This means that when you use a FooBar component in a Mod application the only portion of its template that will be rendered is the foo-bar element.

Note: Mod components are reusable, that is, you can insert them multiple times in the same document, which is why we use a custom data-attribute, data-mod-id, to identify elements and not the document-unique HTML id attribute. This also gives you the freedom to use the id attribute for styling, whether for performance or legacy reasons.

Next, the CSS file: By default, we start off with an almost blank style sheet, waiting for you to bring it to life by adding your meticulously crafted rules. The only content we pass along is the class name of the root element.

.FooBar {

}

Note also that the class name is a CamelCase version of the .mod directory name. This is part of our internal CSS naming convention; it allows us to scope each component’s CSS so that it doesn’t “leak out” and accidentally style other components.

Finally, the JS file:

exports.FooBar = Component.specialize(/** @lends FooBar# */ {
   constructor: {
       value: function FooBar() {
           this.super();
       }
   }
});

The file exports a single object with a CamelCase version of the .mod directory name which inherits Mod methods from Component. The first argument provides a way to define the properties (methods and values) that will be available on the instances of the new type being created. The second argument provides a way to define properties of the type itself, they are accessible directly on the type (e.g., Component.method()).

this.super() is a special function that will call the parent method with the same name. in this case it will call the constructor function that was defined in the Component type. This is useful to extend a behavior and is similar to its Java counterpart.

When in use, the FooBar component will be rendered in a document using its element from its included template, styled using its included CSS, and given instructions on how to act from its included JavaScript.

comments powered by Disqus