Meteo

by gnemeth

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.10/semantic.min.css">
<div class="ui container">
    <div class="ui form">
        <div class="inline fields">
            <div class="eight wide field">
                <label>Message Types:</label>
                <div class="ui checkbox">
                    <input id="metar" type="checkbox" name="metar" class="reportTypes hidden">
                    <label for="metar" class="mr-10">METAR</label>
                </div>
                <div class="ui checkbox">
                    <input id="sigmet" type="checkbox" name="sigmet" class="reportTypes hidden">
                    <label for="sigmet" class="mr-10">SIGMET</label>
                </div>
                <div class="ui checkbox">
                    <input id="taf" type="checkbox" name="taf" class="reportTypes hidden">
                    <label for="taf" class="mr-10">TAF</label>
                </div>
            </div>
        </div>
        <div class="inline fields">
            <div class="eight wide field">
                <label>Airports:</label>
                <input id="icao" type="text" placeholder="Airports">
            </div>
        </div>
        <div class="inline fields">
            <div class="eight wide field">
                <label>Countries:</label>
                <input id="wmo" type="text" placeholder="Countries">
            </div>
        </div>
        <div class="inline fields">
            <div class="eight wide field btn-field">
                <button id="submit-btn" class="ui button primary disabled">Create Briefing</button>
            </div>
        </div>
    </div>

    <div id="msg-holder" class="ui centered grid">
        <div class="columns">
            <div class="left aligned text eight wide column">
                <div id="msg-type" class="ui message">
                    <div id="msg-header" class="header"></div>
                    <div id="msg-body"></div>
             ...

CSS

body {
    padding: 20px 10px;
}

#table-holder,
#error-holder {
    margin: 10px 0;
}

.mr-10 {
    margin-right: 10px;
}

.mt-10 {
    margin-top: 10px;
}

.field > label {
    min-width: 100px;
}

.btn-field {
    justify-content: flex-end;
}

.ui.form .inline.fields {
    justify-content: center;
}

.left.aligned.text {
    text-align: left;
}

.ui.grid {
    margin: initial;
}

.ui.grid>* {
    padding: 0;
}

table .head {
    background-color: rgba(0, 0, 50, .02);
}

.blue {
    color: #0E6EB8;
}

.red {
    color: #B03060;
}

.bold {
    font-weight: bold;
}

#msg-holder {
    display: none;
}

@media only screen and (max-width: 400px) {
    .ui.form .inline.fields .wide.field {
        flex-direction: column;
        align-items: baseline;
    }
    .inline.fields .ui.checkbox {
        margin: 5px 0;
    }
}

JavaScript

let IBL = (function() {
    // Keeping central set of constants
    const REQ_URL = 'https://ogcie.iblsoft.com/ria/opmetquery';
    const REQ_TYPE = 'POST';
    const ERROR_HEAD = '<i class="warning sign icon"></i>';
    const WARN_HEAD = '<i class="info circle icon"></i>';
    const ICAO = 'icao';
    const WMO = 'wmo';
    const ERROR = 'error';
    const WARNING = 'warning';
    const ERROR_MSG_WRONG_INPUT = 'Check Airport and Country fields for typo.';
    const ERROR_MSG_SOMETHING_WENT_WRONG = 'Something went wrong. Try again later.';
    const WARN_MSG_NO_DATA_TO_SHOW = 'There is no data to show. Try again later or check for typo.';

    const CSS_CLASS_HIDDEN = 'hidden-content';
    const CSS_CLASS_DISABLED = 'disabled';
    const CSS_CLASS_LOADING = 'loading';
    const CSS_CLASS_WARNING_MSG = 'warning';
    const CSS_CLASS_ERROR_MSG = 'negative';

    const $submitBtn = $('#submit-btn');
    const $tableHolder = $('#table-holder');
    const $checkboxes = $('input:checkbox');
    const $icaoInput = $('#icao');
    const $wmoInput = $('#wmo');
    const $msgHolder = $('#msg-holder');
    const $msgType = $('#msg-type');
    const $msgHeader = $('#msg-header');
    const $msgBody = $('#msg-body');

    // Global method for grouping data by specific property
    Array.prototype.groupDataBy = function(prop) {
        return this.reduce(function(groups, item) {
            let val = item[prop];
            groups[val] = groups[val] || [];
            groups[val].push(item);
            return groups;
        }, {});
    }

    // Methods for getting data from DOM
    let getDataFromDOM = {
        getCheckedBoxes: function(chkboxClass) {
            return $('.' + chkboxClass + ':checkbox:checked');
        },
        getDataFromInput: function(input) {
            let $choosenInput = null;
            let inputValue = '';

            if (input === 'icao') {
                $choosenInput = $icaoInput;
            } else if (input === 'wmo') {
               ...