System Down Page

Self contained system down page with vanilla js options binder control and language switcher.

by Josh Carroll

HTML

<div class="message-box"> <span id="title">System Unavailable</span>
 <span id="description">The system is currently down for maintenance. We apologize for any inconvenience.</span>

    <div>
        <select id="languages"></select>
    </div>
</div>

CSS

body {
            margin: 0px;
            padding: 0px;
            font-family: Arial, Helvetica, sans-serif;
            color: #000000;
        }

.message-box {
    width: 283px;
    float: left;
    margin: 60px 0 0 60px;
    padding: 20px 40px 25px;
    box-shadow: 0px 0px 1px 1px #a8a8a8;
    border-radius: 10px;
    background: #dcdcdc;
    /* Old browsers */
    /* IE9 SVG, needs conditional override of 'filter' to 'none' */
    background: url(data:image/svg+xml;
    base64, PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RjZGNkYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUlIiBzdG9wLWNvbG9yPSIjZTBlMGUwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMjIlIiBzdG9wLWNvbG9yPSIjZmJmYmZiIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMjUlIiBzdG9wLWNvbG9yPSIjZmVmZWZmIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzMlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDclIiBzdG9wLWNvbG9yPSIjZmFmYWZhIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iODUlIiBzdG9wLWNvbG9yPSIjZGZkZmRmIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2Q5ZDlkOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
    background: -moz-linear-gradient(top, #dcdcdc 0%, #e0e0e0 5%, #fbfbfb 22%, #fefeff 25%, #ffffff 33%, #fafafa 47%, #dfdfdf 85%, #d9d9d9 100%);
    /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #dcdcdc), color-stop(5%, #e0e0e0), color-stop(22%, #fbfbfb), color-stop(25%, #fefeff), color-stop(33%, #ffffff),...

JavaScript

var Controls;
(function () {

    function createElement(name) {
        return document.createElement(name);
    }

    function createAccessor(propName) {
        return function (obj) {
            if (typeof (propName) === "undefined") {
                return obj;
            }

            return obj[propName];
        };
    }

    function isDefined(obj) {
        return typeof (obj) !== "undefined";
    }

    function isUndefined(obj) {
        return typeof (obj) === "undefined";
    }

    function isArray(obj) {
        return !isUndefined(obj) && obj.length;
    }

    function getText(elem) {
        if (isUndefined(elem)) return;
        if (isDefined(elem.textContent)) return elem.textContent;
        if (isDefined(elem.innerText)) return elem.innerText;
    }

    function setText(elem, txt) {
        if (isUndefined(elem)) return;
        if (isDefined(elem.textContent)) {
            elem.textContent = txt;
        } else if (isDefined(elem.innerText)) {
            elem.innerText = txt;
        }
    }

    var SelectControl = function (options) {
        this.settings = options || {};
        this.select = document.getElementById(this.settings.id);

        function onChange(e) {
            for (var i = 0; i < this.eventHandlers.length; i++) {
                this.eventHandlers[i].call(this, e);
            }
        }

        this.valueAccessor = createAccessor(this.settings.valueField);
        this.textAccessor = createAccessor(this.settings.textField);
        this.eventHandlers = [];

        this.select.addEventListener("change", onChange.bind(this), false);
    };

    SelectControl.prototype.addChangeHandler = function (func) {
        this.eventHandlers.push(func);
    };

    SelectControl.prototype.bindData = function (data) {
        if (!isArray(data)) return;

        this.data = data;

        this.clearOptions();

        for (var i = 0; i < data.length; i++) {
            this.addOption({
                value:...