Skip to content

Commit

Permalink
Merge pull request #982 from drgrice1/correct-answer-reveal
Browse files Browse the repository at this point in the history
Add an option to show the correct answer with a reveal button.
  • Loading branch information
pstaabp authored Feb 7, 2024
2 parents e0d0030 + 2bb06d4 commit cf2892b
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 15 deletions.
50 changes: 45 additions & 5 deletions htdocs/js/Feedback/feedback.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
(() => {
const feedbackPopovers = [];

const initializeFeedback = (feedbackBtn) => {
if (feedbackBtn.dataset.popoverInitialized) return;
feedbackBtn.dataset.popoverInitialized = 'true';

new bootstrap.Popover(feedbackBtn, { sanitize: false, container: feedbackBtn.parentElement });
const feedbackPopover = new bootstrap.Popover(feedbackBtn, {
sanitize: false,
container: feedbackBtn.parentElement
});
feedbackPopovers.push(feedbackPopover);

// Render MathJax previews.
if (window.MathJax) {
Expand All @@ -13,18 +19,52 @@
}

feedbackBtn.addEventListener('shown.bs.popover', () => {
const bsPopover = bootstrap.Popover.getInstance(feedbackBtn);

// Execute javascript in the answer preview.
bsPopover.tip?.querySelectorAll('script').forEach((origScript) => {
feedbackPopover.tip?.querySelectorAll('script').forEach((origScript) => {
const newScript = document.createElement('script');
Array.from(origScript.attributes).forEach((attr) => newScript.setAttribute(attr.name, attr.value));
newScript.appendChild(document.createTextNode(origScript.innerHTML));
origScript.parentNode.replaceChild(newScript, origScript);
setTimeout(() => feedbackPopover.update());
});

const moveToFront = () => {
if (feedbackPopover.tip) feedbackPopover.tip.style.zIndex = 18;
for (const popover of feedbackPopovers) {
if (popover === feedbackPopover) continue;
popover.tip?.style.setProperty('z-index', null);
}
};
feedbackPopover.tip?.addEventListener('click', moveToFront);
feedbackPopover.tip?.addEventListener('focusin', moveToFront);
moveToFront();

// Make a click on the popover header close the popover.
bsPopover.tip?.querySelector('.popover-header')?.addEventListener('click', () => bsPopover?.hide());
feedbackPopover.tip
?.querySelector('.popover-header')
?.addEventListener('click', () => feedbackPopover.hide());

const revealCorrectBtn = feedbackPopover.tip?.querySelector('.reveal-correct-btn');
if (revealCorrectBtn && feedbackPopover.correctRevealed) {
revealCorrectBtn.nextElementSibling?.classList.remove('d-none');
revealCorrectBtn.remove();
} else {
revealCorrectBtn?.addEventListener('click', () => {
feedbackPopover.correctRevealed = true;
revealCorrectBtn.classList.add('fade-out');
revealCorrectBtn.parentElement.classList.add('resize-transition');
revealCorrectBtn.parentElement.style.maxWidth = `${revealCorrectBtn.parentElement.offsetWidth}px`;
revealCorrectBtn.parentElement.style.maxHeight = `${revealCorrectBtn.parentElement.offsetHeight}px`;
revealCorrectBtn.addEventListener('animationend', () => {
revealCorrectBtn.nextElementSibling?.classList.remove('d-none');
revealCorrectBtn.nextElementSibling?.classList.add('fade-in');
revealCorrectBtn.parentElement.style.maxWidth = '1000px';
revealCorrectBtn.parentElement.style.maxHeight = '1000px';
revealCorrectBtn.remove();
feedbackPopover.update();
});
});
}
});
};

Expand Down
1 change: 1 addition & 0 deletions htdocs/js/GraphTool/graphtool.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ window.graphTool = (containerId, options) => {
const gt = {};

gt.graphContainer = document.getElementById(containerId);
if (!gt.graphContainer) return;
if (gt.graphContainer.offsetWidth === 0) {
setTimeout(() => window.graphTool(containerId, options), 100);
return;
Expand Down
35 changes: 34 additions & 1 deletion htdocs/js/Problem/problem.scss
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@
--bs-popover-body-padding-x: 0;
--bs-popover-body-padding-y: 0;
--bs-popover-max-width: 600px;
--bs-popover-zindex: 18;
--bs-popover-zindex: 17;
position: absolute;
min-width: 200px;

Expand Down Expand Up @@ -288,6 +288,39 @@
border-bottom-right-radius: var(--bs-card-inner-border-radius);
}
}

&.resize-transition {
overflow: clip;
transition: max-height 1s ease-in, max-width 1s ease-in;
}

.fade-out {
animation: fade-out 0.25s ease-in;

@keyframes fade-out {
0% {
opacity: 1;
}

100% {
opacity: 0;
}
}
}

.fade-in {
animation: fade-in 0.5s ease-in;

@keyframes fade-in {
0% {
opacity: 0;
}

100% {
opacity: 1;
}
}
}
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions lib/WeBWorK/PG.pm
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,12 @@ The summary will also be generated if this is true.
Determines if any messages generated in answer evaluation will be shown.
=item showCorrectAnswers (boolean, default: 0)
=item showCorrectAnswers (numeric, default: 0)
Determines if correct answers will be shown.
Determines if correct answers will be shown. If 0, then correct answers are not
shown. If set to 1, then correct answers are shown but hidden, and a "Reveal"
button is shown at first. If that button is clicked, then the answer is shown.
If set to 2, then correct answers are shown immediately.
=item answerPrefix (string, default: '')
Expand Down
31 changes: 24 additions & 7 deletions macros/PG.pl
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,10 @@ =head2 ENDDOCUMENT
=item *
C<showCorrect>: This is a boolean value that is 1 by default. If this is true
and the translator option C<showCorrectAnswers> is also true, then a preview of
the correct answer is shown in the feedback popover.
and the translator option C<showCorrectAnswers> is nonzero, then a preview of
the correct answer is shown in the feedback popover. In other words, this option
prevents showing correct answers even if the frontend requests that correct
answers be shown.
=item *
Expand Down Expand Up @@ -1230,14 +1232,29 @@ sub ENDDOCUMENT {
)
. (
$rh_envir->{showCorrectAnswers} && $options{showCorrect}
? feedbackLine(
maketext('Correct Answer'),
previewAnswer(
? do {
my $correctAnswer = previewAnswer(
$ansHash->{correct_ans_latex_string},
$options{wrapPreviewInTex},
$ansHash->{correct_ans}
)
)
);
feedbackLine(
maketext('Correct Answer'),
$rh_envir->{showCorrectAnswers} > 1
? $correctAnswer
: Mojo::DOM->new_tag(
'button',
type => 'button',
class => 'reveal-correct-btn btn btn-secondary btn-sm',
maketext('Reveal')
)
. Mojo::DOM->new_tag(
'div',
class => 'd-none',
sub {$correctAnswer}
)
);
}
: ''
);
}
Expand Down

0 comments on commit cf2892b

Please sign in to comment.