Skip to content
Snippets Groups Projects
Forked from MetObs / MetObsSite
50 commits behind, 2 commits ahead of the upstream repository.
form_util.js 9.19 KiB
const site_template = '<div class="form-group"><label>{site}</label></div>'
const inst_select_template = '<select multiple id="{site}_select" style="height:4em;" class="inst_select form-control"></select>'
const MOST_RECENT_VERSION = '<option value="*" selected>Most Recent</option>';
const head_string = '&nbsp;&nbsp;&nbsp;&nbsp;';
const date_re = /^(19[7-9][0-9]|2[0-9]{3})-(0[0-9]|1[0-2])-([012][0-9]|3[01])$/;
const time_re = /^([01][0-9]|2[0-3])(:[0-5][0-9]){0,2}$/;


/* Creates a string for an option html element with value key and innerHTML object.display_name
 * if level is specified, append level to the value string
 */
function makeOption(value, innerHTML, name, tooltip) {
    if (tooltip === undefined) {
        return '<option value="' + value + '" name="' + name + '">' + innerHTML + '</option>';
    } else {
        return '<option value="' + value + '" name="' + name + '"title="' + tooltip + '">' + innerHTML + '</option>';
    }
}

/**
 * Create HTML 'option' for a section header.
 *
 * For example, a 'Tower' option that will select all child options.
 * @param {string} name - HTML text to place inside the option
 * @param {string} subheading
 */
function makeHeaderOption(name, innerHTML) {
    if (innerHTML === undefined) {
        innerHTML = name;
    }
    return makeOption(name + ' header', innerHTML,'header');
}

/* Function to be bound to <options> so that 
 * clicking or ctrl-cliking on it will deselect its "parent" option
 * eg:
 * * AERI               AERI
 *   *level_00   ctrl   *level_00
 *   *level_01   --->    level_01
 *   *level_02          *level_02
 */
function option_toggle_header_on_click() {
    var level = $(this).val();
    // if this is a "header" section then this will be "header"
    // see 'makeHeaderOption' for more information
    // if this is a normal row option then this will be "Tower" or "AERI"
    var header_string = level.split(' ').slice(-1);
    if (header_string != 'header') {
        var parent_form = $(this).closest('select');
        // all currently selected options including the parent headers
        var curr_options = new Set(parent_form.val());
        // if we are deselecting a specific row and the header
        // row is currently selected, then remove deselect the header row
        // NOTE: selecting all sub-rows does not select the header row
        if (curr_options.has(header_string + ' header')) {
            curr_options.delete(header_string + ' header');
            curr_options.delete(level);
        }
        parent_form.val(Array.from(curr_options));
    }
}

/* Function to be bound to a form so that
 * clicking on a header will select all its sub-options
 * eg:
 * AERI        --->  *AERI
 *  level_00          *level_00
 *  leve1_01          *level_01 
 *  level_02          *level_02
 */
var select_options_by_header = function(form, then_do) {
        var curr_options = new Set();
        _.each($(form).val(),function(level){
            var header_string = level.split(' ')[1];
            var level_string = level.split(' ')[0];
            if (header_string == 'header') {
                // if a header is clicked, add it and all its children to the list
                curr_options.add(level);
                $(form).children('[name='+level_string+']').each(function(){
                    curr_options.add($(this).val());
                });
            } else {
                //otherwise, add just the selected option
                curr_options.add(level);
            }
        });
        $(form).val(Array.from(curr_options));
        if(then_do) then_do();
        return $(form).val();
};
/* Function to be bound to a form so that
 * de-clicking on a header will deselect all its sub-options
 * eg:
 *  *AERI        --->  AERI
 *   *level_00          level_00
 *   *leve1_01          level_01 
 *   *level_02          level_02
 */
var bind_deselect_options_by_header = function(form){
    $(form+'>[name=header]').click(function(){
        var header = $(this);
        if($(form).val() == undefined) return;
        if($(form).val().indexOf(header.val()) == -1){
            var curr_options = $(form).val();
            curr_options = _.reject(curr_options,function(option){
                return option.indexOf(header.val().split(' ')[0]) != -1;
            });
            $(form).val(curr_options);
            $(form).trigger('change');
        }
    });
};
/*
 * Returns the value of a jquery object if it has one, or its placeholder if it doesn't
 */
var val_or_place = function(jquery_str){
    return ($(jquery_str).val() != '')? $(jquery_str).val() : $(jquery_str).attr('placeholder');
};

