Merge branch 'develop/UI-updates' into 'master'

Foundations for break times constrained within activity times

Closes #106

See merge request cara/cara!113
This commit is contained in:
Philip James Elson 2020-12-03 19:25:41 +00:00
commit 7be99d9494
3 changed files with 137 additions and 61 deletions

View file

@ -4,13 +4,18 @@ function getChildElement(elem) {
return $("#" + elem.data("enables"));
}
function insertSpanAfter(referenceNode, text) {
function insertErrorFor(referenceNode, text) {
var element = document.createElement("span");
element.setAttribute("class", "error_text");
element.classList.add("red_text");
element.innerHTML = "  " + text;
referenceNode.parentNode.insertBefore(element, referenceNode.nextSibling);
}
function removeErrorFor(referenceNode) {
$(referenceNode).next('span.error_text').remove();
}
/* -------Required fields------- */
function require_fields(obj) {
switch ($(obj).attr('id')) {
@ -134,19 +139,23 @@ function require_recurrent_event(option) {
function require_lunch(option) {
$("#lunch_start").prop('required', option);
$("#lunch_finish").prop('required', option);
var lunchStartObj = document.getElementById("lunch_start");
var lunchFinishObj = document.getElementById("lunch_finish");
if (option) {
var start = document.getElementById("lunch_start");
if (start.value === "")
start.value = "12:30";
var finish = document.getElementById("lunch_finish");
if (finish.value === "")
finish.value = "13:30";
if (lunchStartObj.value === "") {
lunchStartObj.value = "12:30";
}
if (lunchFinishObj.value === "") {
lunchFinishObj.value = "13:30";
}
}
else {
document.getElementById("lunch_start").value = "";
document.getElementById("lunch_finish").value = "";
$("#lunch_finish").removeClass("red_border");
$("#lunch_time_error").hide();
lunchStartObj.value = "";
lunchFinishObj.value = "";
$("#lunch_finish").removeClass("red_border finish_time_error lunch_break_error");
$("#lunch_finish").removeClass("red_border finish_time_error lunch_break_error");
removeErrorFor(lunchFinishObj);
}
}
@ -190,7 +199,7 @@ function removeInvalid(id) {
if ($(id).hasClass("red_border")) {
$(id).val("");
$(id).removeClass("red_border");
$(id).next('span').remove();
removeErrorFor(id);
}
}
@ -277,44 +286,62 @@ function validate_form(form) {
//Validate all non zero values
$("input[required].non_zero").each(function() {
if (!validateValue(this))
if (!validateValue(this)) {
submit = false;
}
});
//Validate all dates
$("input[required].datepicker").each(function() {
if (!validateDate(this))
submit = false;
});
if (submit) {
$("input[required].datepicker").each(function() {
if (!validateDate(this)) {
submit = false;
}
});
}
//Validate all times
$("input[required].finish_time").each(function() {
if (!validateFinishTime(this))
submit = false;
});
if (submit) {
$("input[required].finish_time").each(function() {
if (!validateFinishTime(this)) {
submit = false;
}
});
}
//Validate all lunch breaks
if (submit) {
$("input[required].lunch").each(function() {
if (!validateLunchBreak(this)) {
submit = false;
}
});
}
//Check if breaks length >= activity length
var button = document.getElementById("activity_breaks");
$(button).next('span').remove();
if (submit) {
var activityBreaksObj= document.getElementById("activity_breaks");
removeErrorFor(activityBreaksObj);
var lunch_mins = 0;
if (document.getElementById('lunch_option_yes').checked) {
var lunch_start = document.getElementById("lunch_start");
var lunch_finish = document.getElementById("lunch_finish");
lunch_mins = parseTimeToMins(lunch_finish.value) - parseTimeToMins(lunch_start.value);
}
var coffee_breaks = parseInt(document.querySelector('input[name="coffee_breaks"]:checked').value);
var coffee_duration = parseInt(document.getElementById("break_duration").value);
var coffee_mins = coffee_breaks * coffee_duration;
var activity_start = document.getElementById("activity_start");
var activity_finish = document.getElementById("activity_finish");
var activity_mins = parseTimeToMins(activity_finish.value) - parseTimeToMins(activity_start.value);
var lunch_mins = 0;
if (document.getElementById('lunch_option_yes').checked) {
var lunch_start = document.getElementById("lunch_start");
var lunch_finish = document.getElementById("lunch_finish");
lunch_mins = parseTimeToMins(lunch_finish.value) - parseTimeToMins(lunch_start.value);
}
var coffee_breaks = parseInt(document.querySelector('input[name="coffee_breaks"]:checked').value);
var coffee_duration = parseInt(document.getElementById("break_duration").value);
var coffee_mins = coffee_breaks * coffee_duration;
var activity_start = document.getElementById("activity_start");
var activity_finish = document.getElementById("activity_finish");
var activity_mins = parseTimeToMins(activity_finish.value) - parseTimeToMins(activity_start.value);
if ((lunch_mins + coffee_mins) >= activity_mins) {
insertSpanAfter(button, "Length of breaks >= Length of activity");
submit = false;
if ((lunch_mins + coffee_mins) >= activity_mins) {
insertErrorFor(activityBreaksObj, "Length of breaks >= Length of activity");
submit = false;
}
}
return submit;
@ -322,11 +349,11 @@ function validate_form(form) {
function validateValue(obj) {
$(obj).removeClass("red_border");
$(obj).next('span').remove();
removeErrorFor(obj);
if (!isNonZeroOrEmpty($(obj).val())) {
$(obj).addClass("red_border");
insertSpanAfter(obj, "Value must be > 0");
insertErrorFor(obj, "Value must be > 0");
return false;
}
return true;
@ -341,11 +368,11 @@ function isNonZeroOrEmpty(value) {
function validateDate(obj) {
$(obj).removeClass("red_border");
$(obj).next('span').remove();
removeErrorFor(obj);
if (!isValidDateOrEmpty($(obj).val())) {
$(obj).addClass("red_border");
insertSpanAfter(obj, "Incorrect date format");
insertErrorFor(obj, "Incorrect date format");
return false;
}
return true;
@ -364,19 +391,62 @@ function isValidDateOrEmpty(date) {
}
function validateFinishTime(obj) {
$(obj).removeClass("red_border");
$(obj).next('span').remove();
var startTime = parseValToNumber($(obj).prev().val());
var finishTime = parseValToNumber(obj.value);
if (startTime > finishTime) {
$(obj).addClass("red_border");
insertSpanAfter(obj, "Finish time must be after start");
var groupID = $(obj).data('time-group');
var startObj = $(".start_time[data-time-group='"+groupID+"']")[0];
var finishObj = $(".finish_time[data-time-group='"+groupID+"']")[0];
if ($(finishObj).hasClass("finish_time_error")) {
$(finishObj).removeClass("red_border finish_time_error");
removeErrorFor(finishObj);
}
//Check if finish time error (takes precedence over lunch break error)
var startTime = parseValToNumber(startObj.value);
var finishTime = parseValToNumber(finishObj.value);
if (startTime >= finishTime) {
$(finishObj).addClass("red_border finish_time_error");
removeErrorFor(finishObj);
insertErrorFor(finishObj, "Finish time must be after start");
return false;
}
return true;
}
function validateLunchBreak(lunchGroup) {
var lunchStartObj = $(".start_time[data-time-group='"+lunchGroup+"']")[0];
var lunchFinishObj = $(".finish_time[data-time-group='"+lunchGroup+"']")[0];
//Skip if finish time error present (it takes precedence over lunch break error)
if ($(lunchStartObj).hasClass("finish_time_error") || $(lunchFinishObj).hasClass("finish_time_error"))
return false;
removeErrorFor(lunchFinishObj);
var valid = validateLunchTime(lunchStartObj) & validateLunchTime(lunchFinishObj);
if (!valid) {
insertErrorFor(lunchFinishObj, "Lunch break must be within activity times");
}
return valid;
}
//Check if exposed/infected lunch time within exposed/infected presence times
function validateLunchTime(obj) {
var activityGroup = $(obj).data('lunch-for');
var activityStart = parseValToNumber($(".start_time[data-time-group='"+activityGroup+"']")[0].value);
var activityFinish = parseValToNumber($(".finish_time[data-time-group='"+activityGroup+"']")[0].value);
var time = parseValToNumber(obj.value);
$(obj).removeClass("red_border lunch_break_error");
if ((time < activityStart) || (time > activityFinish)) {
$(obj).addClass("red_border lunch_break_error");
return false;
}
return true;
}
function parseValToNumber(val) {
return parseInt(val.replace(':',''), 10);
}
@ -421,7 +491,12 @@ $(document).ready(function () {
//Validate all finish times
$("input[required].finish_time").each(function() {validateFinishTime(this)});
$(".finish_time").change(function() {validateFinishTime(this)});
$(".start_time").change(function() {validateFinishTime(this.nextSibling.nextSibling)});
$(".start_time").change(function() {validateFinishTime(this)});
//Validate lunch times
$(".start_time[data-lunch-for]").each(function() {validateLunchBreak($(this).data('time-group'))});
$("[data-lunch-for]").change(function() {validateLunchBreak($(this).data('time-group'))});
$("[data-lunch-break]").change(function() {validateLunchBreak($(this).data('lunch-break'))});
var radioValue = $("input[name='event_type']:checked");
if (radioValue.val()) {

View file

@ -134,11 +134,11 @@
<option value="training">Training</option>
<option value="gym">Gym</option>
</select><br>
Start: <input type="time" id="activity_start" class="start_time" name="activity_start" value="09:00" required> &nbsp;&nbsp;
Finish: <input type="time" id="activity_finish" class="finish_time" name="activity_finish" value="18:00" required><br>
Start: <input type="time" id="activity_start" class="start_time" data-time-group="activity" data-lunch-break="lunch_activity" name="activity_start" value="09:00" required> &nbsp;&nbsp;
Finish: <input type="time" id="activity_finish" class="finish_time" data-time-group="activity" data-lunch-break="lunch_activity" name="activity_finish" value="18:00" required><br>
Infected person(s) presence: <br>
Start: <input type="time" id="infected_start" class="start_time" name="infected_start" value="09:00"required> &nbsp;&nbsp;
Finish: <input type="time" id="infected_finish" class="finish_time" name="infected_finish" value="18:00" required><br>
Start: <input type="time" id="infected_start" class="start_time" data-time-group="infected" name="infected_start" value="09:00" required> &nbsp;&nbsp;
Finish: <input type="time" id="infected_finish" class="finish_time" data-time-group="infected" name="infected_finish" value="18:00" required><br>
<hr width="80%">
When is the event?
@ -167,9 +167,9 @@
</select><br>
<hr width="80%">
<div id="activity_breaks">
<span id="activity_breaks">
<b>Activity breaks:</b>
</div>
</span><br>
<!-- Lunch Options -->
Lunch break:&nbsp;&nbsp;
<input type="radio" id="lunch_option_no" name="lunch_option" value=0 onclick="require_fields(this)">
@ -178,8 +178,8 @@
<label for="lunch_option_yes">Yes</label><br>
<div id="DIVlunch_break">
Start: <input type="time" id="lunch_start" class="start_time" name="lunch_start" value="12:30" required> &nbsp;&nbsp;
Finish: <input type="time" id="lunch_finish" class="finish_time" name="lunch_finish" value="13:30" required><br>
Start: <input type="time" id="lunch_start" class="start_time" data-time-group="lunch_activity" data-lunch-for="activity" name="lunch_start" value="12:30" required> &nbsp;&nbsp;
Finish: <input type="time" id="lunch_finish" class="finish_time" data-time-group="lunch_activity" data-lunch-for="activity" name="lunch_finish" value="13:30" required><br>
</div>
<!-- Coffee Options -->

View file

@ -93,10 +93,11 @@
Gym = For comparison only, all persons doing heavy physical exercise, breathing and not talking.
{% endif %}
</p></li>
<li><p class="data_text">Presence of exposed occupant(s):</p></li>
<ul>
<li><p class="data_subtext">Start time: {{ form.activity_start | minutes_to_time }} &nbsp&nbsp End time: {{ form.activity_finish | minutes_to_time }}</p></li>
</ul>
<li><p class="data_text">Exposure time (presence of infected person):</p></li>
<li><p class="data_text">Presence of infected occupant(s):</p></li>
<ul>
<li><p class="data_subtext">Start time: {{ form.infected_start | minutes_to_time }} &nbsp&nbsp End time: {{ form.infected_finish | minutes_to_time }}</p></li>
</ul>