Added foundations of HTML form
This commit is contained in:
parent
0d195cb4ce
commit
86333d7188
6 changed files with 346 additions and 20 deletions
BIN
cara/.DS_Store
vendored
Normal file
BIN
cara/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
cara/apps/.DS_Store
vendored
Normal file
BIN
cara/apps/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
cara/apps/calculator/.DS_Store
vendored
Normal file
BIN
cara/apps/calculator/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
cara/apps/calculator/static/.DS_Store
vendored
Normal file
BIN
cara/apps/calculator/static/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -1,15 +1,178 @@
|
|||
<html>
|
||||
<head>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<form id="covid-calculator">
|
||||
<label for="room_name">Room name:</label>
|
||||
<input name="room_name" type="text" value="" />
|
||||
<input type="submit" value="Send" />
|
||||
</form>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha512-uto9mlQzrs59VwILcLiRYeLKPPbS/bT71da/OEBYEwcdNUk8jYIy+D176RYoop1Da+f9mvkYrmj5MCLZWEtQuA==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="/calculator/static/js/form.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" integrity="sha512-aOG0c6nPNzGk+5zjwyJaoRUgCdOrfSDhmMID2u4+OIslr0GjpLKo7Xm0Ao3xmpM4T8AmIouRkqwj1nrdVsLKEQ==" crossorigin="anonymous" />
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="clear_form()">
|
||||
|
||||
<h1> <p><b>CARA</b> Covid Calculator </p></h1>
|
||||
|
||||
<form name="CARAinputs" onsubmit='return on_submit(this)'>
|
||||
<div style="width: 33%; float:left;">
|
||||
|
||||
<!-- General Options -->
|
||||
Simulation name: <input type="text" name="simulation_name" placeholder="E.g. Workshop without masks" required><br>
|
||||
Room number: <input type="text" name="room_number" placeholder="E.g. 17/R-033" required><br>
|
||||
|
||||
<input type="radio" id="room_type_volume" name="volume_type" value="room_volume" onclick="require_fields(this)" required>
|
||||
Room volume: <input type="number" id="room_volume" name="room_volume" placeholder="Room volume (m³)" min="0"><br>
|
||||
<input type="radio" id="room_type_dimensions" name="volume_type" value="room_dimensions" onclick="require_fields(this)" required>
|
||||
Floor area: <input type="number" id="floor_area" name="floor_area" placeholder="Room floor area (m²)" min="0"><br>
|
||||
Ceiling height: <input type="number" id="ceiling_height" name="ceiling_height" placeholder="Room ceiling height (m²)" min="0"><br>
|
||||
|
||||
<!-- Ventilation Options -->
|
||||
Ventilation type:
|
||||
<input type="radio" id="mechanical" name="ventilation_type" value="mechanical" onclick="show_hide('DIVmechanical_ventilation', 'DIVnatural_ventilation', this)" required>Mechanical</input>
|
||||
<input type="radio" id="natural" name="ventilation_type" value="natural" onclick="show_hide('DIVnatural_ventilation', 'DIVmechanical_ventilation', this)" required>Natural</input>
|
||||
|
||||
<div id="DIVmechanical_ventilation" style="display:none">
|
||||
<input type="radio" id="air_type_changes" name="air_type" value="air_changes" onclick="require_fields(this)">
|
||||
Air changes per hour <input type="number" id="air_changes" name="air_changes" min="0"><br>
|
||||
<input type="radio" id="air_type_supply" name="air_type" value="air_supply" onclick="require_fields(this)">
|
||||
Air supply flow rate <input type="number" id="air_supply" name="air_supply" min="0"><br>
|
||||
</div>
|
||||
|
||||
<div id="DIVnatural_ventilation" style="display:none">
|
||||
Number of windows: <input type="number" id="windows_number" name="windows_number" min="0"><br>
|
||||
Height of window: <input type="number" id="window_height" name="window_height" placeholder="meters" min="0"><br>
|
||||
Width of window: <input type="number" id="window_width" name="window_width" placeholder="meters" min="0"><br>
|
||||
Opening distance: <input type="number" id="opening_distance" name="opening_distance" placeholder="centimeters" min="0"><br>
|
||||
Windows open: <input type="radio" id="always" name="windows_open" value="always">
|
||||
<label for="always">Always</label>
|
||||
<input type="radio" id="interval" name="windows_open" value="interval">
|
||||
<label for="interval">15 min / 2h</label><br>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="width: 33%; float:left;">
|
||||
|
||||
<!-- Event Options -->
|
||||
Event data:<br>
|
||||
Attendees:<br>
|
||||
Total number of people: <input type="number" name="total_people" min="1" required><br>
|
||||
Number of infected people: <input type="number" name="infected_people" min="0" required><br>
|
||||
Activity type: <select id="activity_type" name="activity_type">
|
||||
<option value="training">Training</option>
|
||||
<option value="workshop">Workshop</option>
|
||||
<option value="office">Office</option>
|
||||
</select><br>
|
||||
Start: <input type="time" id="activity_start" name="activity_start" required>
|
||||
Finish: <input type="time" id="activity_finish" name="activity_finish" required><br>
|
||||
|
||||
<input type="radio" id="event_type_single" name="event_type" value="single_event" onclick="require_fields(this)" required>Single event</input>
|
||||
Date: <input type="text" id="datepicker" name="single_event_date" unrequired><br>
|
||||
<input type="radio" id="event_type_recurrent" name="event_type" value="recurrent_event" onclick="require_fields(this)" required>Recurrent usage</input>
|
||||
<select id="recurrent_event_month" name="recurrent_event_month">
|
||||
<option value="January">January</option>
|
||||
<option value="February">February</option>
|
||||
<option value="March">March</option>
|
||||
<option value="April">April</option>
|
||||
<option value="May">May</option>
|
||||
<option value="June">June</option>
|
||||
<option value="July">July</option>
|
||||
<option value="August">August</option>
|
||||
<option value="September">September</option>
|
||||
<option value="October">October</option>
|
||||
<option value="November">November</option>
|
||||
<option value="December">December</option>
|
||||
</select><br>
|
||||
|
||||
<!-- Lunch Options -->
|
||||
<input type="hidden" id="lunch_option" name="lunch_option" value=0>
|
||||
<button type="button" id="BUTTON_lunch" name="BUTTON_lunch" onclick="show('DIVlunch_break', 'lunch_option', this)">Lunch break</button><br>
|
||||
<div id="DIVlunch_break" style="display:none">
|
||||
Start: <input type="time" id="lunch_start" name="lunch_start" unrequired>
|
||||
Finish: <input type="time" id="lunch_finish" name="lunch_finish" unrequired><br>
|
||||
</div>
|
||||
|
||||
<!-- Coffee Options -->
|
||||
<input type="hidden" id="coffee_option" name="coffee_option" value=0>
|
||||
<button type="button" id="BUTTON_coffee" name="BUTTON_coffee" onclick="show('DIVcoffee_break', 'coffee_option', this)">Coffee breaks</button><br>
|
||||
<div id="DIVcoffee_break" style="display:none">
|
||||
Number of breaks: <input type="number" id="coffee_breaks" name="coffee_breaks" min="0"><br>
|
||||
Duration (minutes): <select id="break_duration" name="coffee_duration">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
<option value="6">6</option>
|
||||
<option value="7">7</option>
|
||||
<option value="8">8</option>
|
||||
<option value="9">9</option>
|
||||
<option value="10">10</option>
|
||||
<option value="11">11</option>
|
||||
<option value="12">12</option>
|
||||
<option value="13">13</option>
|
||||
<option value="14">14</option>
|
||||
<option value="15">15</option>
|
||||
<option value="16">16</option>
|
||||
<option value="17">17</option>
|
||||
<option value="18">18</option>
|
||||
<option value="19">19</option>
|
||||
<option value="20">20</option>
|
||||
<option value="21">21</option>
|
||||
<option value="22">22</option>
|
||||
<option value="23">23</option>
|
||||
<option value="24">24</option>
|
||||
<option value="25">25</option>
|
||||
<option value="26">26</option>
|
||||
<option value="27">27</option>
|
||||
<option value="28">28</option>
|
||||
<option value="29">29</option>
|
||||
<option value="30">30</option>
|
||||
</select><br>
|
||||
Regular breaks are spread evenly throughout the day
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="width: 33%; float:left;">
|
||||
Mask wearing: <input type="radio" id="continuous" name="mask_wearing" value="continuous" required>Continuous
|
||||
<input type="radio" id="removed" name="mask_wearing" value="removed" required>Removed when seated
|
||||
|
||||
<p>This tool estimates the risk of COVID-19 spread. It is based on current scientific data and can be used to provide an illustration for different real world scenarios.<br><br>
|
||||
|
||||
<b>How to use this tool:</b><br>
|
||||
|
||||
<b>Room data</b><br>
|
||||
|
||||
Enter the data about the area you wish to study. You can find these in GIS, or by measuring them yourself.
|
||||
For mechanical ventilation, you should check with a specialist for the air flow or air change rate.<br><br>
|
||||
|
||||
<b> Event data </b><br>
|
||||
|
||||
Enter the total number of people and how many you assume are infected.<br><br>
|
||||
|
||||
<b>Activity types: </b><br>
|
||||
|
||||
Office = typical scenario all persons seated, talking quietly.<br>
|
||||
Workshop = assembly workshop environment, all persons doing light exercise, talking.<br>
|
||||
Training = one person standing, talking, all others seated, breathing normally.<br>
|
||||
Seminar = As training, but all participants take turns in standing and talking.<br>
|
||||
|
||||
You should specify if the event is a one off (give date) or recurrent use of the same space for the same activity, in which case tick the months when the activity takes place.<br>
|
||||
|
||||
Specify if a lunch break should be included, and when it starts/stops.<br>
|
||||
|
||||
If you will take coffee breaks, they are spread out evenly throughout the day, in addition to lunch.<br>
|
||||
|
||||
Mask wearing: Specify if they are worn all the time, or only when less than 2 meters apart.</p><br>
|
||||
|
||||
</div>
|
||||
|
||||
<button type='submit'>Generate report</button><br><br><br><br>
|
||||
</form>
|
||||
|
||||
<div id="results">
|
||||
The results will go here:
|
||||
|
|
@ -17,15 +180,6 @@
|
|||
|
||||
<script>
|
||||
|
||||
function objectifyForm(formArray) {
|
||||
//serialize data function
|
||||
var returnArray = {};
|
||||
for (var i = 0; i < formArray.length; i++){
|
||||
returnArray[formArray[i]['name']] = formArray[i]['value'];
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
// Contents from https://stackoverflow.com/a/5004276/741316
|
||||
|
||||
// Variable to hold request
|
||||
|
|
|
|||
172
cara/apps/calculator/static/js/form.js
Normal file
172
cara/apps/calculator/static/js/form.js
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
function clear_form(){
|
||||
document.CARAinputs.reset();
|
||||
}
|
||||
|
||||
/* -------Show/Hide DIVs------- */
|
||||
function show(show, var_id, obj) {
|
||||
var show = document.getElementById(show);
|
||||
if (show.style.display === "none") {
|
||||
show.style.display = "block";
|
||||
document.getElementById(var_id).value = 1;
|
||||
} else {
|
||||
show.style.display = "none";
|
||||
document.getElementById(var_id).value = 0;
|
||||
}
|
||||
require_fields(obj);
|
||||
}
|
||||
|
||||
function show_hide(show, hide, obj) {
|
||||
var show = document.getElementById(show);
|
||||
var hide = document.getElementById(hide);
|
||||
|
||||
if (show.style.display === "none") {
|
||||
show.style.display = "block";
|
||||
hide.style.display = "none";
|
||||
}// else {
|
||||
// show.style.display = "none";
|
||||
//}
|
||||
|
||||
require_fields(obj);
|
||||
|
||||
}
|
||||
|
||||
/*$(document).on("click", "input[name='ventilation_type']", function(){
|
||||
thisRadio = $(this);
|
||||
if (thisRadio.hasClass("imChecked")) {
|
||||
thisRadio.removeClass("imChecked");
|
||||
thisRadio.prop('checked', false);
|
||||
} else {
|
||||
thisRadio.prop('checked', true);
|
||||
thisRadio.addClass("imChecked");
|
||||
};
|
||||
})*/
|
||||
|
||||
/* -------Required fields------- */
|
||||
function require_fields(obj){
|
||||
switch(obj.id) {
|
||||
case "room_type_volume":
|
||||
require_room_volume(true);
|
||||
require_room_dimensions(false);
|
||||
break;
|
||||
case "room_type_dimensions":
|
||||
require_room_volume(false);
|
||||
require_room_dimensions(true);
|
||||
break;
|
||||
case "mechanical":
|
||||
require_mechanical_ventilation(true);
|
||||
require_natural_ventilation(false);
|
||||
break;
|
||||
case "natural":
|
||||
require_mechanical_ventilation(false);
|
||||
require_natural_ventilation(true);
|
||||
break;
|
||||
case "air_type_changes":
|
||||
require_air_changes(true);
|
||||
require_air_supply(false);
|
||||
break;
|
||||
case "air_type_supply":
|
||||
require_air_changes(false);
|
||||
require_air_supply(true);
|
||||
break;
|
||||
case "event_type_single":
|
||||
require_single_event(true);
|
||||
break;
|
||||
case "event_type_recurrent":
|
||||
require_single_event(false);
|
||||
break;
|
||||
case "BUTTON_lunch":
|
||||
var button = document.getElementById("lunch_option");
|
||||
if (button.value == 0)
|
||||
require_lunch(false);
|
||||
else if (button.value == 1)
|
||||
require_lunch(true);
|
||||
break;
|
||||
case "BUTTON_coffee":
|
||||
var button = document.getElementById("coffee_option");
|
||||
if (button.value == 0)
|
||||
require_coffee(false);
|
||||
else if (button.value == 1)
|
||||
require_coffee(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} }
|
||||
|
||||
function require_room_volume(option) {
|
||||
$("#room_volume").prop('required',option);
|
||||
}
|
||||
|
||||
function require_room_dimensions(option) {
|
||||
$("#floor_area").prop('required',option);
|
||||
$("#ceiling_height").prop('required',option);
|
||||
}
|
||||
|
||||
function require_mechanical_ventilation(option) {
|
||||
$("#air_type_changes").prop('required',option);
|
||||
$("#air_type_supply").prop('required',option);
|
||||
}
|
||||
|
||||
function require_natural_ventilation(option) {
|
||||
$("#windows_number").prop('required',option);
|
||||
$("#window_height").prop('required',option);
|
||||
$("#window_width").prop('required',option);
|
||||
$("#opening_distance").prop('required',option);
|
||||
$("#always").prop('required',option);
|
||||
$("#interval").prop('required',option);
|
||||
}
|
||||
|
||||
function require_air_changes(option) {
|
||||
$("#air_changes").prop('required',option);
|
||||
}
|
||||
|
||||
function require_air_supply(option) {
|
||||
$("#air_supply").prop('required',option);
|
||||
}
|
||||
|
||||
function require_single_event(option) {
|
||||
$("#datepicker").prop('required',option);
|
||||
}
|
||||
|
||||
function require_lunch(option) {
|
||||
$("#lunch_start").prop('required',option);
|
||||
$("#lunch_finish").prop('required',option);
|
||||
}
|
||||
|
||||
function require_coffee(option) {
|
||||
$("#coffee_breaks").prop('required',option);
|
||||
}
|
||||
|
||||
/* -------UI------- */
|
||||
$(function() {
|
||||
$("#datepicker").datepicker();
|
||||
});
|
||||
|
||||
/* -------Submit form------- */
|
||||
function on_submit(form){
|
||||
|
||||
//Prevent default posting of form - put here to work in case of errors
|
||||
event.preventDefault();
|
||||
|
||||
//Serialize the data in the form
|
||||
var serializedData = objectifyForm($(form).serializeArray());
|
||||
|
||||
console.log( serializedData );
|
||||
return false; //don't submit
|
||||
}
|
||||
|
||||
//Convert all type int in form
|
||||
function objectifyForm(formArray) {
|
||||
returnArray = {};
|
||||
for (var i = 0; i < formArray.length; i++) {
|
||||
|
||||
var value = Number(formArray[i]['value']);
|
||||
|
||||
if (formArray[i]['name'] === "simulation_name")
|
||||
returnArray[formArray[i]['name']] = formArray[i]['value'].toString();
|
||||
else if(isNaN(value) || !formArray[i]['value'].trim())
|
||||
returnArray[formArray[i]['name']] = formArray[i]['value'];
|
||||
else
|
||||
returnArray[formArray[i]['name']] = value;
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
Loading…
Reference in a new issue