/*
 * Returns a string in the form &begin=YYYY-MM-DDTHH:MM:SS&end=YYYY-MM-DDTHH:MM:SS
 * based on the values in the date range form if possible, otherwise returns false
 */
var make_date_range_query= function(){
    //append zeros to the end of partial time strings
    //eg '23' -> 23:00:00
    var add_zeros = function(time_str){
        while(time_str.length < 8) time_str += ':00'; 
        return time_str
    };
    if($('#Start-date-picker').val() && $('#End-date-picker').val()){
        var start = $('#Start-date-picker').val().split(' ').join('T')+':00';
        var end = $('#End-date-picker').val().split(' ').join('T')+':00';
      
        var query_str = '&begin='+start + '&end='+end;
        return query_str;
    } else {
        return false;
    }
};

function get_selected_streams() {
    //parse the requested instruments and datastreams from subsequent forms
    //check if a streams select exists and has values
    var selected_streams = $('#streams,#products').val()
    if(selected_streams && selected_streams.length){
        selected_streams = $('#streams,#products').val();
        //only show meteorograms for selected headers
        selected_streams = _.reject(selected_streams,function(stream){
            return stream.indexOf('header') != -1;
        });
        //air temp and dewpoint map to the same thing, we only need one of them
        var air_temps = _.filter(selected_streams,function(stream){
            return stream.indexOf('air_temp') != -1;
        });
        /*
        _.each(air_temps,function(t_stream){
            selected_streams = _.reject(selected_streams,function(stream){
                return stream == t_stream.replace('air_temp','dewpoint');
            });
        });
        */
    } else {
        selected_streams = [];
        $('#instruments select').each(function(){
            selected_streams = selected_streams.concat($(this).val());
        });
    }

    return selected_streams;
}

function ql_update_func() {
    //TODO: Split this function up
    var start_date;
    var end_date;
    var ndays;
    if(!$('#last_x_days, #date_range').is(':checked')){
        $('#preview').hide();
        return;
    }
    //parse the requested date range from the Timeframe form
    if($("#last_x_days").is(":checked")){
        ndays = Number(val_or_place('#x_days'));
        if((ndays < 32) && (ndays > 0)){
            start_date= moment.utc();
            end_date = ndays;
        }else{
            $('#preview').hide();
            return;//return if too many days are being requested
        }
    }else if($("#date_range").is(":checked")){
        var date1 = moment.utc(val_or_place('#Start-date-picker'));
        var date2 = moment.utc(val_or_place('#End-date-picker'));
        ndays = dayRange(date1,date2).length;
        if((ndays < 32) && (ndays > 0)){
            start_date = date1;
            end_date = date2;
        }else{
            $('#preview').hide();
            return;//return if too many days are being requested
        }

    }

    var selected_streams = get_selected_streams();
    if (_.some(selected_streams)) {
        $('#qltable>tbody').empty();
        $('#qltable').append('<tr class="ql_date_row" inst="tower" site="aoss"></tr>');
        $('#ql-labels').empty();
        $('#ql-labels').append('<b>Date</b>');
        var used_products = [];

        _.each(selected_streams,function(instr){
            if(!instr) return;
            instr = instr.split(' ')[0];
            var site = instr.split('.')[0];
            var inst = instr.split('.')[1];
            if(!inst) return;
            var product = instr.split('.')[2] || 'meteorogram-daily';
            if(!product || used_products.indexOf(product) != -1) return;
            used_products.push(product);
            //some parameters don't have an associated thumbnail, ignore them
            var image_fmt = quicklookArchiveInfo.getProductUrlsAtLevel(site,inst,'level_b1',product);
            if(!image_fmt.path) return;
            var label = quicklookArchiveInfo.getFancyProductName(site,inst,'level_b1',product);
            $('#qltable').append( 
                '<tr class="ql_row" inst="'+inst+'" site="'+site+ '" product="'+product+'"></tr>'
            );
            $('#ql-labels').append(
                '<div class="ql-label"><b>'+label+'</b></div>'
            );
        });
        $('#preview').show();
        $('#qltable').css('width', 120 * ndays);
        updateQuickLooks(start_date, end_date);
    }
}

var bindQuicklookUpdatesToForms = function(){
    $('#instruments select').change(ql_update_func);
    $('#x_days').change(ql_update_func);
    $('#last_x_days').click(ql_update_func);
};

$(document).ready(function(){
//    $('#preview').resizable();
});