[LON-CAPA-cvs] cvs: loncom /homework optionresponse.pm /interface lonpdfupload.pm
raeburn
raeburn at source.lon-capa.org
Tue Mar 17 11:56:55 EDT 2026
raeburn Tue Mar 17 15:56:55 2026 EDT
Modified files:
/loncom/interface lonpdfupload.pm
/loncom/homework optionresponse.pm
Log:
- Bug 6121
- Support checkbox mode for optionresponse in cases where (a) no form field
retrieved from unchecked boxes, and (b) where LON-CAPA problem needs value
for checked boxes to be 'Off'.
-------------- next part --------------
Index: loncom/interface/lonpdfupload.pm
diff -u loncom/interface/lonpdfupload.pm:1.32 loncom/interface/lonpdfupload.pm:1.33
--- loncom/interface/lonpdfupload.pm:1.32 Sun Feb 22 23:27:03 2026
+++ loncom/interface/lonpdfupload.pm Tue Mar 17 15:56:54 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# PDF Form Upload Handler
#
-# $Id: lonpdfupload.pm,v 1.32 2026/02/22 23:27:03 raeburn Exp $
+# $Id: lonpdfupload.pm,v 1.33 2026/03/17 15:56:54 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -284,7 +284,7 @@
sub grade_pdf {
my @pdfdata = @_;
my ($result,$meta,%grades,%problems,%foreigncourse,%mismatchuser,
- %types,%checkboxoff,$debug);
+ %types,%checkboxoff,%checkboxon,%checkboxtotal,%checkboxinfo,$debug);
my $navmap = Apache::lonnavmaps::navmap->new();
if (!defined($navmap)) {
@@ -354,8 +354,25 @@
if ($type eq 'radiobuttonresponse' && $value eq 'Off' ) {
next;
}
- if (($type eq 'optionresponse') && ($HWVAL =~ /^HWHDN([^:]+):0$/)) {
- $checkboxoff{$symb.$part}{'HWVAL'.$1} = $value;
+ if (($type eq 'optionresponse') && ($HWVAL =~ /^HWHDN(ON|OFF|NUM)([^:]+):0$/)) {
+ my ($key,$id) = ($1,$2);
+ if ($key eq 'ON') {
+ $checkboxon{$symb.$part}{'HWVAL'.$id} = $value;
+ } elsif ($key eq 'OFF') {
+ $checkboxoff{$symb.$part}{'HWVAL'.$id} = $value;
+ } else {
+ $checkboxtotal{$symb.$part}{'HWVAL'.$id} = $value;
+ unless (exists($checkboxinfo{$symb.$part})) {
+ my $submit = $part;
+ $submit =~ s/part_(.*)/submit_$1/;
+ $checkboxinfo{$symb.$part} = {
+ 'resource' => $resource,
+ 'symb' => $symb,
+ 'submitted' => $part,
+ $submit => 'Answer',
+ };
+ }
+ }
next;
}
@@ -397,6 +414,45 @@
$result .= '<h2 class="LC_heading_2">'.&mt('Result of PDF Form upload').'</h2>';
+ if (keys(%checkboxtotal)) {
+ foreach my $key (keys(%checkboxtotal)) {
+ if ((ref($checkboxtotal{$key}) eq 'HASH') && (ref($checkboxoff{$key}) eq 'HASH')) {
+ foreach my $hwvalprefix (keys(%{$checkboxtotal{$key}})) {
+ if ($checkboxoff{$key}{$hwvalprefix} ne '') {
+ my $unchecked = $checkboxoff{$key}{$hwvalprefix};
+ my $total = $checkboxtotal{$key}{$hwvalprefix};
+ my ($part, $type, $HWVAL, $input_id) = split(/&/,$key);
+ if (($unchecked ne '') && ($total > 1)) {
+ for (my $i=1; $i<$total; $i++) {
+ my $hwval = $hwvalprefix.':'.$i;
+ if ((!exists($types{$key})) ||
+ ((ref($types{$key}) eq 'HASH') && (!exists($types{$key}{$hwval})))) {
+ if (ref($problems{$key}) eq 'HASH') {
+ if ($problems{$key}{$hwval} eq '') {
+ $problems{$key}{$hwval} = $unchecked;
+ }
+ } else {
+ if (ref($checkboxinfo{$key}) eq 'HASH') {
+ $problems{$key} = $checkboxinfo{$key};
+ }
+ $problems{$key}{$hwval} = $unchecked;
+ }
+ if (!exists($types{$key})) {
+ $types{$key}{$hwval} = 'optionresponse';
+ } elsif (ref($types{$key}) eq 'HASH') {
+ if (!exists($types{$key}{$hwval})) {
+ $types{$key}{$hwval} = 'optionresponse';
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
if (keys(%problems) > 0) {
$result .= &Apache::loncommon::start_data_table()
.&Apache::loncommon::start_data_table_header_row()
@@ -422,12 +478,17 @@
push(@{$problem{$hwval}},$ordered{$digit});
}
}
- } elsif (ref($checkboxoff{$key}) eq 'HASH') {
- if (($problem{$hwval} eq '') &&
- ($types{$key}{$hwval} eq 'optionresponse')) {
+ } elsif ((ref($checkboxoff{$key}) eq 'HASH') && (ref($checkboxon{$key}) eq 'HASH')) {
+ if ($types{$key}{$hwval} eq 'optionresponse') {
my ($hwvalprefix) = split(/:/,$hwval);
- if ($checkboxoff{$key}{$hwvalprefix} ne '') {
- $problem{$hwval} = $checkboxoff{$key}{$hwvalprefix};
+ if (($problem{$hwval} eq '') || ($problem{$hwval} eq 'Off')) {
+ if ($checkboxoff{$key}{$hwvalprefix} ne '') {
+ $problem{$hwval} = $checkboxoff{$key}{$hwvalprefix};
+ }
+ } elsif (($problem{$hwval} eq 'Yes') && ($checkboxon{$key}{$hwvalprefix} ne 'Yes')) {
+ if ($checkboxon{$key}{$hwvalprefix} ne '') {
+ $problem{$hwval} = $checkboxon{$key}{$hwvalprefix};
+ }
}
}
}
Index: loncom/homework/optionresponse.pm
diff -u loncom/homework/optionresponse.pm:1.207 loncom/homework/optionresponse.pm:1.208
--- loncom/homework/optionresponse.pm:1.207 Sun Feb 22 23:27:02 2026
+++ loncom/homework/optionresponse.pm Tue Mar 17 15:56:55 2026
@@ -1,7 +1,7 @@
# LearningOnline Network with CAPA
# option list style responses
#
-# $Id: optionresponse.pm,v 1.207 2026/02/22 23:27:02 raeburn Exp $
+# $Id: optionresponse.pm,v 1.208 2026/03/17 15:56:55 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -739,13 +739,13 @@
my $checkboxopt;
if ($target eq 'web') {
$checkboxopt=&check_box_opt($target,$checkboxvalue, at opt);
- if ($checkboxopt && (!$no_tfprompt)) {
+ if (($checkboxopt ne '') && (!$no_tfprompt)) {
$result.='<br />'.
($checkboxchoices?&mt('Choices: ').'<b>'.$opt[0].','.$opt[1].'</b>. ':'').
&mt('Select all that are [_1].','<b>'.$checkboxopt.'</b>');
}
}
- my ($fieldname,$checkboxoff);
+ my ($fieldname,$checkboxoff,$hiddennum);
if ($target eq 'tex' and $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
$fieldname = &Apache::lonenc::encrypted($env{'request.symb'},1);
@@ -761,16 +761,31 @@
$escres =~ s{_}{\\_}g;
$fieldname .= '\&part\_'.$escpart.'\&optionresponse';
($checkboxopt,$checkboxoff)=&check_box_opt($target,$checkboxvalue, at opt);
-
-# To support checkbox mode for optionresponse, include a hidden form
-# field in the PDF with the value set to the option in effect for
-# the unchecked checkboxes. When the submitted form data are processed
-# the values for any unchecked boxes (each null value in received form
-# data) are all set to the value retrieved from the hidden form field.
-
- if ($checkboxopt) {
- my $hidden = $fieldname.'\&HWHDN\_'.$escres.':';
- $result .= &Apache::lonxml::print_pdf_hidden_textfield($hidden.'0',$checkboxoff).' ';
+#
+# To support checkbox mode for optionresponse, include three hidden form
+# fields in the PDF: (a) HWHDNOFF with its value set to option in effect for
+# unchecked checkboxes, (b) HWHDNON with its value set to the option in
+# effect for checked checkboxes, and (c) HWHDNNUM with number of checkboxes.
+#
+# When the submitted form data are processed, if the checked value is 'Off'
+# the value is reported as 'Yes', and this needs to be detected
+# and replaced with the required value, as retrieved from the value for
+# the HWHDNON form field.
+#
+# If the checked value is not 'Off', then the values of the unchecked boxes
+# may be reported as 'Off', and, if so, this needs to be detected and replaced
+# with the required value retrieved from the value for the HWHDNOFF form field.
+#
+# If entries for the unchecked boxes are missing from the list of form fields
+# then form field items are created for each missing item with the value for
+# the the HWHDNOFF form field assigned to each item.
+#
+ if ($checkboxopt ne '') {
+ $hiddennum = $fieldname.'\&HWHDNNUM\_'.$escres.':';
+ my $hiddenoff = $fieldname.'\&HWHDNOFF\_'.$escres.':';
+ $result .= &Apache::lonxml::print_pdf_hidden_textfield($hiddenoff.'0',$checkboxoff).' ';
+ my $hiddenon = $fieldname.'\&HWHDNON\_'.$escres.':';
+ $result .= &Apache::lonxml::print_pdf_hidden_textfield($hiddenon.'0',$checkboxopt).' ';
if (!$no_tfprompt) {
$result .= ($checkboxchoices?&mt('Choices: ').
'\textbf{'.$opt[0].','.$opt[1].'}. ':'').
@@ -795,7 +810,7 @@
if($target eq 'tex' and $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
- if ($checkboxopt) {
+ if ($checkboxopt ne '') {
$optionlist = '\vskip 4 mm'.
&Apache::lonxml::print_pdf_checkbox($fieldname.$temp,$checkboxopt);
} else {
@@ -809,7 +824,7 @@
if ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER'
&& $Apache::lonhomework::type ne 'exam') {
- unless ($checkboxopt) {
+ if ($checkboxopt eq '') {
$optionlist .= &Apache::lonxml::print_pdf_add_combobox_option($option);
}
} else {
@@ -819,7 +834,7 @@
if ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER'
&& $Apache::lonhomework::type ne 'exam') {
- unless ($checkboxopt) {
+ if ($checkboxopt eq '') {
$optionlist .= &Apache::lonxml::print_pdf_add_combobox_option($option);
}
} else {
@@ -830,7 +845,7 @@
if ($target ne 'tex') {
if ($Apache::lonhomework::type ne 'exam') {
# we are on the web, this is not an exam, and the problem can be answered
- if ($checkboxopt) {
+ if ($checkboxopt ne '') {
# generate checkboxes
my $fieldname=$Apache::inputtags::response['-1'].':'.$temp;
my $altopt=$opt[0];
@@ -931,7 +946,7 @@
&& $Apache::lonhomework::type ne 'exam') {
$text =~ s/\\item//m;
$result .= " $optionlist ";
- if ($checkboxopt) {
+ if ($checkboxopt ne '') {
$result .= $text;
} else {
$result .= &Apache::lonxml::print_pdf_end_combobox($text);
@@ -945,6 +960,13 @@
$result.= '</div>';
}
}
+ if (($target eq 'tex') &&
+ ($env{'form.pdfFormFields'} eq 'yes') &&
+ ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') &&
+ ($Apache::lonhomework::type ne 'exam') &&
+ ($checkboxopt ne '')) {
+ $result .= &Apache::lonxml::print_pdf_hidden_textfield($hiddennum.'0',$temp).' ';
+ }
}
if ($target eq 'web') {
More information about the LON-CAPA-cvs
mailing list