Skip to content

Commit

Permalink
Add a "Show Correct Answers" button to the problem and test pages.
Browse files Browse the repository at this point in the history
When this button is used correct answers will be shown with no other
content in the feedback popover, scaffolds will all be open, and the
feedback popovers will open immediately on page load. This is an
instructor only option for now.  I don't think this will be a good idea
to enable for students.

Furthermore, the "Show Correct Answers" buttons on other instructor
pages (pg problem editor, problem library, set detail page, statistics,
and manual problem grader) now use this for showing correct answers.

This works well for most problems, but there are some cases where
answers are tightly grouped particularly when there are on the same line
that the popovers can overlap in not the best way.

This is one potential resolution of openwebwork/pg#1047.
  • Loading branch information
drgrice1 committed Apr 23, 2024
1 parent 85da32b commit d77064e
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 104 deletions.
3 changes: 2 additions & 1 deletion htdocs/js/PGProblemEditor/pgproblemeditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@
processAnswers: 0,
showPreviewButton: isProblem,
showCheckAnswersButton: isProblem,
showCorrectAnswersButton: isProblem,
showCorrectAnswersButton: 0,
showCorrectAnswersOnlyButton: isProblem,
showFooter: 0,
displayMode: document.getElementById('action_view_displayMode_id')?.value ?? 'MathJax',
language: document.querySelector('input[name="hidden_language"]')?.value ?? 'en',
Expand Down
1 change: 1 addition & 0 deletions htdocs/js/RenderProblem/renderproblem.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
showAnswerNumbers: 0,
showHints: 1,
showSolutions: 1,
showCorrectAnswersOnlyButton: 1,
isInstructor: 1,
forceScaffoldsOpen: 1,
noprepostambles: 1,
Expand Down
91 changes: 46 additions & 45 deletions lib/FormatRenderedProblem.pm
Original file line number Diff line number Diff line change
Expand Up @@ -235,51 +235,52 @@ sub formatRenderedProblem {
my %template_params = (
template => $formatName eq 'ptx' ? 'RPCRenderFormats/ptx' : 'RPCRenderFormats/default',
$formatName eq 'json' ? (format => 'json') : (),
formatName => $formatName,
ws => $ws,
ce => $ce,
lh => $lh,
rh_result => $rh_result,
SITE_URL => $SITE_URL,
FORM_ACTION_URL => $SITE_URL . $ws->c->webwork_url . '/' . $ws->c->current_route,
COURSE_LANG_AND_DIR => get_lang_and_dir($formLanguage),
theme => $ws->{inputs_ref}{theme} || $ce->{defaultTheme},
courseID => $ws->{inputs_ref}{courseID} // '',
user => $ws->{inputs_ref}{user} // '',
passwd => $ws->{inputs_ref}{passwd} // '',
disableCookies => $ws->{inputs_ref}{disableCookies} // '',
key => $ws->authen->{session_key},
PROBLEM_LANG_AND_DIR => $PROBLEM_LANG_AND_DIR,
problemSeed => $rh_result->{problem_seed} // $ws->{inputs_ref}{problemSeed} // 6666,
psvn => $rh_result->{psvn} // $ws->{inputs_ref}{psvn} // 54321,
problemUUID => $problemUUID,
displayMode => $displayMode,
third_party_css => \@third_party_css,
extra_css_files => \@extra_css_files,
third_party_js => \@third_party_js,
extra_js_files => \@extra_js_files,
problemText => $problemText,
extra_header_text => $ws->{inputs_ref}{extra_header_text} // '',
resultSummary => $resultSummary,
showScoreSummary => $submitMode && !$renderErrorOccurred && $problemResult,
answerhashXML => $answerhashXML,
LTIGradeMessage => $LTIGradeMessage,
sourceFilePath => $ws->{inputs_ref}{sourceFilePath} // '',
problemSource => $ws->{inputs_ref}{problemSource} // '',
rawProblemSource => $ws->{inputs_ref}{rawProblemSource} // '',
uriEncodedProblemSource => $ws->{inputs_ref}{uriEncodedProblemSource} // '',
fileName => $ws->{inputs_ref}{fileName} // '',
formLanguage => $formLanguage,
isInstructor => $ws->{inputs_ref}{isInstructor} // '',
forceScaffoldsOpen => $ws->{inputs_ref}{forceScaffoldsOpen} // '',
showSummary => $showSummary,
showHints => $ws->{inputs_ref}{showHints} // '',
showSolutions => $ws->{inputs_ref}{showSolutions} // '',
showPreviewButton => $ws->{inputs_ref}{showPreviewButton} // '',
showCheckAnswersButton => $ws->{inputs_ref}{showCheckAnswersButton} // '',
showCorrectAnswersButton => $ws->{inputs_ref}{showCorrectAnswersButton} // '',
showFooter => $ws->{inputs_ref}{showFooter} // '',
pretty_print => \&pretty_print
formatName => $formatName,
ws => $ws,
ce => $ce,
lh => $lh,
rh_result => $rh_result,
SITE_URL => $SITE_URL,
FORM_ACTION_URL => $SITE_URL . $ws->c->webwork_url . '/' . $ws->c->current_route,
COURSE_LANG_AND_DIR => get_lang_and_dir($formLanguage),
theme => $ws->{inputs_ref}{theme} || $ce->{defaultTheme},
courseID => $ws->{inputs_ref}{courseID} // '',
user => $ws->{inputs_ref}{user} // '',
passwd => $ws->{inputs_ref}{passwd} // '',
disableCookies => $ws->{inputs_ref}{disableCookies} // '',
key => $ws->authen->{session_key},
PROBLEM_LANG_AND_DIR => $PROBLEM_LANG_AND_DIR,
problemSeed => $rh_result->{problem_seed} // $ws->{inputs_ref}{problemSeed} // 6666,
psvn => $rh_result->{psvn} // $ws->{inputs_ref}{psvn} // 54321,
problemUUID => $problemUUID,
displayMode => $displayMode,
third_party_css => \@third_party_css,
extra_css_files => \@extra_css_files,
third_party_js => \@third_party_js,
extra_js_files => \@extra_js_files,
problemText => $problemText,
extra_header_text => $ws->{inputs_ref}{extra_header_text} // '',
resultSummary => $resultSummary,
showScoreSummary => $submitMode && !$renderErrorOccurred && $problemResult,
answerhashXML => $answerhashXML,
LTIGradeMessage => $LTIGradeMessage,
sourceFilePath => $ws->{inputs_ref}{sourceFilePath} // '',
problemSource => $ws->{inputs_ref}{problemSource} // '',
rawProblemSource => $ws->{inputs_ref}{rawProblemSource} // '',
uriEncodedProblemSource => $ws->{inputs_ref}{uriEncodedProblemSource} // '',
fileName => $ws->{inputs_ref}{fileName} // '',
formLanguage => $formLanguage,
isInstructor => $ws->{inputs_ref}{isInstructor} // '',
forceScaffoldsOpen => $ws->{inputs_ref}{forceScaffoldsOpen} // '',
showSummary => $showSummary,
showHints => $ws->{inputs_ref}{showHints} // '',
showSolutions => $ws->{inputs_ref}{showSolutions} // '',
showPreviewButton => $ws->{inputs_ref}{showPreviewButton} // '',
showCheckAnswersButton => $ws->{inputs_ref}{showCheckAnswersButton} // '',
showCorrectAnswersButton => $ws->{inputs_ref}{showCorrectAnswersButton} // '',
showCorrectAnswersOnlyButton => $ws->{inputs_ref}{showCorrectAnswersOnlyButton} // 0,
showFooter => $ws->{inputs_ref}{showFooter} // '',
pretty_print => \&pretty_print
);

return $ws->c->render(%template_params) if $formatName eq 'json' || !$ws->{inputs_ref}{send_pg_flags};
Expand Down
13 changes: 8 additions & 5 deletions lib/WeBWorK/ContentGenerator/GatewayQuiz.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,8 @@ async sub getProblemHTML ($c, $effectiveUser, $set, $formFields, $mergedProblem)
&& $c->{can}{showProblemScores}
&& $mergedProblem->num_correct + $mergedProblem->num_incorrect > 0;

my $showOnlyCorrectAnswers = $c->param('showCorrectAnswers') && $c->{will}{showCorrectAnswers};

my $pg = await renderPG(
$c,
$effectiveUser,
Expand All @@ -1465,14 +1467,15 @@ async sub getProblemHTML ($c, $effectiveUser, $set, $formFields, $mergedProblem)
|| $c->{previewAnswers}
|| $c->{will}{checkAnswers}
|| $showReturningFeedback,
showAttemptAnswers => $c->ce->{pg}{options}{showEvaluatedAnswers},
showAttemptPreviews => 1,
showAttemptResults => !$c->{previewAnswers} && $c->{can}{showProblemScores},
forceShowAttemptResults => $c->{will}{showProblemGrader}
showAttemptAnswers => $showOnlyCorrectAnswers ? 0 : $c->ce->{pg}{options}{showEvaluatedAnswers},
showAttemptPreviews => !$showOnlyCorrectAnswers,
showAttemptResults => !$showOnlyCorrectAnswers && !$c->{previewAnswers} && $c->{can}{showProblemScores},
forceShowAttemptResults => $showOnlyCorrectAnswers
|| $c->{will}{showProblemGrader}
|| ($c->ce->{pg}{options}{automaticAnswerFeedback}
&& !$c->{previewAnswers}
&& $c->can_showCorrectAnswersForAll($set, $c->{problem}, $c->{tmplSet})),
showMessages => 1,
showMessages => !$showOnlyCorrectAnswers,
showCorrectAnswers => (
$c->{will}{showProblemGrader} ? 2
: !$c->{previewAnswers} && $c->can_showCorrectAnswersForAll($set, $c->{problem}, $c->{tmplSet})
Expand Down
22 changes: 17 additions & 5 deletions lib/WeBWorK/ContentGenerator/Problem.pm
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,8 @@ async sub pre_header_initialize ($c) {
}
}

my $showOnlyCorrectAnswers = $c->param('showCorrectAnswers') && $will{showCorrectAnswers};

# Translation
debug('begin pg processing');
my $pg = await renderPG(
Expand All @@ -589,18 +591,19 @@ async sub pre_header_initialize ($c) {
effectivePermissionLevel => $db->getPermissionLevel($effectiveUserID)->permission,
useMathQuill => $will{useMathQuill},
useMathView => $will{useMathView},
forceScaffoldsOpen => 0,
forceScaffoldsOpen => $showOnlyCorrectAnswers,
isInstructor => $authz->hasPermissions($userID, 'view_answers'),
showFeedback => $c->{submitAnswers} || $c->{previewAnswers} || $showReturningFeedback,
showAttemptAnswers => $ce->{pg}{options}{showEvaluatedAnswers},
showAttemptPreviews => 1,
showAttemptAnswers => $showOnlyCorrectAnswers ? 0 : $ce->{pg}{options}{showEvaluatedAnswers},
showAttemptPreviews => !$showOnlyCorrectAnswers,
showAttemptResults => $c->{submitAnswers} || $showReturningFeedback,
forceShowAttemptResults => $will{checkAnswers}
forceShowAttemptResults => $showOnlyCorrectAnswers
|| $will{checkAnswers}
|| $will{showProblemGrader}
|| ($ce->{pg}{options}{automaticAnswerFeedback}
&& !$c->{previewAnswers}
&& after($c->{set}->answer_date, $c->submitTime)),
showMessages => 1,
showMessages => !$showOnlyCorrectAnswers,
showCorrectAnswers => (
$will{showProblemGrader} || ($c->{submitAnswers} && $c->{showCorrectOnRandomize}) ? 2
: !$c->{previewAnswers} && after($c->{set}->answer_date, $c->submitTime)
Expand Down Expand Up @@ -1470,6 +1473,15 @@ sub output_summary ($c) {
),
$c->attemptResults($pg)
);
} elsif ($c->param('showCorrectAnswers') && $will{showCorrectAnswers}) {
push(
@$output,
$c->tag(
'div',
class => 'alert alert-danger d-inline-block mb-2 p-1',
$c->maketext('CORRECT ANSWERS SHOWN ONLY -- ANSWERS NOT RECORDED')
),
);
} elsif ($c->{previewAnswers}) {
push(
@$output,
Expand Down
40 changes: 30 additions & 10 deletions lib/WeBWorK/ContentGenerator/ShowMeAnother.pm
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ async sub pre_header_initialize ($c) {

my %SMAoptions = map { $_ => 1 } @{ $ce->{pg}{options}{showMeAnother} };
my %showMeAnother = (
active => !($checkAnswers or $previewAnswers)
active => !($checkAnswers || $previewAnswers || $c->param('showCorrectAnswers'))
&& $ce->{pg}{options}{enableShowMeAnother}
&& ($problem->{showMeAnother} > -1 || $problem->{showMeAnother} == -2),
CheckAnswers => $checkAnswers
Expand Down Expand Up @@ -131,6 +131,7 @@ async sub pre_header_initialize ($c) {
displayMode => 'plainText',
showHints => 0,
showSolutions => 0,
forceScaffoldsOpen => 1,
refreshMath2img => 0,
processAnswers => 1,
permissionLevel => $db->getPermissionLevel($userName)->permission,
Expand Down Expand Up @@ -167,6 +168,7 @@ async sub pre_header_initialize ($c) {
displayMode => 'plainText',
showHints => 0,
showSolutions => 0,
forceScaffoldsOpen => 1,
refreshMath2img => 0,
processAnswers => 1,
permissionLevel => $db->getPermissionLevel($userName)->permission,
Expand Down Expand Up @@ -210,7 +212,7 @@ async sub pre_header_initialize ($c) {
}
}

} elsif (($showMeAnother{CheckAnswers} or $showMeAnother{Preview})
} elsif (($showMeAnother{CheckAnswers} || $showMeAnother{Preview} || $c->param('showCorrectAnswers'))
&& defined($problemSeed)
&& $problemSeed != $problem->problem_seed)
{
Expand All @@ -228,6 +230,7 @@ async sub pre_header_initialize ($c) {
displayMode => 'plainText',
showHints => 0,
showSolutions => 0,
forceScaffoldsOpen => 1,
refreshMath2img => 0,
processAnswers => 1,
permissionLevel => $db->getPermissionLevel($userName)->permission,
Expand All @@ -250,7 +253,16 @@ async sub pre_header_initialize ($c) {
}

# if showMeAnother is active, then disable all other options
if (($showMeAnother{active} || $showMeAnother{CheckAnswers} || $showMeAnother{Preview}) && $can->{showMeAnother}) {
if (
(
$showMeAnother{active}
|| $showMeAnother{CheckAnswers}
|| $showMeAnother{Preview}
|| $c->param('showCorrectAnswers')
)
&& $can->{showMeAnother}
)
{
$can->{recordAnswers} = 0;
$can->{checkAnswers} = 0; # turned on if showMeAnother conditions met below
$can->{getSubmitButton} = 0;
Expand All @@ -275,6 +287,8 @@ async sub pre_header_initialize ($c) {
my $will = $c->{will};
$will->{$_} = $can->{$_} && $want->{$_} for keys %$can;

my $showOnlyCorrectAnswers = $c->param('showCorrectAnswers') && $will->{showCorrectAnswers};

# PG problem translation
# Unfortunately we have to do this over because we potentially picked a new problem seed.

Expand All @@ -295,15 +309,17 @@ async sub pre_header_initialize ($c) {
effectivePermissionLevel => $db->getPermissionLevel($effectiveUserName)->permission,
useMathQuill => $will->{useMathQuill},
useMathView => $will->{useMathView},
forceScaffoldsOpen => 0,
forceScaffoldsOpen => $showOnlyCorrectAnswers,
isInstructor => $authz->hasPermissions($userName, 'view_answers'),
showFeedback => $c->{checkAnswers} || $c->{previewAnswers},
showAttemptAnswers => $ce->{pg}{options}{showEvaluatedAnswers},
showAttemptPreviews => 1,
showAttemptAnswers => $showOnlyCorrectAnswers ? 0 : $ce->{pg}{options}{showEvaluatedAnswers},
showAttemptPreviews => !$showOnlyCorrectAnswers,
showAttemptResults => $c->{checkAnswers},
showMessages => 1,
showCorrectAnswers => $will->{checkAnswers} && $will->{showCorrectAnswers} ? 1 : 0,
debuggingOptions => getTranslatorDebuggingOptions($authz, $userName)
forceShowAttemptResults => $showOnlyCorrectAnswers,
showMessages => !$showOnlyCorrectAnswers,
showCorrectAnswers => $showOnlyCorrectAnswers
|| ($will->{checkAnswers} && $will->{showCorrectAnswers}) ? 1 : 0,
debuggingOptions => getTranslatorDebuggingOptions($authz, $userName)
}
);

Expand Down Expand Up @@ -585,7 +601,11 @@ sub output_grader ($c) {
sub output_hidden_info ($c) {
# Hidden field for clicking Preview Answers and Check Answers from a Show Me Another screen.
# It needs to send the seed from showMeAnother back to the screen.
if ($c->{showMeAnother}{active} || $c->{showMeAnother}{CheckAnswers} || $c->{showMeAnother}{Preview}) {
if ($c->{showMeAnother}{active}
|| $c->{showMeAnother}{CheckAnswers}
|| $c->{showMeAnother}{Preview}
|| $c->param('showCorrectAnswers'))
{
return $c->c(
$c->hidden_field(showMeAnotherCheckAnswers => 1, id => 'showMeAnotherCheckAnswers_id'),
# Output the problem seed from ShowMeAnother so that it can be used in Check Answers.
Expand Down
32 changes: 22 additions & 10 deletions lib/WebworkWebservice/RenderProblem.pm
Original file line number Diff line number Diff line change
Expand Up @@ -222,19 +222,31 @@ async sub renderProblem {
effectivePermissionLevel => $rh->{effectivePermissionLevel} || $rh->{permissionLevel} || 0,
useMathQuill => $ce->{pg}{specialPGEnvironmentVars}{entryAssist} eq 'MathQuill',
useMathView => $ce->{pg}{specialPGEnvironmentVars}{entryAssist} eq 'MathView',
isInstructor => $rh->{isInstructor} // 0,
forceScaffoldsOpen => $rh->{forceScaffoldsOpen} // 0,
isInstructor => $rh->{isInstructor} // 0,
forceScaffoldsOpen => $rh->{WWcorrectAnsOnly} ? 1 : ($rh->{forceScaffoldsOpen} // 0),
QUIZ_PREFIX => $rh->{answerPrefix},
showFeedback => $rh->{previewAnswers} || $rh->{WWsubmit} || $rh->{WWcorrectAns},
showAttemptAnswers => $rh->{showAttemptAnswers} // 1,
showAttemptPreviews => $rh->{showAttemptPreviews}
// ($rh->{previewAnswers} || $rh->{WWsubmit} || $rh->{WWcorrectAns}),
showAttemptAnswers => $rh->{WWcorrectAnsOnly} ? 0 : ($rh->{showAttemptAnswers} // 1),
showAttemptPreviews => (
$rh->{WWcorrectAnsOnly} ? 0
: ($rh->{showAttemptPreviews} // ($rh->{previewAnswers} || $rh->{WWsubmit} || $rh->{WWcorrectAns}))
),
showAttemptResults => $rh->{showAttemptResults} // ($rh->{WWsubmit} || $rh->{WWcorrectAns}),
forceShowAttemptResults => $rh->{forceShowAttemptResults} || ($rh->{isInstructor}
&& ($rh->{showAttemptResults} // ($rh->{WWsubmit} || $rh->{WWcorrectAns}))),
showMessages => $rh->{showMessages} // ($rh->{previewAsnwers} || $rh->{WWsubmit} || $rh->{WWcorrectAns}),
showCorrectAnswers => $rh->{showCorrectAnswers} // ($rh->{WWcorrectAns} ? 2 : 0),
debuggingOptions => {
forceShowAttemptResults => (
$rh->{WWcorrectAnsOnly} ? 1
: (
$rh->{forceShowAttemptResults}
|| ($rh->{isInstructor}
&& ($rh->{showAttemptResults} // ($rh->{WWsubmit} || $rh->{WWcorrectAns})))
)
),
showMessages => (
$rh->{WWcorrectAnsOnly} ? 0
: ($rh->{showMessages} // ($rh->{previewAsnwers} || $rh->{WWsubmit} || $rh->{WWcorrectAns}))
),
showCorrectAnswers =>
($rh->{WWcorrectAnsOnly} ? 1 : ($rh->{showCorrectAnswers} // ($rh->{WWcorrectAns} ? 2 : 0))),
debuggingOptions => {
show_resource_info => $rh->{show_resource_info} // 0,
view_problem_debugging_info => $rh->{view_problem_debugging_info} // 0,
show_pg_info => $rh->{show_pg_info} // 0,
Expand Down
12 changes: 10 additions & 2 deletions templates/ContentGenerator/GatewayQuiz.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -499,11 +499,15 @@
%
% if ($c->{submitAnswers}) {
% if ($c->{scoreRecordedMessage}[ $probOrder->[$i] ] ne 'recorded') {
% $recordMessage = tag('div', class => 'alert alert-dangeer d-inline-block mb-2 p-1',
% $recordMessage = tag('div', class => 'alert alert-danger d-inline-block mb-2 p-1',
% maketext('ANSWERS NOT RECORDED -- [_1]', $c->{scoreRecordedMessage}[ $probOrder->[$i] ])
% );
% }
% $resultsTable = $c->attemptResults($pg);
% } elsif (param('showCorrectAnswers') && $c->{will}{showCorrectAnswers}) {
% $recordMessage = tag('div', class => 'alert alert-danger d-inline-block mb-2 p-1',
% maketext('CORRECT ANSWERS SHOWN ONLY -- ANSWERS NOT RECORDED')
% );
% } elsif ($c->{will}{checkAnswers} || $c->{will}{showProblemGrader}) {
% $recordMessage = tag('div', class => 'alert alert-danger d-inline-block mb-2 p-1',
% maketext('ANSWERS ONLY CHECKED -- ANSWERS NOT RECORDED')
Expand Down Expand Up @@ -679,7 +683,11 @@
% }
%
% if ($c->{can}{showProblemGrader}) {
<div class="col-12 my-2">
<div class="submit-buttons-container col-12 my-2">
% if ($c->{can}{showCorrectAnswers}) {
<%= submit_button maketext('Show Correct Answers'), name => 'showCorrectAnswers',
class => 'btn btn-primary mb-1' =%>
% }
% if ($c->{will}{showProblemGrader}) {
<%= submit_button maketext('Hide Problem Graders'), name => 'hideProblemGrader',
class => 'btn btn-primary mb-1' =%>
Expand Down
4 changes: 4 additions & 0 deletions templates/ContentGenerator/Problem/instructor_buttons.html.ep
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
% last unless $authz->hasPermissions(param('user'), 'access_instructor_tools');
%
<div class="submit-buttons-container col-12 my-2">
% if ($c->{can}{showCorrectAnswers}) {
<%= submit_button maketext('Show Correct Answers'), name => 'showCorrectAnswers',
class => 'btn btn-primary mb-1' =%>
% }
% if ($c->{can}{showProblemGrader} && !$c->{will}{showMeAnother}) {
% if ($c->{will}{showProblemGrader}) {
<%= submit_button maketext('Hide Problem Grader'), name => 'hideProblemGrader',
Expand Down

0 comments on commit d77064e

Please sign in to comment.