[LON-CAPA-cvs] cvs: loncom /interface lonmodifycourse.pm

raeburn raeburn at source.lon-capa.org
Mon May 4 17:14:36 EDT 2026


raeburn		Mon May  4 21:14:36 2026 EDT

  Modified files:              
    /loncom/interface	lonmodifycourse.pm 
  Log:
  - WCAG 2 compliance
    Include labels for form elements.
    Sequential headings.
    Group form elements in fieldset with legend for screenreaders.
  
  
-------------- next part --------------
Index: loncom/interface/lonmodifycourse.pm
diff -u loncom/interface/lonmodifycourse.pm:1.110 loncom/interface/lonmodifycourse.pm:1.111
--- loncom/interface/lonmodifycourse.pm:1.110	Mon Dec 15 05:32:44 2025
+++ loncom/interface/lonmodifycourse.pm	Mon May  4 21:14:36 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # handler for DC-only modifiable course settings
 #
-# $Id: lonmodifycourse.pm,v 1.110 2025/12/15 05:32:44 raeburn Exp $
+# $Id: lonmodifycourse.pm,v 1.111 2026/05/04 21:14:36 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -618,11 +618,11 @@
         );
 
     $r->print(
-        '<h3>'
+        '<h2 class="LC_heading_2">'
        .&mt($type).': <span class="LC_nobreak">'.$cdesc.'</span>'
-       .'</h3>'."\n");
+       .'</h2>'."\n");
     if ($extendedtype) {
-        $r->print('<h4>'.&mt('Type').': '.&mt("$extendedtype $type").'</h4>');
+        $r->print('<b>'.&mt('Type').': '.&mt("$extendedtype $type").'</b>');
     }
     $r->print(
         '<form name="menu" method="post" action="/adm/modifycourse">'
@@ -673,6 +673,7 @@
     my %enrollvar = &get_enrollment_settings($cdom,$cnum);
     my %longtype = &course_settings_descrip($type);
     my %lt = &Apache::lonlocal::texthash(
+            'enro' => 'Enrollment setting',
             'valu' => 'Current value',
             'cour' => 'Current settings are:',
             'cose' => "Settings which control auto-enrollment using classlists from your institution's student information system fall into two groups:",
@@ -693,7 +694,7 @@
     }
     my $disp_table = &Apache::loncommon::start_data_table()."\n".
                      &Apache::loncommon::start_data_table_header_row()."\n".
-                     "<th> </th>\n".
+                     "<th>$lt{'enro'}</th>\n".
                      "<th>$lt{'valu'}</th>\n".
                      "<th>$lt{'dcon'}</th>\n".
                      &Apache::loncommon::end_data_table_header_row()."\n";
@@ -747,8 +748,8 @@
         $setparms_link_start = '<a href="javascript:changePage(document.viewparms,'."'setparms'".');">';
         $setparms_link_end = '</a>';
     }
