Skip to content

Commit 499a44c

Browse files
authored
Merge pull request #2819 from drgrice1/test-confirm-unanswered
Add a message to the grade test confirmation dialog when questions are unanswered.
2 parents 1677706 + 0ae7331 commit 499a44c

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

htdocs/js/GatewayQuiz/gateway.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,41 @@
188188

189189
if (actuallySubmit) return;
190190

191+
const inputs = Array.from(document.querySelectorAll('input, select'));
192+
193+
// All problem numbers are represented by a probstatus hidden input. Use those to determine the problem
194+
// numbers of problems in the test. Note that problem numbering displayed on the page will not match these
195+
// numbers in the cases that the test definition has non-consecutive numbering or that problem order is
196+
// randomized. But the problem numbering will always match the quiz prefix numbering.
197+
const problems = [];
198+
for (const input of inputs.filter((i) => /^probstatus\d*/.test(i.name))) {
199+
problems[parseInt(input.name.replace('probstatus', ''))] = {};
200+
}
201+
202+
// Determine which questions have been answered. Note that there can be multiple inputs for a
203+
// given question (for example for checkbox or radio answers).
204+
for (const input of inputs.filter(
205+
(i) => /Q\d{4}_/.test(i.name) && !/^MaThQuIlL_/.test(i.name) && !/^previous_/.test(i.name)
206+
)) {
207+
const answered =
208+
input.type === 'radio' || input.type === 'checkbox' ? !!input.checked : /\S/.test(input.value);
209+
const match = /Q(\d{4})_/.exec(input.name);
210+
const problemNumber = parseInt(match?.[1] ?? '0');
211+
if (!(input.name in problems[problemNumber])) problems[problemNumber][input.name] = answered;
212+
else if (answered) problems[problemNumber][input.name] = 1;
213+
}
214+
215+
// Determine if there are any unanswered questions in each problem.
216+
let numProblemsWithUnanswered = 0;
217+
for (const problem of problems) {
218+
// Skip problem 0 and any problems that don't exist in the test
219+
// due to non-consecutive numbering in the test definition.
220+
if (!problem) continue;
221+
222+
if (!Object.keys(problem).length || !Object.values(problem).every((answered) => answered))
223+
++numProblemsWithUnanswered;
224+
}
225+
191226
// Prevent the gwquiz form from being submitted until after confirmation.
192227
evt.preventDefault();
193228

@@ -219,8 +254,25 @@
219254

220255
const modalBody = document.createElement('div');
221256
modalBody.classList.add('modal-body');
222-
const modalBodyContent = document.createElement('div');
223257

258+
if (numProblemsWithUnanswered) {
259+
const modalSecondaryContent = document.createElement('div');
260+
modalSecondaryContent.classList.add('mb-3');
261+
modalSecondaryContent.textContent =
262+
(numProblemsWithUnanswered > 1
263+
? submitAnswers.dataset.unansweredQuestionsMessage
264+
? submitAnswers.dataset.unansweredQuestionsMessage.replace('%d', numProblemsWithUnanswered)
265+
: `There are ${numProblemsWithUnanswered} problems with unanswered questions.`
266+
: (submitAnswers.dataset.unansweredQuestionMessage ??
267+
'There is a problem with unanswered questions.')) +
268+
' ' +
269+
(submitAnswers.dataset.returnToTestMessage ??
270+
'Are you sure you want to grade the test? ' +
271+
'Select "No" if you would like to return to the test to enter more answers.');
272+
modalBody.append(modalSecondaryContent);
273+
}
274+
275+
const modalBodyContent = document.createElement('div');
224276
modalBodyContent.textContent = submitAnswers.dataset.confirmDialogMessage;
225277
modalBody.append(modalBodyContent);
226278

templates/ContentGenerator/GatewayQuiz.html.ep

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,15 @@
718718
: maketext(
719719
'This is your only submission. If you say yes, then your answers will be final, '
720720
. 'and you will not be able to continue to work this test version.'
721+
),
722+
# This is always a plural form. JavaScript replaces %d with the
723+
# number of unanswered questions which will be greater than one.
724+
unanswered_questions_message =>
725+
maketext('There are [_1] problems with unanswered questions.', '%d'),
726+
unanswered_question_message => maketext('There is a problem with unanswered questions.'),
727+
return_to_test_message => maketext(
728+
'Are you sure you want to grade the test? '
729+
. 'Select "No" if you would like to return to the test to enter more answers.'
721730
)
722731
}
723732
)

0 commit comments

Comments
 (0)