[LON-CAPA-cvs] cvs: loncom /html/adm/helper parameter.helper resettimes.helper /interface loncommon.pm lonhelper.pm lonnavmaps.pm lonparmset.pm
raeburn
raeburn at source.lon-capa.org
Thu Apr 23 12:56:44 EDT 2026
raeburn Thu Apr 23 16:56:44 2026 EDT
Modified files:
/loncom/interface loncommon.pm lonhelper.pm lonnavmaps.pm
lonparmset.pm
/loncom/html/adm/helper resettimes.helper parameter.helper
Log:
- WCAG 2.2 compliance
- Include labels for form elements.
- Satisfy minimum spacing between touch targets.
- Use <th> tags for column headings and row headings in data table
with scope="row" attribute for latter.
- For form elements in data table cells use aria-labelledby to reference
appropriate column and row headers.
- Group form elements in fieldset with legend for screenreaders.
-------------- next part --------------
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1516 loncom/interface/loncommon.pm:1.1517
--- loncom/interface/loncommon.pm:1.1516 Tue Apr 21 07:30:27 2026
+++ loncom/interface/loncommon.pm Thu Apr 23 16:56:43 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.1516 2026/04/21 07:30:27 raeburn Exp $
+# $Id: loncommon.pm,v 1.1517 2026/04/23 16:56:43 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -9624,7 +9624,7 @@
table.LC_resourceList {
font-size: 90%;
- line-height: 170%;
+ line-height: 180%;
}
table.LC_resourceList tr.LC_odd_row th.LC_colheader {
@@ -9635,11 +9635,13 @@
}
table.LC_resourceList tr.LC_odd_row th,
+table.LC_paramDefault tr.LC_odd_row th.LC_rowheader,
table#contentlist tr.LC_odd_row th {
background-color: $data_table_light;
}
table.LC_resourceList tr.LC_even_row th,
+table.LC_paramDefault tr.LC_even_row th.LC_rowheader,
table#contentlist tr.LC_even_row th {
background-color: $data_table_dark;
}
@@ -9649,6 +9651,8 @@
}
table.LC_resourceList tr th.LC_rowheader,
+table.LC_paramDefault tr.LC_odd_row th.LC_rowheader,
+table.LC_paramDefault tr.LC_even_row th.LC_rowheader,
table#contentlist tr.LC_odd_row th.LC_rowheader,
table#contentlist tr.LC_even_row th.LC_rowheader {
font-weight: normal;
Index: loncom/interface/lonhelper.pm
diff -u loncom/interface/lonhelper.pm:1.208 loncom/interface/lonhelper.pm:1.209
--- loncom/interface/lonhelper.pm:1.208 Sun Apr 19 03:47:18 2026
+++ loncom/interface/lonhelper.pm Thu Apr 23 16:56:43 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# .helper XML handler to implement the LON-CAPA helper
#
-# $Id: lonhelper.pm,v 1.208 2026/04/19 03:47:18 raeburn Exp $
+# $Id: lonhelper.pm,v 1.209 2026/04/23 16:56:43 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -641,9 +641,9 @@
$buttons .= '</p>'; # '</fieldset>';
}
-
-
- $result .= '<h2 class="LC_heading_2">'.$stateTitle.$stateHelp.'</h2>';
+ if (($stateTitle ne '') || ($stateHelp ne '')) {
+ $result .= '<h2 class="LC_heading_2">'.$stateTitle.$stateHelp.'</h2>';
+ }
# $result .= '<div>';
@@ -2452,7 +2452,8 @@
}
$result .= '<th id="col'.$col.'" class="LC_colheader">'.&Apache::lonlocal::mt('Select').'</th>';
if ($addparts) {
- $result .= '<th class="LC_colheader">'.&Apache::lonlocal::mt('Select parts').'</th>';
+ $col ++;
+ $result .= '<th id="col'.$col.'" class="LC_colheader">'.&Apache::lonlocal::mt('Select parts').'</th>';
}
$result .= '<th class="LC_colheader">'.&Apache::lonlocal::mt('Name of Resource').'</th>';
if ($addstatus) {
@@ -2557,12 +2558,14 @@
};
my $renderPartsFunc = sub {
my ($resource, $part, $params) = @_;
+ my $colnum = 0;
my $col= "<td>";
my $id=$resource->{ID};
my $resource_name =
&HTML::Entities::encode(&$valueFunc($resource),"<>&\"'");
if ($addparts && (scalar(@{$resource->parts}) > 1)) {
- $col .= "<select onclick=\"javascript:updateRadio(this.form,'${var}_forminput','$resource_name');updateHidden(this.form,'$id','${var}');\" name='part_${id}_forminput'>\n";
+ $colnum ++;
+ $col .= "<select onclick=\"javascript:updateRadio(this.form,'${var}_forminput','$resource_name');updateHidden(this.form,'$id','${var}');\" name='part_${id}_forminput' aria-labelledby='row".$params->{counter}." col".$colnum."'>\n";
$col .= "<option value=\"$part\">".&Apache::lonlocal::mt('All Parts')."</option>\n";
foreach my $part (@{$resource->parts}) {
$col .= "<option value=\"$part\">".&Apache::lonlocal::mt('Part: [_1]',$part)."</option>\n";
Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.588 loncom/interface/lonnavmaps.pm:1.589
--- loncom/interface/lonnavmaps.pm:1.588 Sun Apr 19 03:47:18 2026
+++ loncom/interface/lonnavmaps.pm Thu Apr 23 16:56:43 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Navigate Maps Handler
#
-# $Id: lonnavmaps.pm,v 1.588 2026/04/19 03:47:18 raeburn Exp $
+# $Id: lonnavmaps.pm,v 1.589 2026/04/23 16:56:43 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -1145,7 +1145,7 @@
# We're done preparing and finally ready to start the rendering
my $result;
if (($params->{'caller'} eq 'printout') || ($params->{'caller'} eq 'newslot') ||
- ($params->{'caller'} eq 'resettimes')) {
+ ($params->{'caller'} eq 'resettimes') || ($params->{'caller'} eq 'parameter')) {
$result = '<th scope="row" id="row'.$params->{counter}.'" class="LC_middle LC_rowheader">';
} else {
$result = '<td class="LC_middle">';
@@ -1162,7 +1162,7 @@
# Decide what to display
$result .= "$newBranchText$linkopen$icon";
-
+
my $curMarkerBegin = '';
my $curMarkerEnd = '';
@@ -1203,7 +1203,7 @@
}
$result .= "$curMarkerBegin$title$partLabel$curMarkerEnd$linkclose$editmapLink$nonLinkedText";
if (($params->{'caller'} eq 'printout') || ($params->{'caller'} eq 'newslot') ||
- ($params->{'caller'} eq 'resettimes')) {
+ ($params->{'caller'} eq 'resettimes') || ($params->{'caller'} eq 'parameter')) {
$result .= "</th>";
} else {
$result .= "</td>";
@@ -1998,7 +1998,7 @@
$args->{'counter'}++;
unless ($tablestarted) {
if (($args->{'caller'} eq 'printout') || ($args->{'caller'} eq 'newslot') ||
- ($args->{'caller'} eq 'resettimes')) {
+ ($args->{'caller'} eq 'resettimes') || ($args->{'caller'} eq 'parameter')) {
$result .= &Apache::loncommon::start_data_table("LC_resourceList");
} else {
$result .= &Apache::loncommon::start_data_table("LC_tableOfContent").
Index: loncom/interface/lonparmset.pm
diff -u loncom/interface/lonparmset.pm:1.633 loncom/interface/lonparmset.pm:1.634
--- loncom/interface/lonparmset.pm:1.633 Wed Dec 24 18:36:07 2025
+++ loncom/interface/lonparmset.pm Thu Apr 23 16:56:43 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set parameters for assessments
#
-# $Id: lonparmset.pm,v 1.633 2025/12/24 18:36:07 raeburn Exp $
+# $Id: lonparmset.pm,v 1.634 2026/04/23 16:56:43 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -7724,17 +7724,18 @@
}
$r->print(&mt('Manual setting rules apply to all interfaces.').'<br />'.
&mt('Automatic setting rules apply to table mode interfaces only.'));
- $r->print("\n".&Apache::loncommon::start_data_table().
+ $r->print("\n".&Apache::loncommon::start_data_table('LC_paramDefault').
&Apache::loncommon::start_data_table_header_row().
- "<th>".&mt('Rule for parameter').'</th><th>'.
- &mt('Action').'</th><th>'.&mt('Value').'</th>'.
+ '<th id="rule-column">'.&mt('Rule for parameter').'</th><th id="action-column">'.
+ &mt('Action').'</th><th id="value-column">'.&mt('Value').'</th>'.
&Apache::loncommon::end_data_table_header_row());
foreach my $tempkey (&keysindisplayorder(\%allparms,\%keyorder)) {
unless ($tempkey) { next; }
$r->print("\n".&Apache::loncommon::start_data_table_row().
- "<td>".$allparms{$tempkey}."\n<br />(".$tempkey.')</td><td>');
+ '<th scope="row" id="'.$tempkey.'-row" class="LC_rowheader">'
+ .$allparms{$tempkey}."\n<br />(".$tempkey.')</th>');
my $action=&rulescache($tempkey.'_action');
- $r->print('<select name="'.$tempkey.'_action">');
+ $r->print('<select name="'.$tempkey.'_action" aria-labelledby="rule-column '.$tempkey.'-row">');
if (&isdateparm($defkeytype{$tempkey})) {
for (my $i=0;$i<=$#dateoptions;$i++) {
if ($dateoptions[$i]=~/\_$tempkey$/) { next; }
@@ -7752,8 +7753,8 @@
}
$r->print('</select>');
unless (&isdateparm($defkeytype{$tempkey})) {
- $r->print("\n<br />".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
- '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" />');
+ $r->print("\n<br /><label>".&mt('Triggering value(s) of other parameter (optional, comma-separated):').
+ '<input type="text" size="20" name="'.$tempkey.'_triggervalue" value="'.&rulescache($tempkey.'_triggervalue').'" /></label>');
}
$r->print("\n</td><td>\n");
@@ -7762,24 +7763,30 @@
my $hours=&rulescache($tempkey.'_hours');
my $min=&rulescache($tempkey.'_min');
my $sec=&rulescache($tempkey.'_sec');
+ my $legend = &mt('Value for: [_1]',$tempkey);
$r->print(<<ENDINPUTDATE);
- <input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}<br />
- <input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}<br />
- <input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}<br />
- <input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}
+ <fieldset class="LC_borderless" style="line-height: 190%">
+ <legend class="LC_visually_hidden">$legend</legend>
+ <label><input name="$tempkey\_days" type="text" size="4" value="$days" />$lt{'days'}</label><br />
+ <label><input name="$tempkey\_hours" type="text" size="4" value="$hours" />$lt{'hours'}</label><br />
+ <label><input name="$tempkey\_min" type="text" size="4" value="$min" />$lt{'min'}</label><br />
+ <label><input name="$tempkey\_sec" type="text" size="4" value="$sec" />$lt{'sec'}</label>
+ </fieldset>
ENDINPUTDATE
} elsif ($defkeytype{$tempkey} eq 'string_yesno') {
my $yeschecked='';
my $nochecked='';
if (&rulescache($tempkey.'_value') eq 'yes') { $yeschecked=' checked="checked"'; }
if (&rulescache($tempkey.'_value') eq 'no') { $nochecked=' checked="checked"'; }
-
+ my $legend = &mt('Value for: [_1]',$tempkey);
$r->print(<<ENDYESNO);
+ <fieldset class="LC_borderless" style="line-height: 190%"><legend class="LC_visually_hidden">$legend</legend>
<label><input type="radio" name="$tempkey\_value" value="yes"$yeschecked /> $lt{'yes'}</label><br />
<label><input type="radio" name="$tempkey\_value" value="no"$nochecked /> $lt{'no'}</label>
+ </fieldset>
ENDYESNO
} else {
- $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" />');
+ $r->print('<input type="text" size="20" name="'.$tempkey.'_value" value="'.&rulescache($tempkey.'_value').'" aria-labelledby="value-column '.$tempkey.'-row" />');
}
$r->print('</td>'.&Apache::loncommon::end_data_table_row());
}
Index: loncom/html/adm/helper/resettimes.helper
diff -u loncom/html/adm/helper/resettimes.helper:1.12 loncom/html/adm/helper/resettimes.helper:1.13
--- loncom/html/adm/helper/resettimes.helper:1.12 Mon Dec 1 03:16:29 2025
+++ loncom/html/adm/helper/resettimes.helper Thu Apr 23 16:56:44 2026
@@ -1,12 +1,21 @@
<helper title="Reset Access Times" requiredpriv="mgr">
<state name="START" title="Select Scope">
<message>
- Select
+ <span aria-hidden="true">Select</span>
+ <div>
+ <fieldset class="LC_borderless">
+ <legend class="LC_visually_hidden">
+ Select scope of access times reset
+ </legend>
</message>
<choices variable="harry">
<choice computer='1' nextstate="Student">Reset times on one or more folders/maps, resources or the course for a single student.</choice>
<choice computer='0' nextstate="Class">Reset times on a single folder/map, resource or the course for a section or the whole class.</choice>
</choices>
+ <message>
+ </fieldset>
+ </div>
+ </message>
</state>
<state name="Student" title="Select Student">
<message nextstate="SelectAccess">
@@ -15,9 +24,14 @@
<student variable='stu1' coursepersonnel='true' activeonly='true' />
</state>
- <state name="SelectAccess">
+ <state name="SelectAccess" title="Select Accesses to Delete">
<message nextstate="ConfirmStu">
- This is a list of first access times and what was accessed, please select those you want deleted.
+ <span aria-hidden="true">This is a list of first access times and what was accessed, please select those you want deleted.</span>
+ <div>
+ <fieldset class="LC_borderless">
+ <legend class="LC_visually_hidden">
+ Select first access times to delete
+ </legend>
</message>
<choices variable='delete' multichoice='true'>
<exec>
@@ -36,6 +50,10 @@
}
</exec>
</choices>
+ <message>
+ </fieldset>
+ </div>
+ </message>
</state>
<state name="ConfirmStu">
Index: loncom/html/adm/helper/parameter.helper
diff -u loncom/html/adm/helper/parameter.helper:1.23 loncom/html/adm/helper/parameter.helper:1.24
--- loncom/html/adm/helper/parameter.helper:1.23 Sat Mar 5 21:49:52 2016
+++ loncom/html/adm/helper/parameter.helper Thu Apr 23 16:56:44 2026
@@ -48,7 +48,12 @@
</state>
<state name="CHOOSE_LEVEL" title="Which Problem or Problems?">
- <message>Which problems do you wish to set a parameter for?</message>
+ <message>
+ <span aria-hidden="true">Which problems do you wish to set a parameter for?</span>
+ <div>
+ <fieldset class="LC_borderless">
+ <legend class="LC_visually_hidden">Which problems do you wish to set a parameter for?</legend>
+ </message>
<choices variable="GRANULARITY">
<choice computer="whole_course" nextstate="CHOOSE_ACTION">
Course default for all problems
@@ -67,6 +72,10 @@
One particular problem (overrides folder and course defaults)
</choice>
</choices>
+ <message>
+ </fieldset>
+ </div>
+ </message>
</state>
<state name="CHOOSE_FOLDER" title="Select Folder">
@@ -90,10 +99,21 @@
</state>
<state name="CHOOSE_ACTION" title="Parameter Type">
- <eval>return &mt('What parameter do you want to set for ' .
+ <message><span aria-hidden="true"></message>
+ <eval>return &mt('What parameter do you want to set for ' .
&{$helper->{DATA}->{'levelType'}}()
. '?');
- </eval>
+ </eval>
+ <message>
+ </span><div>
+ <fieldset class="LC_borderless">
+ <legend class="LC_visually_hidden">
+ </message>
+ <eval>return &mt('What parameter do you want to set for ' .
+ &{$helper->{DATA}->{'levelType'}}()
+ . '?');
+ </eval>
+ <message></legend></message>
<choices variable="ACTION_TYPE">
<nextstate>CHOOSE_DATE</nextstate>
<choice computer="open_date" nextstate="CHOOSE_DATE">Set an <b>open date</b></choice>
@@ -102,10 +122,14 @@
<choice computer="tries" nextstate="CHOOSE_TRIES">Set the <b>number of tries</b></choice>
<choice computer="weight" nextstate="CHOOSE_WEIGHT">Set the <b>problem weight</b></choice>
</choices>
+ <message>
+ </fieldset>
+ </div>
+ </message>
</state>
<state name="CHOOSE_WEIGHT" title="Set Problem Weight">
- <eval>return &mt('What weight should be set for ' .
+ <eval>return '<label>'.&mt('What weight should be set for ' .
&{$helper->{DATA}->{'levelType'}}()
. '?').'<br />';
</eval>
@@ -114,12 +138,15 @@
return &mt('[_1] is not an acceptable weight. Weight must be a positive number.','"'.$element->getValue().'"');
}
return undef;
- </validator>
- </string>
- </state>
+ </validator>
+ </string>
+ <message>
+ </label>
+ </message>
+ </state>
<state name="CHOOSE_TRIES" title="Set Problem Tries">
- <eval>return &mt('How many tries should be set for ' .
+ <eval>return '<label>'.&mt('How many tries should be set for ' .
&{$helper->{DATA}->{'levelType'}}()
. '?').'<br />';
</eval>
@@ -127,9 +154,12 @@
<validator>if ($val !~ /^[1234567890]+$/) {
return &mt('[_1] is not an acceptable number of tries. Tries must be a positive number with no decimal point.','"'.$element->getValue().'"');}
return undef;
- </validator>
- </string>
- </state>
+ </validator>
+ </string>
+ <message>
+ </label>
+ </message>
+ </state>
<state name="CHOOSE_DATE" title="Set Date">
<eval>
@@ -137,19 +167,33 @@
&{$helper->{DATA}->{'dateType'}}() .
' be set to?').'<br /><br />';
</eval>
- <date variable="PARM_DATE" hoursminutes='1'>
+ <date variable="PARM_DATE" hoursminutes='1' aria-label="Date parameter">
<nextstate>CHOOSE_STUDENT_LEVEL</nextstate>
</date>
</state>
<state name="CHOOSE_STUDENT_LEVEL" title="Students Affected">
+ <message><span aria-hidden="true"></message>
<eval>
- return &mt('Set ' .
+ return &mt('Set ' .
&{$helper->{DATA}->{'dateType'}}() .
' for ' .
&{$helper->{DATA}->{'levelType'}}() .
' for ...');
- </eval>
+ </eval>
+ <message>
+ </span><div>
+ <fieldset class="LC_borderless">
+ <legend class="LC_visually_hidden">
+ </message>
+ <eval>
+ return &mt('Set ' .
+ &{$helper->{DATA}->{'dateType'}}() .
+ ' for ' .
+ &{$helper->{DATA}->{'levelType'}}() .
+ ' for ...');
+ </eval>
+ <message></legend></message>
<choices variable="TARGETS">
<condition>
<clause>return 1 if ($env{'request.course.sec'} eq '')</clause>
@@ -165,8 +209,12 @@
</condition>
<choice computer="student" nextstate="CHOOSE_STUDENT">
. . . for an individual <b>student</b> or <b>user</b></choice>
- </choices>
- </state>
+ </choices>
+ <message>
+ </fieldset>
+ </div>
+ </message>
+ </state>
<state name="CHOOSE_SECTION" title="Select Section">
<eval>
More information about the LON-CAPA-cvs
mailing list