Javascript Micro-Frameworks
fun for the DIYers

A month ago a friend showed me a toy he was building. Basically, he was trying to do angular without having to install all of angular. (This was just after angular announced 2.0 which he said "is going to be... weird.") He built it using microframeworks. That is, tiny javascript libraries and frameworks that do one thing really well in a small footprint. He told me to go look at microjs.com which is a catalog of these types of libraries. I did and I liked it.

I took a look at his code again today and thought I might try using one of these libraries to DIY routing in a simple app. I wanted to build a single page app that acted as a questionnaire/wizard. Almost a Choose-Your-Own-Adventure type application that, when finished going through the questions, provides some sort of insight or guidance to the user. My friend used RLite so I thought I'd do the same.

The idea is to store the questions as an object (so we can easily create a service that returns these questionnaires as JSON) and have the app guide the user through them. Start with a simple index.html:

<!doctype html>
<html>
<head>
    <link rel="stylesheet" href="/css/apptest.css">
    <title>JS Webapp Playground</title>
</head>

<body bc-cloak> <header> <nav> <ul> <li><a href="#/">Home</a></li> <li><a href="#/first_visit_type">first_visit_type</a></li> </ul> </nav> </header>

<main id="main">Loading...</main>

<footer> <p>Special thanks to <a href="https://github.com/bchociej/apptest/&quot;>Ben</a></p> </footer> <script src="/js/lib/lodash.min.js"></script> <script src="/js/rlite.js"></script> <script src="/js/apptest.js"></script> </body> </html>

Notice all that does is set up the structure of the page and include rlite, lodash, and a custom js file called apptest.js. Apptest.js simply sets up the rlite router based on the questions object which is called lower_back:

;
(function () {
    "use strict";

    var question = .template('<b>name:</b> <%= name %> <b>type:</b> <%= type %> <b>exits:</b> <% .forEach(exits, function(exit) { %><a href="#/<%- exit %>"><%- exit %></a><% }); %>');

    var lowerback = {
        _id: 'lower_back',
        type: 'doineedthis',
        title: 'lower back',
        description: 'total description here',
        reference: 'http://www.guideline.gov/content.aspx?id=47586&search=odg&#39;,
        questions: [
            {
                name: 'first_visit_type',
                type: 'router',
                description: 'select specialist type and initial result ',
                specialist_type: ['MD/DO', 'ORTHO', 'CHIRO', 'PAIN'],
                exits: ['first_without_radioplathy', 'first_with_radioplathy']
            },
            {
                name: 'first_without_radioplathy',
                type: 'router',
                description: 'firstwithout ',
                specialist_type: ['MD/DO', 'ORTHO', 'CHIRO', 'PAIN'],
                exits: ['end']
            },
            {
                name: 'first_with_radioplathy',
                type: 'router',
                description: 'first with ',
                specialist_type: ['MD/DO', 'ORTHO', 'CHIRO', 'PAIN'],
                exits: ['end']
            },
            {
                name: 'end',
                type: 'exit',
                description: 'Thank you ',
                exits: []
            }
        ]
    };

    var main = document.getElementById('main');
    var views = {};

    var decloak = function decloak() {
        document.body.removeAttribute('bc-cloak');
        decloak = function decloak() {
        };
    };

    var loadQuestion = function loadQuestion(n) {
        return function () {
            main.innerHTML = question(n);
            decloak();
        };
    };

    (function (r) {
        .forEach(lower_back.questions, function (n) {
            r.add(n.name, loadQuestion(n));
        });

        var update = function update() {
            var hash = location.hash || '#';
            r.run(hash.substr(1));
        };

        window.addEventListener('hashchange', update);
        update();
    })(new Rlite);

})();

The router will replace the contents of the #main div with html created by the lodash template using lower_back for data. The "exits" array tell the template which links to create at the end of the question (that way your questions can branch based on user input.)

The code doesn't do much, but it taught me that microframeworks give you a nice, low-level approach to building a javascript app. This functionality is exactly what I wanted and it only took a few lines of code. For simple projects like this, it might not make sense to lug angular or backbone along for the ride. It just makes more sense to use HTML5 and modern browsers to get the job done.