v 1.1.3

Defining custom elements

The modoJS library is built completely modular. This allows us to always create additional elements for our needs, since every application will have some special requirements for additional user interface elements.

In many cases, this can be solved by simply passing a UI definition structure to modo.generate(), but if you find yourself in the place that you re-apply the same kind of UI definition on multiple places in your application, you might consider wrapping it into a own, custom interface element, to simplify your development process.

Wrapping parts of your interface into new modoJS user interface elements gives you the possibility of modularization and makes debugging easier. In the end, you are even able to just take pre-made user interface components and re-use them in another application.

Tools for defining a new modoJS user interface element

modoJS provides the method modo.defineElement() for this task. It enables you to inject a new object constructor into the library so it can be used anywhere by calling new modo.ElementName, or even use it inside a UI definition structure for modo.generate() by simply typing type: 'ElementName'.

A live example

So how does this work in particular? Lets create a datepicker element by fusing already present user interface elements into one new thing: the modoJS Calendar, the modoJS InputText and the modoJS PopupBubble.

So for the beginning, I'm fleshing out the new element quickly. We will naming it Datepicker, since this describes its purpose and functionality perfectly:

(function (){
    'use strict';

    //Calling defineElement and providing the element name, the used CSS classes and the constructor function.
    modo.defineElement('Datepicker', ['datepicker', 'datepicker-bubble'], function (params){
        //Every modoJS element constructor will take ONE object with constructor attributes.
        //Make sure a dummy object is created, in case the params object has been omitted when calling the constructor.
        params = params || {};

        //Every modoJS element needs at least to be based upon modo.Element.
        //This element is basically a extended text input, so we will base it on modo.InputText, instead.
        modo.InputText.call(this, params);

        //Every modoJS element has the method addClass(), which adds a CSS class and automatically
        //prefixes it with modo's CSS prefix. In our case: mdo-datepicker

        //Now we pre-create the additional elements we need for the datepicker:
        //When the user clicks on the textfield, we want to open a popup bubble with a calendar in it.
        var subUI;

        subUI = modo.generate([
                type: 'PopUpBubble',
                ref: 'bubble',
                params: {
                    className: modo.Datepicker.classNames[1]
                children: [
                        type: 'Calendar',
                        ref: 'calendar'

        var self = this;

        //Now, when the user clicks into the text-field, we want to open up the calendar.
        this.on('focus', function (){
            //Attaching the Popup Bubble to the input box
            subUI.bubble.attach(self, 'br').open();

        //And when the user clicks on a date on the calendar, feed it back into the input box.
        subUI.calendar.on('change', function (){

    //We inherit the prototype of the basic modo.Element object to enable compatibility with the
    //modoJS library.

Thats it. Our element looks like this:

Of course, our element isn't perfect like that. You might prefer opening the calendar only over a little button, next to the text input, since its not very pleaseant that the calendar opens every time the text element is just focused.

A real datepicker would also need to parse the text value, the user entered, to check if its a correct date - in whatever format is used in the users country.


Creating your own interface elements for modoJS is easy. If you need inspiration, you can always download the development version of modoJS and look through the element definitions that are already present.

comments powered by Disqus