Skip to content

Commit cfdc61c

Browse files
committed
Feedback button changes.
This changes the feedback buttons in two ways. 1) Use copies of the bootstrap classes to color buttons. This way the feedback colors don't get changed by theming on the client side. The themes can still modify the actual classes used to change the buttons if desired, but the feedback buttons themselves can be themed independently of other bootstrap buttons. 2) Create a new feedback class "unknown" to use when showing the results of a problem with `$showPartialCorrectAnswers=0`. Currently on problems with limited feedback, it can be unclear to the student that they actually submitted the answer vs previewed the answer. This is accomplished by marking the buttons as incorrect if no answer is correct (0% on the problem), and marking them as "unknown" which shows a yellow button with a question mark in a circle if the problem is partially correct.
1 parent c1f68bf commit cfdc61c

3 files changed

Lines changed: 104 additions & 13 deletions

File tree

htdocs/js/Problem/problem.scss

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@
153153
&.partially-correct::before {
154154
content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='black' stroke='none'><path d='M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.146.146 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.163.163 0 0 1-.054.06.116.116 0 0 1-.066.017H1.146a.115.115 0 0 1-.066-.017.163.163 0 0 1-.054-.06.176.176 0 0 1 .002-.183L7.884 2.073a.147.147 0 0 1 .054-.057zm1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z'/><path d='M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995z'/></svg>");
155155
}
156+
157+
&.unknown::before {
158+
content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 640'><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d='M528 320C528 205.1 434.9 112 320 112C205.1 112 112 205.1 112 320C112 434.9 205.1 528 320 528C434.9 528 528 434.9 528 320zM64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320zM320 240C302.3 240 288 254.3 288 272C288 285.3 277.3 296 264 296C250.7 296 240 285.3 240 272C240 227.8 275.8 192 320 192C364.2 192 400 227.8 400 272C400 319.2 364 339.2 344 346.5L344 350.3C344 363.6 333.3 374.3 320 374.3C306.7 374.3 296 363.6 296 350.3L296 342.2C296 321.7 310.8 307 326.1 302C332.5 299.9 339.3 296.5 344.3 291.7C348.6 287.5 352 281.7 352 272.1C352 254.4 337.7 240.1 320 240.1zM288 432C288 414.3 302.3 400 320 400C337.7 400 352 414.3 352 432C352 449.7 337.7 464 320 464C302.3 464 288 449.7 288 432z'/></svg>");
159+
}
156160
}
157161

158162
&.with-message::before {
@@ -163,7 +167,7 @@
163167
left: 100%;
164168
border: 1px solid black;
165169
border-radius: 50%;
166-
background-color: var(--bs-warning);
170+
background-color: #ffc107;
167171
padding: 0.25rem;
168172
animation: flash-in 0.75s;
169173

@@ -181,6 +185,75 @@
181185
}
182186
}
183187

