4.5. Intro to Doon and Acquire

For the admin, Cradle relies on two main JavaScript libraries Doon and Acquire. While it’s not required to use these in your front end, it’s still important to be aware of their existence.

4.5.1. Doon (Do On)

Doon is a super light weight event driven container. Since most of the Schema Fields are using by Doon Interfaces, we should basically understand the basic premise in case we would want to use the exact same fields in the front end.

The following is a basic Doon implementation

<div data-do="trigger" data-on="click|mouseover|mouseout"></div>

The reason it is called Doon is because there are two things typically required data-do and data-on. The following JavaScript can be used to bind functionality to the above HTML.

$(window).on('trigger-init', function(e, target) {
  $(target).html('Click Me');
}).on('trigger-click', function(e, target) {
  $(target).css('color', 'red');
}).on('trigger-mouseout', function(e, target) {
  $(target).css('color', 'blue');
  $(target).css('font-size', '12px');
}).on('trigger-mouseover', function(e, target) {
  $(target).css('font-size', '20px');
});

$('div').doon()

With Doon there is an obvious pattern change when we code the JavaScript which is we don’t specify the selector to listen to. This is nice if ever we need to change the HTML, we don’t need to change the JavaScript.

Now the Doon Library is not written to be complicated (in fact, the source code is only 44 lines). /public/scripts/www.js has a predefined list of Doon Interfaces that you can use on the Front End (also /public/styles/www.css has the interface styles).

Now a lot of these Doon Interfaces uses third party libraries and wrap it as a Doon because it introduces consistency between libraries. For example in /public/scripts/www.js we can describe the Mask Field as the following.

$(window).on('mask-field-init', function(e, target) {
    $.require(
        'components/inputmask/dist/min/jquery.inputmask.bundle.min.js',
        function() {
            var format = $(target).attr('data-format');
            $(target).inputmask(format);
        }
    );
});

The code above includes the third party library when it needs it using $.require().

4.5.2. Acquire

The $.require() is an alias for the Acquire Library which is a lightweight AMD require() script and file loader with caching.

Usage
require('/application/bar.js');

Pre-Loader

Set up a preloader so you can use it like require in Node JS.

require.load(
    '/application/bar.js',
    '/application/template.html',
    '/application/circle2.js',  
    '/application/circle1.js');

You can also directly define the paths as in:

require.load({
    '/application/bar.js': function() {
        return 'foo';
    },
    '/application/template.html': '<h1>Yay</h1>',
    '/application/circle2.js': function() {
        console.log('circle-2');
    },  
    '/application/circle1.js': 'eval;require('%2Fapplication%2Fcircle2.js')()%3Bmodule.exports%20%3D%20function()%20%7B%09console.log('circle-1')%3B%7D'});

This is the recommended way when you are ready to bundle and minify your code for production use. As you can see /application/circle1.js is compiled different than the others. This is because there is some other code outside of the module.exports. If you have this same case wrap your entire file using encodeURIComponent. Acquire will evaluate strings that start with eval; following the encoded code.

If you need to wait for the pre loaders you can include a callback at the end of the load method as in:

require.load(
    '/application/bar.js',
    '/application/template.html',
    '/application/circle2.js',  
    '/application/circle1.js',
    function(bar, template, circle2, circle1) {
        require('/test.js');
    });
Path Configuration
require.config({
    application: {
        root: '/application',
        index: 'foobar'
    },
    foobar: '/foobar'
});

require('application/bar'); // will now be the same as require('/application/bar.js')
require('application/bar/'); // will now be the same as require('/application/bar/foobar.js')
require('foobar/bar'); // will now be the same as require('/foobar/bar.js')
require('foobar/bar/'); // will now be the same as require('/foobar/bar/index.js')
Warning: Relative paths like require('application/bar') with no config will default to require('/node_modules/application/bar.js')