ui modifications on js logic
This commit is contained in:
parent
6581586982
commit
7e29c0c5cf
2 changed files with 204 additions and 153 deletions
|
|
@ -1,7 +1,5 @@
|
|||
// JS file to handle manipulation on CO2 Fitting Algorithm Dialog.
|
||||
const CO2_data_form = [
|
||||
'CO2_data',
|
||||
'specific_breaks',
|
||||
'exposed_coffee_break_option',
|
||||
'exposed_coffee_duration',
|
||||
'exposed_finish',
|
||||
|
|
@ -9,6 +7,8 @@ const CO2_data_form = [
|
|||
'exposed_lunch_option',
|
||||
'exposed_lunch_start',
|
||||
'exposed_start',
|
||||
'fitting_ventilation_states',
|
||||
'fitting_ventilation_type',
|
||||
'infected_coffee_break_option',
|
||||
'infected_coffee_duration',
|
||||
'infected_dont_have_breaks_with_exposed',
|
||||
|
|
@ -21,174 +21,239 @@ const CO2_data_form = [
|
|||
'room_volume',
|
||||
'total_people',
|
||||
'ventilation_type',
|
||||
'windows_duration',
|
||||
'windows_frequency',
|
||||
'window_opening_regime',
|
||||
]
|
||||
|
||||
// Method to upload a valid excel file
|
||||
function upload_file() {
|
||||
clear_fitting_result_component();
|
||||
$("#generate_fitting_data").show();
|
||||
$("#save_and_dismiss_dialog").hide();
|
||||
var files = document.getElementById("file_upload").files;
|
||||
if (files.length == 0) {
|
||||
alert("Please choose any file...");
|
||||
return;
|
||||
];
|
||||
|
||||
// Method to upload a valid excel file
|
||||
function uploadFile(endpoint) {
|
||||
clearFittingResultComponent();
|
||||
const files = document.getElementById("file_upload").files;
|
||||
if (files.length === 0) {
|
||||
alert("Please choose any file...");
|
||||
return;
|
||||
}
|
||||
const filename = files[0].name;
|
||||
const extension = filename.substring(filename.lastIndexOf(".")).toUpperCase();
|
||||
if (extension == ".XLS" || extension == ".XLSX") {
|
||||
//Here calling another method to read excel file into json
|
||||
excelFileToJSON(files[0]);
|
||||
} else {
|
||||
alert("Please select a valid excel file.");
|
||||
}
|
||||
}
|
||||
|
||||
//Method to read excel file and convert it into JSON
|
||||
function excelFileToJSON(file) {
|
||||
const file = files[0];
|
||||
const extension = file.name.substring(file.name.lastIndexOf(".")).toUpperCase();
|
||||
extension === ".XLS" || extension === ".XLSX"
|
||||
? excelFileToJSON(endpoint, file)
|
||||
: alert("Please select a valid excel file.");
|
||||
}
|
||||
|
||||
// Method to read excel file and convert it into JSON
|
||||
function excelFileToJSON(endpoint, file) {
|
||||
try {
|
||||
var reader = new FileReader();
|
||||
reader.readAsBinaryString(file);
|
||||
reader.onload = function (e) {
|
||||
var data = e.target.result;
|
||||
var workbook = XLSX.read(data, { type: "binary" });
|
||||
var firstSheetName = workbook.SheetNames[0];
|
||||
//reading only first sheet data
|
||||
var jsonData = XLSX.utils.sheet_to_json(workbook.Sheets[firstSheetName]);
|
||||
//displaying the json result into HTML table
|
||||
displayJsonToHtmlTable(jsonData);
|
||||
};
|
||||
const reader = new FileReader();
|
||||
reader.readAsBinaryString(file);
|
||||
reader.onload = function (e) {
|
||||
const data = e.target.result;
|
||||
const workbook = XLSX.read(data, { type: "binary" });
|
||||
const firstSheetName = workbook.SheetNames[0];
|
||||
const jsonData = XLSX.utils.sheet_to_json(workbook.Sheets[firstSheetName]);
|
||||
displayJsonToHtmlTable(endpoint, jsonData);
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
//Method to display the data in HTML Table
|
||||
function displayJsonToHtmlTable(jsonData) {
|
||||
var table = document.getElementById("display_excel_data");
|
||||
var format = document.getElementById("formatted_data");
|
||||
let structure = { times: [], CO2: [] };
|
||||
}
|
||||
|
||||
// Method to display the data in HTML Table
|
||||
function displayJsonToHtmlTable(endpoint, jsonData) {
|
||||
const table = document.getElementById("display_excel_data");
|
||||
const format = document.getElementById("CO2_data");
|
||||
const structure = { times: [], CO2: [] };
|
||||
if (jsonData.length > 0) {
|
||||
var htmlData = "<tr><th>Time</th><th>CO2 Value</th></tr>";
|
||||
let jsonLength = jsonData.length;
|
||||
for (var i = 0; i < jsonLength; i++) {
|
||||
var row = jsonData[i];
|
||||
if (i < 5) {
|
||||
htmlData +=
|
||||
`<tr><td>
|
||||
${row["Times"].toFixed(2)}
|
||||
</td><td>
|
||||
${row["CO2"].toFixed(2)}
|
||||
</td></tr>`;
|
||||
}
|
||||
structure["times"].push(row["Times"]);
|
||||
structure["CO2"].push(row["CO2"]);
|
||||
let htmlData = "<tr><th>Time</th><th>CO2 Value</th></tr>";
|
||||
const jsonLength = jsonData.length;
|
||||
for (let i = 0; i < jsonLength; i++) {
|
||||
const row = jsonData[i];
|
||||
if (i < 5) {
|
||||
htmlData += `
|
||||
<tr>
|
||||
<td>${row["Times"].toFixed(2)}</td>
|
||||
<td>${row["CO2"].toFixed(2)}</td>
|
||||
</tr>`;
|
||||
}
|
||||
|
||||
if (jsonLength >= 5) htmlData += "<tr><td> ... </td><td> ... </td></tr>";
|
||||
table.innerHTML = htmlData;
|
||||
format.value = JSON.stringify(structure);
|
||||
$('#generate_fitting_data').prop("disabled", false);
|
||||
structure.times.push(row["Times"]);
|
||||
structure.CO2.push(row["CO2"]);
|
||||
}
|
||||
|
||||
if (jsonLength >= 5) {
|
||||
htmlData += "<tr><td> ... </td><td> ... </td></tr>";
|
||||
}
|
||||
format.value = JSON.stringify(structure);
|
||||
$('#generate_fitting_data').prop("disabled", false);
|
||||
$('#fitting_ventilation_states').prop('disabled', false);
|
||||
$('[name=fitting_ventilation_type]').prop('disabled', false);
|
||||
plotCO2Data(endpoint);
|
||||
} else {
|
||||
table.innerHTML = "There is no data in the spreadsheet file";
|
||||
table.innerHTML = "There is no data in the spreadsheet file";
|
||||
}
|
||||
}
|
||||
|
||||
// Method to download Excel template available on CERNBox
|
||||
function downloadTemplate(uri = 'https://caimira-resources.web.cern.ch/CO2_template.xlsx', filename = 'CO2_template.xlsx') {
|
||||
var link = document.createElement("a");
|
||||
}
|
||||
|
||||
// Method to download Excel template available on CERNBox
|
||||
function downloadTemplate(uri = 'https://caimira-resources.web.cern.ch/CO2_template.xlsx', filename = 'CO2_template.xlsx') {
|
||||
const link = document.createElement("a");
|
||||
link.download = filename;
|
||||
link.href = uri;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
delete link;
|
||||
}
|
||||
|
||||
function insertErrorFor(referenceNode, text) {
|
||||
var element = document.createElement("span");
|
||||
}
|
||||
|
||||
function insertErrorFor(referenceNode, text) {
|
||||
const element = document.createElement("span");
|
||||
element.setAttribute("class", "error_text");
|
||||
element.classList.add("red_text");
|
||||
element.innerHTML = " " + text;
|
||||
$(referenceNode).before(element);
|
||||
}
|
||||
|
||||
function validate() {
|
||||
}
|
||||
|
||||
function validateFormInputs(obj) {
|
||||
$('span.' + "error_text").remove();
|
||||
let submit = true;
|
||||
for (var i = 0; i < CO2_data_form.length; i++) {
|
||||
let element = $(`[name=${CO2_data_form[i]}]`)[0];
|
||||
if (element.value === '') {
|
||||
insertErrorFor($('#CO2_input_data_div'), `'${element.name}' must be defined.`); // raise error for total number and room volume.
|
||||
for (let i = 0; i < CO2_data_form.length; i++) {
|
||||
const element = $(`[name=${CO2_data_form[i]}]`)[0];
|
||||
if (element.name !== 'fitting_ventilation_states' && element.value === '') {
|
||||
insertErrorFor($('#DIVCO2_data_dialog'), `'${element.name}' must be defined.<br />`);
|
||||
submit = false;
|
||||
}
|
||||
}
|
||||
if (submit) {
|
||||
$($(obj).data('target')).modal('show');
|
||||
}
|
||||
return submit;
|
||||
}
|
||||
|
||||
function validateCO2Form() {
|
||||
let submit = true;
|
||||
if (validateFormInputs($('#button_fit_data'))) submit = true;
|
||||
|
||||
// Check if natural ventilation is selected
|
||||
if ($('input[name="fitting_ventilation_type"]:checked')[0].value == 'fitting_natural_ventilation') {
|
||||
// Validate ventilation scheme
|
||||
const element = $('[name=fitting_ventilation_states')[0]
|
||||
if (element.value !== '') {
|
||||
// validate input format
|
||||
try {
|
||||
const parsedValue = JSON.parse(element.value);
|
||||
if (!Array.isArray(parsedValue)) {
|
||||
insertErrorFor($('#DIVCO2_fitting_result'), `'${element.name}' must be a list.</br>`);
|
||||
submit = false;
|
||||
};
|
||||
} catch {
|
||||
insertErrorFor($('#DIVCO2_fitting_result'), `'${element.name}' must be a list of numbers.</br>`);
|
||||
submit = false;
|
||||
};
|
||||
} else {
|
||||
insertErrorFor($('#DIVCO2_fitting_result'), `'${element.name}' must be defined.</br>`);
|
||||
submit = false;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return submit;
|
||||
}
|
||||
|
||||
function display_transition_times_hour_format(start, stop) {
|
||||
var minutes_start = start % 1 * 60;
|
||||
var minutes_stop = stop % 1 * 60;
|
||||
return Math.floor(start) + ':' + minutes_start.toPrecision(2) + ' - ' + Math.floor(stop) + ':' + minutes_stop.toPrecision(2);
|
||||
function displayTransitionTimesHourFormat(start, stop) {
|
||||
var minutes_start = (start % 1 * 60).toPrecision(2);
|
||||
var minutes_stop = (stop % 1 * 60).toPrecision(2);
|
||||
return Math.floor(start) + ':' + ((minutes_start != '0.0') ? minutes_start : '00') + ' - ' + Math.floor(stop) + ':' + ((minutes_stop != '0.0') ? minutes_stop : '00');
|
||||
}
|
||||
|
||||
function display_fitting_data(json_response) {
|
||||
$("#DIV_CO2_fitting_result").show();
|
||||
function displayFittingData(json_response) {
|
||||
$("#DIVCO2_fitting_result").show();
|
||||
$("#CO2_data_plot").attr("src", json_response['CO2_plot']);
|
||||
// Not needed for the form submit
|
||||
delete json_response['CO2_plot'];
|
||||
$("#CO2_fitting_result").val(JSON.stringify(json_response));
|
||||
$("#exhalation_rate_fit").html('Exhalation rate: ' + String(json_response['exhalation_rate'].toFixed(2)) + ' m³/h');
|
||||
let ventilation_table = "<tr><th>Time (HH:MM)</th><th>ACH value (h⁻¹)</th></tr>";
|
||||
json_response['ventilation_values'].map((val, index) => {
|
||||
let transition_times = display_transition_times_hour_format(json_response['transition_times'][index], json_response['transition_times'][index + 1]);
|
||||
json_response['ventilation_values'].forEach((val, index) => {
|
||||
let transition_times = displayTransitionTimesHourFormat(json_response['transition_times'][index], json_response['transition_times'][index + 1]);
|
||||
ventilation_table += `<tr><td>${transition_times}</td><td>${val.toPrecision(2)}</td></tr>`;
|
||||
});
|
||||
$('#disable_fitting_algorithm').prop('disabled', false);
|
||||
$("#ventilation_rate_fit").html(ventilation_table);
|
||||
$("#generate_fitting_data").html('Fit data');
|
||||
$("#generate_fitting_data").hide();
|
||||
$("#save_and_dismiss_dialog").show();
|
||||
}
|
||||
|
||||
function submit_fitting_algorithm(url) {
|
||||
if (validate()) {
|
||||
let CO2_mapping = {};
|
||||
CO2_data_form.map(el => {
|
||||
let element = $(`[name=${el}]`);
|
||||
// Validate radio buttons
|
||||
if (element.length != 1) CO2_mapping[element[0].name] = $(`[name=${element[0].name}]:checked`)[0].value
|
||||
else CO2_mapping[element[0].name] = element[0].value;
|
||||
})
|
||||
$('#CO2_input_data_div').show();
|
||||
$("#generate_fitting_data").html(
|
||||
`<span id="loading_spinner" class="spinner-border spinner-border-sm mr-2" role="status" aria-hidden="true" disabled ></span>Loading...`
|
||||
);
|
||||
$('#CO2_input_data').html(JSON.stringify(CO2_mapping, null, "\t"))
|
||||
function formatCO2DataForm(CO2_data_form) {
|
||||
let CO2_mapping = {};
|
||||
CO2_data_form.map(el => {
|
||||
let element = $(`[name=${el}]`);
|
||||
// Validate checkboxes
|
||||
if (element[0].type == 'checkbox') {
|
||||
CO2_mapping[element[0].name] = String(+element[0].checked);
|
||||
}
|
||||
// Validate radio buttons
|
||||
else if (element[0].type == 'radio') CO2_mapping[element[0].name] = $(`[name=${element[0].name}]:checked`)[0].value;
|
||||
else CO2_mapping[element[0].name] = element[0].value;
|
||||
});
|
||||
return CO2_mapping;
|
||||
}
|
||||
|
||||
function plotCO2Data(url) {
|
||||
if (validateFormInputs()) {
|
||||
let CO2_mapping = formatCO2DataForm(CO2_data_form);
|
||||
fetch(url, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(CO2_mapping),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((json_response) => {
|
||||
display_fitting_data(json_response);
|
||||
});
|
||||
.then((response) =>
|
||||
response.json()
|
||||
.then(json_response => $("#CO2_data_plot").attr("src", json_response['CO2_plot']))
|
||||
.then($('#DIVCO2_fitting_to_submit').show())
|
||||
.catch(error => console.log(error))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function clear_fitting_result_component() {
|
||||
$('#generate_fitting_data').prop("disabled", true);
|
||||
$("#display_excel_data tbody").remove();
|
||||
function submitFittingAlgorithm(url) {
|
||||
if (validateCO2Form()) {
|
||||
// Disable all the ventilation inputs
|
||||
$('#fitting_ventilation_states, [name=fitting_ventilation_type]').prop('disabled', true);
|
||||
|
||||
// Prepare data for submission
|
||||
const CO2_mapping = formatCO2DataForm(CO2_data_form);
|
||||
$('#CO2_input_data_div').show();
|
||||
$('#disable_fitting_algorithm').prop('disabled', true);
|
||||
$('#generate_fitting_data')
|
||||
.html('<span id="loading_spinner" class="spinner-border spinner-border-sm mr-2" role="status" aria-hidden="true"></span>Loading...')
|
||||
.prop('disabled', true);
|
||||
$('#CO2_input_data').html(JSON.stringify(CO2_mapping, null, '\t'));
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(CO2_mapping),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((json_response) => {
|
||||
displayFittingData(json_response);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function clearFittingResultComponent() {
|
||||
// Remove all the previously generated fitting elements
|
||||
$('#generate_fitting_data').prop('disabled', true);
|
||||
$('#CO2_fitting_result').val('');
|
||||
$('#formatted_data').val('');
|
||||
$('span.' + "error_text").remove();
|
||||
$('#DIV_CO2_fitting_result').hide();
|
||||
$('#CO2_input_data_div').hide();
|
||||
}
|
||||
|
||||
function clear_fitting_algorithm() {
|
||||
clear_fitting_result_component();
|
||||
$('#CO2_data_no').click();
|
||||
ventilation_from_fitting(false);
|
||||
}
|
||||
$('#CO2_data').val('{}');
|
||||
$('#fitting_ventilation_states').val('');
|
||||
$('span.error_text').remove();
|
||||
$('#DIVCO2_fitting_result, #CO2_input_data_div').hide();
|
||||
$('#CO2_data_plot').attr('src', '');
|
||||
|
||||
// Update the ventilation scheme components
|
||||
$('#fitting_ventilation_states, [name=fitting_ventilation_type]').prop('disabled', false);
|
||||
|
||||
// Update the bottom right buttons
|
||||
$('#generate_fitting_data').show();
|
||||
$('#save_and_dismiss_dialog').hide();
|
||||
}
|
||||
|
||||
function disableFittingAlgorithm() {
|
||||
clearFittingResultComponent();
|
||||
$('#CO2_data_no').click();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -247,8 +247,6 @@ function on_ventilation_type_change() {
|
|||
ventilation_types = $('input[type=radio][name=ventilation_type]');
|
||||
ventilation_types.each(function (index) {
|
||||
if (this.checked) {
|
||||
|
||||
if ($(this).val() != 'from_fitting') $('#button_fit_data').attr('data-previous-vent', $(this).val())
|
||||
getChildElement($(this)).show();
|
||||
require_fields(this);
|
||||
} else {
|
||||
|
|
@ -495,32 +493,13 @@ function on_coffee_break_option_change() {
|
|||
}
|
||||
}
|
||||
|
||||
function ventilation_from_fitting(condition_from_fitting) {
|
||||
$('input[type=radio][id=no_ventilation]').prop("disabled", condition_from_fitting);
|
||||
$('input[type=radio][id=mechanical_ventilation]').prop("disabled", condition_from_fitting);
|
||||
$('input[type=radio][id=natural_ventilation]').prop("disabled", condition_from_fitting);
|
||||
$('input[type=radio][id=from_fitting]').prop("disabled", !condition_from_fitting);
|
||||
if (condition_from_fitting) {
|
||||
$('input[type=radio][id=from_fitting]').prop('checked',true);
|
||||
$('#DIVfrom_fitting').after($('#window_opening_regime'));
|
||||
}
|
||||
else {
|
||||
let selected_ventilation = $("#button_fit_data").attr('data-previous-vent');
|
||||
$(`input[type=radio][id=${selected_ventilation}]`).prop('checked',true);
|
||||
$('#DIVopening_distance').after($('#window_opening_regime'));
|
||||
}
|
||||
on_ventilation_type_change();
|
||||
}
|
||||
|
||||
function on_CO2_data_option_change() {
|
||||
CO2_data_options = $('input[type=radio][name=CO2_data_option]');
|
||||
CO2_data_options.each(function (index){
|
||||
function on_CO2_fitting_ventilation_change() {
|
||||
ventilation_options = $('input[type=radio][name=fitting_ventilation_type]');
|
||||
ventilation_options.each(function (index) {
|
||||
if (this.checked) {
|
||||
if (this.id == 'CO2_data_yes') ventilation_from_fitting(true);
|
||||
else if (this.id == 'CO2_data_no') ventilation_from_fitting(false);
|
||||
getChildElement($(this)).show();
|
||||
require_fields(this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
getChildElement($(this)).hide();
|
||||
require_fields(this);
|
||||
|
|
@ -700,6 +679,13 @@ function validate_form(form) {
|
|||
on_short_range_option_change();
|
||||
}
|
||||
|
||||
// Check if fitting is selected
|
||||
if ($('input[type=radio][id=from_fitting]').prop('checked') ) {
|
||||
if ($('#CO2_fitting_result').val() == '')
|
||||
$("input[type=radio][id=no_ventilation]").prop("checked", true);
|
||||
on_ventilation_type_change();
|
||||
}
|
||||
|
||||
if (submit) {
|
||||
$("#generate_report").prop("disabled", true);
|
||||
//Add spinner to button
|
||||
|
|
@ -969,7 +955,7 @@ $(document).ready(function () {
|
|||
|
||||
// Populate CO2 Fitting Algorithm Dialog
|
||||
let CO2_data = url.searchParams.has('CO2_fitting_result') ? url.searchParams.get('CO2_fitting_result') : null;
|
||||
if (CO2_data) display_fitting_data(JSON.parse(CO2_data));
|
||||
if (CO2_data) displayFittingData(JSON.parse(CO2_data));
|
||||
|
||||
// Populate primary vaccine dropdown
|
||||
$("#vaccine_type option").remove();
|
||||
|
|
@ -1086,11 +1072,11 @@ $(document).ready(function () {
|
|||
// Call the function now to handle forward/back button presses in the browser.
|
||||
on_coffee_break_option_change();
|
||||
|
||||
// When the CO2_data_option changes we want to make its respective
|
||||
// When the ventilation on the fitting changes we want to make its respective
|
||||
// children show/hide.
|
||||
$("input[type=radio][name=CO2_data_option]").change(on_CO2_data_option_change);
|
||||
$("input[type=radio][name=fitting_ventilation_type]").change(on_CO2_fitting_ventilation_change);
|
||||
// Call the function now to handle forward/back button presses in the browser.
|
||||
on_CO2_data_option_change();
|
||||
on_CO2_fitting_ventilation_change();
|
||||
|
||||
// Setup the maximum number of people at page load (to handle back/forward),
|
||||
// and update it when total people is changed.
|
||||
|
|
|
|||
Loading…
Reference in a new issue