188+
/* Feedback button colors. */
189+
.btn-correct {
190+
--bs-btn-color: #fff;
191+
--bs-btn-bg: #198754;
192+
--bs-btn-border-color: #198754;
193+
--bs-btn-hover-color: #fff;
194+
--bs-btn-hover-bg: #157347;
195+
--bs-btn-hover-border-color: #146c43;
196+
--bs-btn-focus-shadow-rgb: 60, 153, 110;
197+
--bs-btn-active-color: #fff;
198+
--bs-btn-active-bg: #146c43;
199+
--bs-btn-active-border-color: #13653f;
200+
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
201+
--bs-btn-disabled-color: #fff;
202+
--bs-btn-disabled-bg: #198754;
203+
--bs-btn-disabled-border-color: #198754;
204+
}
205+
206+
.btn-incorrect {
207+
--bs-btn-color: #fff;
208+
--bs-btn-bg: #dc3545;
209+
--bs-btn-border-color: #dc3545;
210+
--bs-btn-hover-color: #fff;
211+
--bs-btn-hover-bg: #bb2d3b;
212+
--bs-btn-hover-border-color: #b02a37;
213+
--bs-btn-focus-shadow-rgb: 225, 83, 97;
214+
--bs-btn-active-color: #fff;
215+
--bs-btn-active-bg: #b02a37;
216+
--bs-btn-active-border-color: #a52834;
217+
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
218+
--bs-btn-disabled-color: #fff;
219+
--bs-btn-disabled-bg: #dc3545;
220+
--bs-btn-disabled-border-color: #dc3545;
221+
}
222+
223+
.btn-partially-correct {
224+
--bs-btn-color: #000;
225+
--bs-btn-bg: #ffc107;
226+
--bs-btn-border-color: #ffc107;
227+
--bs-btn-hover-color: #000;
228+
--bs-btn-hover-bg: #ffca2c;
229+
--bs-btn-hover-border-color: #ffc720;
230+
--bs-btn-focus-shadow-rgb: 217, 164, 6;
231+
--bs-btn-active-color: #000;
232+
--bs-btn-active-bg: #ffcd39;
233+
--bs-btn-active-border-color: #ffc720;
234+
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
235+
--bs-btn-disabled-color: #000;
236+
--bs-btn-disabled-bg: #ffc107;
237+
--bs-btn-disabled-border-color: #ffc107;
238+
}
239+
240+
.btn-preview {
241+
--bs-btn-color: #fff;
242+
--bs-btn-bg: #1a67ea;
243+
--bs-btn-border-color: #1a67ea;
244+
--bs-btn-hover-color: #fff;
245+
--bs-btn-hover-bg: #1658c7;
246+
--bs-btn-hover-border-color: #1552bb;
247+
--bs-btn-focus-shadow-rgb: 60, 126, 237;
248+
--bs-btn-active-color: #fff;
249+
--bs-btn-active-bg: #1552bb;
250+
--bs-btn-active-border-color: #144db0;
251+
--bs-btn-active-shadow: inset 0 3px 5px #00000020;
252+
--bs-btn-disabled-color: #fff;
253+
--bs-btn-disabled-bg: #1a67ea;
254+
--bs-btn-disabled-border-color: #1a67ea;
255+
}
256+
184257
.radio-buttons-container,
185258
.checkboxes-container {
186259
max-width: calc(100% - 1rem - 25px);
@@ -256,7 +329,7 @@
256329
.popover-header {
257330
text-align: center;
258331
cursor: pointer;
259-
--bs-popover-header-bg: var(--bs-info);
332+
--bs-popover-header-bg: #1a67ea;
260333
--bs-popover-header-color: white;
261334

262335
.btn-close {
@@ -268,21 +341,22 @@
268341

269342
&.correct {
270343
.popover-header {
271-
--bs-popover-header-bg: var(--bs-success);
344+
--bs-popover-header-bg: #198754;
272345
--bs-popover-header-color: white;
273346
}
274347
}
275348

276349
&.incorrect {
277350
.popover-header {
278-
--bs-popover-header-bg: var(--bs-danger);
351+
--bs-popover-header-bg: #dc3545;
279352
--bs-popover-header-color: white;
280353
}
281354
}
282355

283-
&.partially-correct {
356+
&.partially-correct,
357+
&.unknown {
284358
.popover-header {
285-
--bs-popover-header-bg: var(--bs-warning);
359+
--bs-popover-header-bg: #ffc107;
286360
--bs-popover-header-color: black;
287361
}
288362
}

macros/PG.pl

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,12 @@ =head2 ENDDOCUMENT
845845
846846
=item *
847847
848-
C<btnClass>: This is the bootstrap button class added to the feedback button.
849-
By default it is "btn-info", "btn-success", "btn-danger", or "btn-warning"
848+
C<btnClass>: This is the button class added to the feedback button. These are
849+
based on bootstrap button styles, but are custom styles for the feedback
850+
buttons to allow clients to theme the bootstrap buttons without changing the
851+
feedback styles. By default it is "btn-preview" (coppied from btn-info),
852+
"btn-correct" (coppied from btn-success), "btn-incorrect" (coppied from
853+
btn-danger), or "btn-partially-correct" (coppied from btn-warning)
850854
depending on the status of the answer and the type of submission.
851855
852856
=item *
@@ -1059,7 +1063,7 @@ sub ENDDOCUMENT {
10591063
my %options = (
10601064
resultTitle => maketext('Answer Preview'),
10611065
resultClass => '',
1062-
btnClass => 'btn-info',
1066+
btnClass => 'btn-preview',
10631067
btnAddClass => 'ms-2',
10641068
feedbackElements => Mojo::Collection->new,
10651069
insertElement => undef,
@@ -1108,15 +1112,28 @@ sub ENDDOCUMENT {
11081112
} elsif ($answerScore >= 1) {
11091113
$options{resultTitle} = maketext('Correct');
11101114
$options{resultClass} = 'correct';
1111-
$options{btnClass} = 'btn-success';
1115+
$options{btnClass} = 'btn-correct';
11121116
} elsif ($answerScore == 0) {
11131117
$options{resultTitle} = maketext('Incorrect');
11141118
$options{resultClass} = 'incorrect';
1115-
$options{btnClass} = 'btn-danger';
1119+
$options{btnClass} = 'btn-incorrect';
11161120
} else {
11171121
$options{resultTitle} = maketext('[_1]% correct', round($answerScore * 100));
11181122
$options{resultClass} = 'partially-correct';
1119-
$options{btnClass} = 'btn-warning';
1123+
$options{btnClass} = 'btn-partially-correct';
1124+
}
1125+
} elsif ($rh_envir->{showAttemptResults} && !$PG->{flags}{showPartialCorrectAnswers}) {
1126+
# Partially correct feedback is not being shown, but this is not a preview, so make the
1127+
# feedback look different than a preview. If the problem score is zero, everything is
1128+
# incorrect, so mark the whole problem as incorrect. Otherwise mark it as unknown correctness.
1129+
if ($problemResult->{score}) {
1130+
$options{resultTitle} = maketext('Unknown');
1131+
$options{resultClass} = 'unknown';
1132+
$options{btnClass} = 'btn-partially-correct';
1133+
} else {
1134+
$options{resultTitle} = maketext('Incorrect');
1135+
$options{resultClass} = 'incorrect';
1136+
$options{btnClass} = 'btn-incorrect';
11201137
}
11211138
}
11221139

macros/core/PGessaymacros.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ sub essay_cmp {
6767

6868
$options->{resultClass} = '';
6969
$options->{insertMethod} = 'append_content';
70-
$options->{btnClass} = 'btn-info';
70+
$options->{btnClass} = 'btn-preview';
7171
$options->{btnAddClass} = '';
7272
$options->{wrapPreviewInTex} = 0;
7373
$options->{showEntered} = 0; # Suppress output of the feedback entered answer.

0 commit comments

Comments
 (0)