add simple countdown timer
This commit is contained in:
+30
-3
@@ -550,7 +550,12 @@ img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dialog-text {
|
.dialog-text {
|
||||||
margin-bottom: 3.2rem;
|
padding: .4rem 2.8rem;
|
||||||
|
/* margin-bottom: 3.2rem; */
|
||||||
|
}
|
||||||
|
|
||||||
|
#exam-time {
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-cancel {
|
.dialog-cancel {
|
||||||
@@ -570,6 +575,17 @@ img {
|
|||||||
background-color: #b71c1c !important;
|
background-color: #b71c1c !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-review {
|
||||||
|
border-radius: 5px 5px 5px 5px !important;
|
||||||
|
border-width: 0px !important;
|
||||||
|
margin: 1.6rem 1.6rem 1.6rem 0.8rem !important;
|
||||||
|
width: 19.2rem !important;
|
||||||
|
padding: 0.8rem !important;
|
||||||
|
background-color: #4527A0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Options overlay */
|
/* Options overlay */
|
||||||
|
|
||||||
.fullscreen-overlay {
|
.fullscreen-overlay {
|
||||||
@@ -769,8 +785,9 @@ select option:disabled {
|
|||||||
|
|
||||||
.save-button {
|
.save-button {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
padding-left: 10px;
|
margin-left: 10px;
|
||||||
color:#FFFFFF;
|
color:#FFFFFF;
|
||||||
|
border-bottom:2px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save-button a {
|
.save-button a {
|
||||||
@@ -778,7 +795,8 @@ select option:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.save-button:hover {
|
.save-button:hover {
|
||||||
color: blue;
|
color: #311B92;
|
||||||
|
border-bottom:2px solid #311B92;
|
||||||
}
|
}
|
||||||
|
|
||||||
.packet-button:hover{
|
.packet-button:hover{
|
||||||
@@ -794,6 +812,15 @@ select option:disabled {
|
|||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#timer {
|
||||||
|
position: relative;
|
||||||
|
top: 50%;
|
||||||
|
/* left: 50%; */
|
||||||
|
transform: translate(0, -20%);
|
||||||
|
/* color: #4527A0; */
|
||||||
|
opacity: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
.sk-cube-grid {
|
.sk-cube-grid {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
|
|||||||
+21
-2
@@ -23,6 +23,7 @@
|
|||||||
<button id="review-overlay-button" class="navigation nav-right">review</button>
|
<button id="review-overlay-button" class="navigation nav-right">review</button>
|
||||||
<!--<button id="logout-button" class="navigation nav-right">logout</button>-->
|
<!--<button id="logout-button" class="navigation nav-right">logout</button>-->
|
||||||
<div class="app-name nav-left">RTS</div>
|
<div class="app-name nav-left">RTS</div>
|
||||||
|
<div id="timer"></div>
|
||||||
<div class="exam-name"></div>
|
<div class="exam-name"></div>
|
||||||
<input type="button" class="navigation nav-left" value="previous" disabled="disabled">
|
<input type="button" class="navigation nav-left" value="previous" disabled="disabled">
|
||||||
<input type="button" class="navigation nav-left" value="next">
|
<input type="button" class="navigation nav-left" value="next">
|
||||||
@@ -92,12 +93,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="start-dialog" class="dialog modal">
|
||||||
|
<h3 class="dialog-title">Start exam</h3>
|
||||||
|
<div class="dialog-text">
|
||||||
|
Click to start exam.
|
||||||
|
<p>You will have <span id='exam-time'></span> minutes.</p>
|
||||||
|
</div>
|
||||||
|
<button id="start-packet-button" class="navigation dialog-yes">Start</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="time-up-dialog" class="dialog modal">
|
||||||
|
<h3 class="dialog-title">Time ended</h3>
|
||||||
|
<div class="dialog-text">
|
||||||
|
Allocated time has ended. You can review or continue.
|
||||||
|
</div>
|
||||||
|
<button id="time-up-review-button" class="navigation dialog-review">Review</button>
|
||||||
|
<button id="time-up-continue-button" class="navigation dialog-yes">Continue</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="login-dialog" class="dialog modal">
|
<div id="login-dialog" class="dialog modal">
|
||||||
<h3 class="dialog-title">Select exam</h3>
|
<h3 class="dialog-title">Select exam</h3>
|
||||||
Candidate number: <input type="text" id="candidate-number" name="candidate" required size="10">
|
|
||||||
<div class="dialog-text">
|
<div class="dialog-text">
|
||||||
<button id="start-exam-button" class="navigation dialog-yes">Start</button>
|
Candidate number: <input type="text" id="candidate-number" name="candidate" required size="10">
|
||||||
</div>
|
</div>
|
||||||
|
<button id="start-exam-button" class="navigation dialog-yes">Start</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loading" class="fullscreen-overlay">
|
<div id="loading" class="fullscreen-overlay">
|
||||||
|
|||||||
@@ -40,3 +40,55 @@ export function formatBytes(bytes, decimals = 2) {
|
|||||||
|
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function CountDownTimer(duration, granularity) {
|
||||||
|
this.duration = duration;
|
||||||
|
this.granularity = granularity || 1000;
|
||||||
|
this.tickFtns = [];
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CountDownTimer.prototype.start = function () {
|
||||||
|
if (this.running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.running = true;
|
||||||
|
var start = Date.now(),
|
||||||
|
that = this,
|
||||||
|
diff,
|
||||||
|
obj;
|
||||||
|
|
||||||
|
(function timer() {
|
||||||
|
diff = that.duration - (((Date.now() - start) / 1000) | 0);
|
||||||
|
|
||||||
|
if (diff > 0) {
|
||||||
|
setTimeout(timer, that.granularity);
|
||||||
|
} else {
|
||||||
|
diff = 0;
|
||||||
|
that.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = CountDownTimer.parse(diff);
|
||||||
|
that.tickFtns.forEach(function (ftn) {
|
||||||
|
ftn.call(this, obj.minutes, obj.seconds);
|
||||||
|
}, that);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
CountDownTimer.prototype.onTick = function (ftn) {
|
||||||
|
if (typeof ftn === 'function') {
|
||||||
|
this.tickFtns.push(ftn);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
CountDownTimer.prototype.expired = function () {
|
||||||
|
return !this.running;
|
||||||
|
};
|
||||||
|
|
||||||
|
CountDownTimer.parse = function (seconds) {
|
||||||
|
return {
|
||||||
|
'minutes': (seconds / 60) | 0,
|
||||||
|
seconds: seconds % 60 | 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
+49
-2
@@ -16,6 +16,7 @@ window.number_of_questions = null;
|
|||||||
window.question_type = null;
|
window.question_type = null;
|
||||||
window.loaded_question = null;
|
window.loaded_question = null;
|
||||||
window.review = false;
|
window.review = false;
|
||||||
|
window.exam_time = 60;
|
||||||
|
|
||||||
window.allow_self_marking = true;
|
window.allow_self_marking = true;
|
||||||
|
|
||||||
@@ -83,13 +84,14 @@ function loadPacketFromAjax(path) {
|
|||||||
// setUpPacket(data);
|
// setUpPacket(data);
|
||||||
// $("#options-panel").hide();
|
// $("#options-panel").hide();
|
||||||
// })
|
// })
|
||||||
|
$("#progress").html(`Requesting packet: ${path}`);
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: path,
|
url: path,
|
||||||
progress: function (e) {
|
progress: function (e) {
|
||||||
if (e.lengthComputable) {
|
if (e.lengthComputable) {
|
||||||
var completedPercentage = Math.round((e.loaded * 100) / e.total);
|
var completedPercentage = Math.round((e.loaded * 100) / e.total);
|
||||||
console.log(completedPercentage);
|
|
||||||
|
|
||||||
$("#progress").html(
|
$("#progress").html(
|
||||||
`${completedPercentage}%<br/>${helper.formatBytes(e.total)}`
|
`${completedPercentage}%<br/>${helper.formatBytes(e.total)}`
|
||||||
@@ -146,6 +148,19 @@ function setUpQuestions() {
|
|||||||
|
|
||||||
loadQuestion(0, 1, true);
|
loadQuestion(0, 1, true);
|
||||||
createQuestionListPanel();
|
createQuestionListPanel();
|
||||||
|
|
||||||
|
|
||||||
|
if (window.question_type == "rapid") {
|
||||||
|
window.exam_time = 35 * 60;
|
||||||
|
} else if (window.question_type == "anatomy"){
|
||||||
|
window.exam_time = 90 * 60;
|
||||||
|
} else if (window.question_type == "long"){
|
||||||
|
window.exam_time = 75 * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#exam-time").text(window.exam_time / 60)
|
||||||
|
|
||||||
|
$("#start-dialog").modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up cornerstone (the dicom viewer)
|
// Set up cornerstone (the dicom viewer)
|
||||||
@@ -1128,12 +1143,16 @@ $("#review-overlay-button").click(function (evt) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#finish-exam").click(function (evt) {
|
$("#finish-exam, #time-up-review-button").click(function (evt) {
|
||||||
window.review = true;
|
window.review = true;
|
||||||
reviewQuestions();
|
reviewQuestions();
|
||||||
$.modal.close();
|
$.modal.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#time-up-continue-button").click(function (evt) {
|
||||||
|
$.modal.close();
|
||||||
|
});
|
||||||
|
|
||||||
$("#finish-cancel").click(function (evt) {
|
$("#finish-cancel").click(function (evt) {
|
||||||
$.modal.close();
|
$.modal.close();
|
||||||
});
|
});
|
||||||
@@ -1663,6 +1682,34 @@ $("#start-exam-button").click(function (evt) {
|
|||||||
$.modal.close();
|
$.modal.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#start-packet-button").click(function (evt) {
|
||||||
|
//window.cid = parseInt($("#candidate-number").val());
|
||||||
|
// const t = 35 * 60;
|
||||||
|
|
||||||
|
//const t = 2;
|
||||||
|
let display = document.querySelector("#timer");
|
||||||
|
let timer = new helper.CountDownTimer(window.exam_time);
|
||||||
|
let timeObj = helper.CountDownTimer.parse(window.exam_time);
|
||||||
|
|
||||||
|
format(timeObj.minutes, timeObj.seconds);
|
||||||
|
|
||||||
|
timer.onTick(format);
|
||||||
|
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
function format(minutes, seconds) {
|
||||||
|
minutes = minutes < 10 ? "0" + minutes : minutes;
|
||||||
|
seconds = seconds < 10 ? "0" + seconds : seconds;
|
||||||
|
display.textContent = "Time left: " + minutes + ":" + seconds;
|
||||||
|
|
||||||
|
if (minutes == 0 && seconds == 0) {
|
||||||
|
$("#time-up-dialog").modal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.modal.close();
|
||||||
|
});
|
||||||
|
|
||||||
$("#btn-delete-databases").click(function (evt) {
|
$("#btn-delete-databases").click(function (evt) {
|
||||||
var r = confirm("This will delete ALL saved answers!");
|
var r = confirm("This will delete ALL saved answers!");
|
||||||
if (r == true) {
|
if (r == true) {
|
||||||
|
|||||||
Reference in New Issue
Block a user