-    $r->print('<h3>'.&mt('Current automated enrollment settings').'</h3>'."\n".
-              '<h4><span class="LC_nobreak">'.&mt($type).': '.$cdesc.'</span></h4>'."\n".
+    $r->print('<h2 class="LC_heading_2">'.&mt('Current automated enrollment settings').'</h2>'."\n".
+              '<span class="LC_nobreak"><b>'.&mt($type).': '.$cdesc.'</b></span><br />'."\n".
               '<form action="/adm/modifycourse" method="post" name="viewparms">'."\n".
               '<p>'.$lt{'cose'}.'</p><ul>'.
               '<li>'.&mt('Settings modifiable by a [_1] via the [_2]Automated Enrollment Manager[_3] in a course.',
@@ -771,8 +772,8 @@
 sub print_setquota {
     my ($r,$cdom,$cnum,$cdesc,$type,$readonly) = @_;
     my $lctype = lc($type);
-    my $headline = '<h3>'.&mt("Set disk space quotas for $lctype").'</h3>'."\n".
-                   '<h4><span class="LC_nobreak">'.&mt($type).': '.$cdesc.'</span></h4>'."\n";
+    my $headline = '<h2 class="LC_heading_2">'.&mt("Set disk space quotas for $lctype").'</h2>'."\n".
+                   '<span class="LC_nobreak"><b>'.&mt($type).': '.$cdesc.'</b></span><br />'."\n";
     my %lt = &Apache::lonlocal::texthash(
                 'gpqu' => 'Disk space for storage of group portfolio files',
                 'upqu' => 'Disk space for storage of content directly uploaded to course via Content Editor',
@@ -817,11 +818,11 @@
 $headline
 <form action="/adm/modifycourse" method="post" name="setquota" onsubmit="return verify_quota();">
 <p><span class="LC_nobreak">
-$porthelpitem $lt{'gpqu'}: <input type="text" size="4" name="coursequota" value="$coursequota" $disabled /> MB
+$porthelpitem <label>$lt{'gpqu'}: <input type="text" size="4" name="coursequota" value="$coursequota" $disabled /></label> MB
 </span>
 <br />
 <span class="LC_nobreak">
-$uploadhelpitem $lt{'upqu'}: <input type="text" size="4" name="uploadquota" value="$uploadquota" $disabled /> MB
+$uploadhelpitem <label>$lt{'upqu'}: <input type="text" size="4" name="uploadquota" value="$uploadquota" $disabled /></label> MB
 </span>
 </p>
 <p>
@@ -870,11 +871,11 @@
     my $helpitem = &Apache::loncommon::help_open_topic('Modify_Anonsurvey_Threshold');
     my $showtype = &mt($type);
     $r->print(<<ENDDOCUMENT);
-<h3>$lt{'resp'}</h3>
-<h4><span class="LC_nobreak">$showtype: $cdesc</span></h4>
+<h2 class="LC_heading_2">$lt{'resp'}</h2>
+<span class="LC_nobreak"><b>$showtype: $cdesc</b></span>
 <form action="/adm/modifycourse" method="post" name="setanon" onsubmit="return verify_anon_threshold();">
 <p>
-$helpitem $lt{'sufa'}: <input type="text" size="4" name="threshold" value="$threshold" $disabled />     </p>
+$helpitem <label>$lt{'sufa'}: <input type="text" size="4" name="threshold" value="$threshold" $disabled /></label>     </p>
 $submit
 $hidden_elements
 </form>
@@ -937,17 +938,18 @@
     my $helpitem = &Apache::loncommon::help_open_topic('Modify_Postsubmit_Config');
     my $showtype = &mt($type);
     $r->print(<<ENDDOCUMENT);
-<h3>$lt{'conf'}</h3>
-<h4><span class="LC_nobreak">$showtype: $cdesc</span></h4>
+<h2 class="LC_heading_2">$lt{'conf'}</h2>
+<span class="LC_nobreak"><b>$showtype: $cdesc</b></span><br /><br />
 <form action="/adm/modifycourse" method="post" name="setpostsubmit" onsubmit="return verify_postsubmit();">
-<p>
-$helpitem $lt{'disa'}:
+<fieldset class="LC_borderless">
+<legend class="LC_visually_hidden">$lt{'disa'}</legend>
+$helpitem <span aria-hidden="true">$lt{'disa'}:</span>
 <label><input type="radio" name="postsubmit" $checkedon onclick="togglePostsubmit('studentsubmission');" value="1" $disabled />
 $lt{'yes'}</label>  
 <label><input type="radio" name="postsubmit" $checkedoff onclick="togglePostsubmit('studentsubmission');" value="0" $disabled />
-$lt{'no'}</label></p>
+$lt{'no'}</label></fieldset>
 <div id="studentsubmission" style="display: $display">
-$lt{'nums'} <input type="text" name="postsubtimeout" value="$postsubtimeout" $disabled /><br />
+<label>$lt{'nums'} <input type="text" name="postsubtimeout" value="$postsubtimeout" $disabled /></label><br />
 $zero</div>
 <p>
 $submit
@@ -1014,8 +1016,8 @@
         $lt{'categ'} = &mt('Categorize Community');
         $lt{'assi'} = &mt('Assign one or more subcategories to this community.');
     }
-    $r->print('<h3>'.$lt{'catset'}.'</h3>'."\n".
-              '<h4><span class="LC_nobreak">'.&mt($type).': '.$cdesc.'</span></h4>'."\n".
+    $r->print('<h2 class="LC_heading_2">'.$lt{'catset'}.'</h2>'."\n".
+              '<span class="LC_nobreak"><b>'.&mt($type).': '.$cdesc.'</b></span><br /><br />'."\n".
               '<form action="/adm/modifycourse" method="post" name="catsettings">'."\n");
     my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
     my @cat_params = &catalog_settable($domconf{'coursecategories'},$type);
@@ -1033,10 +1035,11 @@
                 $excludeon = $excludeoff;
                 $excludeoff = '';
             }
-            $r->print('<br /><h4>'.$lt{'visi'}.'</h4>'.
-                      '<p>'.
-                      $lt{'exclude'}.
-                      ' <label><input name="hidefromcat" type="radio" value="yes" '.$excludeon.$disabled.' />'.&mt('Yes').'</label>   <label><input name="hidefromcat" type="radio" value="" '.$excludeoff.$disabled.' />'.&mt('No').'</label></p><p>');
+            $r->print('<h3 class="LC_heading_3">'.$lt{'visi'}.'</h3>'.
+                      '<span aria-hidden="true">'.$lt{'exclude'}.'</span>'.
+                      '<fieldset class="LC_borderless">'.
+                      '<legend class="LC_visually_hidden">'.$lt{'exclude'}.'</legend>'.
+                      ' <label><input name="hidefromcat" type="radio" value="yes" '.$excludeon.$disabled.' />'.&mt('Yes').'</label>   <label><input name="hidefromcat" type="radio" value="" '.$excludeoff.$disabled.' />'.&mt('No').'</label></fieldset><br /><p>');
             if ($type eq 'Community') {
                 $r->print(&mt("If a community has been categorized using at least one of the categories defined for communities in the domain, it will be listed in the domain's publicly accessible Course/Community Catalog, unless excluded.").'</p>');
             } elsif ($type eq 'Placement') {
@@ -1055,7 +1058,7 @@
         }
         my $shownsave;
         if (grep(/^categorize$/, at cat_params)) {
-            my $categheader = '<br /><h4>'.$lt{'categ'}.'</h4>';
+            my $categheader = '<br /><h3 class="LC_heading_3">'.$lt{'categ'}.'</h3>';
             if (ref($domconf{'coursecategories'}) eq 'HASH') {
                 my $cathash = $domconf{'coursecategories'}{'cats'};
                 if (ref($cathash) eq 'HASH') {
@@ -1115,6 +1118,7 @@
             'sett' => 'Setting',
             'domd' => 'Domain default',
             'whom' => 'Who configures',
+            'seto' => 'Set course owner',
     );
     my ($ownertable,$ccrole,$javascript_validations,$authenitems,$ccname,$disabled);
     my %enrollvar = &get_enrollment_settings($cdom,$cnum);
@@ -1130,6 +1134,7 @@
     if ($crstype eq 'Community') {
         $ccrole = 'co';
         $lt{'nocc'} = &mt('There is currently no owner set for this community.');
+        $lt{'seto'} = &mt('Set community owner');
     } else {
         $ccrole ='cc';
         ($javascript_validations,$authenitems) = &gather_authenitems($cdom,\%enrollvar,$readonly);
@@ -1168,27 +1173,31 @@
     } else {
         my $numlocalcc = scalar(@local_ccs);
         $ownertable = '<input type="hidden" name="numlocalcc" value="'.$numlocalcc.'" />'.
-                      &Apache::loncommon::start_data_table()."\n".
+                      '<fieldset class="LC_borderless" style="line-height: 185%;">'.
+                      '<legend class="LC_visually_hidden">'.$lt{'seto'}.'</legend>'.
+                      &Apache::loncommon::start_data_table('LC_paramDefault')."\n".
                       &Apache::loncommon::start_data_table_header_row()."\n".
-                      '<th>'.$lt{'ownr'}.'</th>'.
+                      '<th id="courseownercol">'.$lt{'ownr'}.'</th>'.
                       '<th>'.$lt{'name'}.'</th>'.
                       '<th>'.$lt{'unme'}.'</th>'.
                       '<th>'.$lt{'stus'}.'</th>'.
                       &Apache::loncommon::end_data_table_header_row()."\n";
+        my $rownum = 0;
         foreach my $cc (@local_ccs) {
             $ownertable .= &Apache::loncommon::start_data_table_row()."\n";
+            my $checked = '';
             if ($cc eq $enrollvar{'courseowner'}) {
-                $ownertable .= '<td><input type="radio" name="courseowner" value="'.$cc.'" checked="checked"'.$disabled.' /></td>'."\n";
-            } else {
-                $ownertable .= '<td><input type="radio" name="courseowner" value="'.$cc.'"'.$disabled.' /></td>'."\n";
+                $checked = ' checked="checked"';
             }
             $ownertable .=
+                 '<td><input type="radio" name="courseowner" value="'.$cc.'"'.$checked.$disabled.' aria-labelledby="courseownercol usernamerow'.$rownum.'" /></td>'."\n".
                  '<td>'.$pname{$cc}.'</td>'."\n".
-                 '<td>'.$cc.'</td>'."\n".
+                 '<th id="usernamerow'.$rownum.'" scope="row" class="LC_rowheader">'.$cc.'</th>'."\n".
                  '<td>'.$cc_status{$cc}.' '.$ccname.'</td>'."\n".
                  &Apache::loncommon::end_data_table_row()."\n";
+            $rownum ++;
         }
-        $ownertable .= &Apache::loncommon::end_data_table();
+        $ownertable .= &Apache::loncommon::end_data_table().'</fieldset>';
     }
     &print_header($r,$crstype,$javascript_validations);
     my $dctitle = &Apache::lonnet::plaintext('dc');
@@ -1197,8 +1206,8 @@
     if (($type eq 'official') || ($type eq 'unofficial') || ($type eq 'textbook')) {
         $showtype = ' ('.&mt($type).')';
     }
-    $r->print('<h3>'.&modifiable_only_title($crstype).'</h3>'."\n".
-              '<h4><span class="LC_nobreak">'.&mt($crstype).': '.$cdesc.$showtype.'</span></h4><br />'."\n".
+    $r->print('<h2 class="LC_heading_2">'.&modifiable_only_title($crstype).'</h2>'."\n".
+              '<span class="LC_nobreak"><b>'.&mt($crstype).': '.$cdesc.$showtype.'</b></span><br /><br />'."\n".
               '<form action="/adm/modifycourse" method="post" name="'.$env{'form.phase'}.'">'."\n".
               &Apache::lonhtmlcommon::start_pick_box());
     if ($crstype eq 'Community') {
@@ -1209,8 +1218,8 @@
     } else {
         $r->print(&Apache::lonhtmlcommon::row_title(
                       &Apache::loncommon::help_open_topic('Modify_Course_Instcode').
-                      ' '.&mt('Course Code'))."\n".
-                  '<input type="text" size="15" name="coursecode" value="'.$enrollvar{'coursecode'}.'"'.$disabled.' />'.
+                      ' <label for="coursecode">'.&mt('Course Code').'</label>')."\n".
+                  '<input type="text" size="15" name="coursecode" id="coursecode" value="'.$enrollvar{'coursecode'}.'"'.$disabled.' />'.
                   &Apache::lonhtmlcommon::row_closure());
         if (($crstype eq 'Course') && (&showcredits($cdom))) {
             $r->print(&Apache::lonhtmlcommon::row_title(
@@ -1278,22 +1287,23 @@
         $r->print(&Apache::loncommon::start_data_table_row()."\n".
                  '<td>'.$selfenrolltitles->{$item}.'</td>'."\n".
                  '<td>'.&mt('[_1] configures',$default).'</td>'."\n".
-                 '<td>');
+                 '<td><fieldset class="LC_borderless" style="line-height: 185%;">'.
+                 '<legend class="LC_visually_hidden">'.&mt("Who configures $item?").'</legend>');
         foreach my $option ('','0','1') {
             $r->print('<span class="LC_nobreak"><label>'.
                       '<input type="radio" name="selfenrollmgr_'.$item.'" '.
                       'value="'.$option.'"'.$checked{$option}.$disabled.' />'.
                       $optionname{$option}.'</label></span><br />');
         }
-        $r->print('</td>'."\n".
+        $r->print('</fieldset></td>'."\n".
                   &Apache::loncommon::end_data_table_row()."\n");
     }
     $r->print(&Apache::loncommon::end_data_table()."\n".
               '<br />'.&Apache::lonhtmlcommon::row_closure().
               &Apache::lonhtmlcommon::row_title(
               &Apache::loncommon::help_open_topic('Modify_Course_Table_Lifetime').
-              ' '.&mt('"Temporary" Tables Lifetime (s)'))."\n".
-              '<input type="text" size="10" name="mysqltables" value="'.$settings{'internal.mysqltables'}.'"'.$disabled.' />'.
+              ' <label for="mysqltables">'.&mt('"Temporary" Tables Lifetime (s)').'</label>')."\n".
+              '<input type="text" size="10" name="mysqltables" id="mysqltables" value="'.$settings{'internal.mysqltables'}.'"'.$disabled.' />'.
               &Apache::lonhtmlcommon::row_closure(1).
               &Apache::lonhtmlcommon::end_pick_box().'<br />'.$hidden_elements);
     unless ($readonly) {
@@ -1416,15 +1426,18 @@
     my $hidden_elements = &hidden_form_elements();
     my $helpitem = &Apache::loncommon::help_open_topic($helpfile);
     my $showtype = &mt($type);
+    my $legendtext = &mt('Domain default or course-specific setting?');
     $r->print(<<ENDDOCUMENT);
-<h3>$helpitem $title</h3>
-<h4><span class="LC_nobreak">$showtype: $cdesc</span></h4>
+<h2 class="LC_heading_2">$helpitem $title</h2>
+<span class="LC_nobreak"><b>$showtype: $cdesc</b></span><br />
 <form action="/adm/modifycourse" method="post" name="set$item">
 <p><span class="LC_nobreak">$titles{'curd'}: <span style="font-style:italic">$domdefdisplay</span></span></p>
-<p><span class="LC_nobreak">
+<fieldset class="LC_borderless" style="line-height: 185%;">
+<legend class="LC_visually_hidden">$legendtext</legend>
+<span class="LC_nobreak">
 <label><input type="radio" name="${item}set" value="dom" onclick="toggleOptions(this.form,'set$item');"$checkeddom$disabled />$titles{'used'}</label></span><br />
 <span class="LC_nobreak">
-<label><input type="radio" name="${item}set" value="course" onclick="toggleOptions(this.form,'set$item');"$checkedcrs$disabled />$titles{'cour'}</label></span></p>
+<label><input type="radio" name="${item}set" value="course" onclick="toggleOptions(this.form,'set$item');"$checkedcrs$disabled />$titles{'cour'}</label></span></fieldset><br />
 <fieldset id="crs$item" style="$divsty">
 <legend>$titles{'valu'}</legend>
 $crselements
@@ -2005,8 +2018,8 @@
         $reply = $chgresponse.$nochgresponse.$warning;
     }
     &print_header($r,$type);
-    $reply = '<h3>'.&modifiable_only_title($type).'</h3>'."\n".
-             '<h4><span class="LC_nobreak">'.&mt($type).': '.$cdesc.'</span></h4>'."\n".
+    $reply = '<h2 class="LC_heading_2">'.&modifiable_only_title($type).'</h2>'."\n".
+             '<span class="LC_nobreak"><b>'.&mt($type).': '.$cdesc.'</b></span>'."\n".
              '<p>'.$reply.'</p>'."\n".
              '<form action="/adm/modifycourse" method="post" name="processparms">'.
              &hidden_form_elements();


More information about the LON-CAPA-cvs mailing list