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

raeburn raeburn at source.lon-capa.org
Sun Feb 8 17:51:05 EST 2026


raeburn		Sun Feb  8 22:51:05 2026 EDT

  Modified files:              
    /loncom/interface	lonrequestcourse.pm loncommon.pm 
  Log:
  - WCAG 2 compliance
    - Include landmark for page's main content to support "Skip to main content"
    - Include labels for form elements 
    - Group related form elements in fieldset with legend for screenreaders  
    - Sequential headings
    - Replace use of <table> with <div> for layout
  - Satisfy w3c validation  
  
  
-------------- next part --------------
Index: loncom/interface/lonrequestcourse.pm
diff -u loncom/interface/lonrequestcourse.pm:1.120 loncom/interface/lonrequestcourse.pm:1.121
--- loncom/interface/lonrequestcourse.pm:1.120	Wed Dec 24 18:36:07 2025
+++ loncom/interface/lonrequestcourse.pm	Sun Feb  8 22:51:04 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Request a course
 #
-# $Id: lonrequestcourse.pm,v 1.120 2025/12/24 18:36:07 raeburn Exp $
+# $Id: lonrequestcourse.pm,v 1.121 2026/02/08 22:51:04 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -175,6 +175,7 @@
                               '<div>'.
                               '<p class="LC_info">'.&mt('You do not have privileges to request creation of LTI courses.').'</p>'.
                               '</div>'.
+                              '</div>'.
                               &Apache::loncommon::end_page());
                 }
             }
@@ -204,9 +205,9 @@
                if ($warning ne '') {
                    my $args = { only_body => 1 };
                    $r->print(&header('Course/Community Requests','','' ,'',$args).
-                             '<h3>'.&mt('Course/Community Request Details').'</h3>'.
+                             '<h1 class="LC_heading_2">'.&mt('Course/Community Request Details').'</h1>'.
                              '<div class="LC_warning">'.$warning.'</div>'.
-                             &close_popup_form());
+                             &close_popup_form().'</div>');
                 } else {
                     $states{'display'} = ['details'];
                     my $loaditems = &onload_action($action,$state);
@@ -359,10 +360,11 @@
                                         $showcredits,$instcredits,\@invalidcrosslist);
             }
         } else {
-            $r->print(&header('Course/Community Requests').$crumb.
+            $r->print(&header('Course/Community Requests').$crumb."\n".
+                      '<div class="LC_landmark" role="main" id="LC_main_content">'."\n".
                       '<div class="LC_warning">'.
                       &mt('You do not have privileges to request creation of courses or communities.').
-                      '</div>'.&Apache::loncommon::end_page());
+                      '</div></div>'.&Apache::loncommon::end_page());
         }
     } elsif ($action eq 'view') {
         if ($state eq 'crstype') {
@@ -374,10 +376,11 @@
     } elsif ($action eq 'display') {
         if ($warning ne '') {
             my $args = { only_body => 1 };
-            $r->print(&header('Course/Community Requests','','' ,'',$args).$crumb.
-                      '<h3>'.&mt('Course/Community Request Details').'</h3>'.
+            $r->print(&header('Course/Community Requests','','' ,'',$args).$crumb."\n".
+                      '<div class="LC_landmark" role="main" id="LC_main_content">'."\n".
+                      '<h1 class="LC_heading_2">'.&mt('Course/Community Request Details').'</h1>'.
                       '<div class="LC_warning">'.$warning.'</div>'.
-                      &close_popup_form());
+                      &close_popup_form().'</div>');
         } else {
             &request_administration($r,$action,$state,$page,\%states,$dom,$jscript,
                                     $loaditems,$crumb,'','','','',$showcredits,'','',
@@ -860,17 +863,18 @@
             $earlyout = 1;
         }
     }
-    $r->print(&header($pagetitle,$js.$jscript,$loaditems).$crumb.
-             '<p>'.$pageinfo.'</p>');
+    $r->print(&header($pagetitle,$js.$jscript,$loaditems).$crumb."\n"
+             .'<div class="LC_landmark" role="main" id="LC_main_content">'."\n"
+             .'<p>'.$pageinfo.'</p>');
     if ($earlyout) {
-        $r->print(&Apache::loncommon::end_page());
+        $r->print('</div>'.&Apache::loncommon::end_page());
         return;
     }
     $r->print('<div>'.
               &Apache::lonhtmlcommon::start_pick_box().
-              &Apache::lonhtmlcommon::row_title($domaintitle).
+              &Apache::lonhtmlcommon::row_title('<label for="reqshowdom">'.$domaintitle.'</label>').
               '<form name="domforcourse" method="post" action="/adm/requestcourse">'.
-              &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange,$incdoms));
+              &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange,$incdoms,'','','reqshowdom'));
     if (!$onchange) {
         $r->print(' <input type="submit" name="godom" value="'.
                    &mt('Change').'" />');
@@ -878,23 +882,23 @@
     unless ((ref($can_request) eq 'HASH') && (keys(%{$can_request}) > 0)) {
         $r->print('</form>'.&Apache::lonhtmlcommon::row_closure(1)."\n".
                   &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n".
-                  &Apache::loncommon::end_page());
+                  '</div>'.&Apache::loncommon::end_page());
         return;
     }
     $r->print('</form>'.&Apache::lonhtmlcommon::row_closure());
     my $formname = 'requestcrs';
     my $nexttext = &mt('Next');
-    $r->print(&Apache::lonhtmlcommon::row_title(&mt('Action')).'
+    $r->print(&Apache::lonhtmlcommon::row_title('<label for="reqaction">'.&mt('Action').'</label>').'
 <form name="mainmenu_action" method="post" action=""> 
-<select size="1" name="action" >
+<select size="1" name="action" id="reqaction">
  <option value="new">'.&mt('New request').'</option>
  <option value="view">'.&mt('View/Modify/Cancel pending requests').'</option>
  <option value="log">'.&mt('View request history').'</option>
 </select></form>'.
               &Apache::lonhtmlcommon::row_closure().
-              &Apache::lonhtmlcommon::row_title(&mt('Type')).'
+              &Apache::lonhtmlcommon::row_title('<label for="reqtype">'.&mt('Type').'</label>').'
 <form name="mainmenu_coursetype" method="post" action="">
-<select size="1" name="crstype">');
+<select size="1" name="crstype" id="reqtype">');
     if (ref($can_request) eq 'HASH') {
         if (keys(%{$can_request}) > 1) {
             $r->print(' <option value="any">'.&mt('All types').'</option>');
@@ -928,7 +932,7 @@
               '<input type="button" name="next" value="'.$nexttext.
               '" onclick="javascript:nextPage(document.'.$formname.')" />'."\n".
               '</form></div>');
-    $r->print(&Apache::loncommon::end_page());
+    $r->print('</div>'.&Apache::loncommon::end_page());
     return;
 }
 
@@ -976,7 +980,8 @@
         } else {
             $title = 'Request a course';
         }
-        $r->print(&header($title,$js.$jscript,$loaditems,$jsextra).$crumb);
+        $r->print(&header($title,$js.$jscript,$loaditems,$jsextra).$crumb."\n".
+                  '<div class="LC_landmark" role="main" id="LC_main_content">'."\n");
         &print_request_form($r,$action,$state,$page,$states,$dom,$newinstcode,
                             $codechk,$checkedcode,$description,$showcredits,
                             $instcredits,$invalidcrosslist);
@@ -1000,7 +1005,8 @@
         } else {
             $title = 'Manage course requests';
         }
-        $r->print(&header($title,$js.$jscript.$jsextra,$loaditems).$crumb);
+        $r->print(&header($title,$js.$jscript.$jsextra,$loaditems).$crumb."\n".
+                  '<div class="LC_landmark" role="main" id="LC_main_content">'."\n");
         my $form = '<form method="post" name="'.$formname.'" action="/adm/requestcourse" />';
         if ($state eq 'pick_request') {
             my $title;
@@ -1017,7 +1023,7 @@
             } else {
                 $title = &mt('Pending course/community requests'); 
             }
-            $r->print('<h3>'.$title.'</h3><div>'."\n".$form."\n".
+            $r->print('<h2 class="LC_heading_2">'.$title.'</h2><div>'."\n".$form."\n".
                       &print_request_status($dom,$action).'</form></div>');
         } elsif ($state eq 'details') {
             my (@codetitles,%cat_titles,%cat_order, at code_order,$instcode,$code_chk);
@@ -1138,13 +1144,15 @@
             $header = &mt('Course Request');
         }
         $r->print(&header($title,'','','',{ 'only_body' => 1}).
-                  $crumb."\n".'<h3>'.$header.'</h3>'.
+                  $crumb."\n".
+                  '<div class="LC_landmark" role="main" id="LC_main_content">'."\n".
+		  '<h1 class="LC_heading_2">'.$header.'</h1>'.
                   &print_review($dom,\@codetitles,\%cat_titles,\%cat_order,
                                 \@code_order,$uname,$udom,'','',$instcredits)."\n".
                   '</div>'.
                   &close_popup_form());
     }
-    $r->print(&Apache::loncommon::end_page());
+    $r->print('</div>'.&Apache::loncommon::end_page());
     return;
 }
 
@@ -1570,9 +1578,9 @@
         &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
                                                  \%cat_order,\@code_order);
         if ($crstype eq 'community') {
-            $r->print('<h3>'.&mt('Review community request details before submission').'</h3>');
+            $r->print('<h2 class="LC_heading_2">'.&mt('Review community request details before submission').'</h2>');
         } else {
-            $r->print('<h3>'.&mt('Review course request details before submission').'</h3>');
+            $r->print('<h2 class="LC_heading_2">'.&mt('Review course request details before submission').'</h2>');
         }
         $r->print(&print_review($dom,\@codetitles,\%cat_titles,\%cat_order,\@code_order,'','',\@disallowed,\%disallowmsg,$instcredits).
                   '<input type="hidden" name="cnum" value="'.$cnum.'" />');
@@ -1921,7 +1929,6 @@
     my $access_dates = 
         &date_setting_table($starttime,$endtime,$formname,'access',$hasauto,
                             $hascredits,%accesstitles);
-    $output .= &Apache::lonhtmlcommon::start_pick_box();
     if ($sections) {
         $output .=  $sections;
     }
@@ -1937,13 +1944,13 @@
             $header = &mt('Access dates for community members');
         }
         $output .= &Apache::lonhtmlcommon::row_headline('Access').
-                   '<h3>'.$header.'</h3>'.
+                   '<h2 class="LC_heading_2">'.$header.'</h2>'.
                    &Apache::lonhtmlcommon::row_closure(1).
                    $access_dates;
     }
     if ($creditsrow) {
         $output .= &Apache::lonhtmlcommon::row_headline('Credits').
-                   '<h3>'.&mt('Credits earned by students').'</h3>'.
+                   '<h2 class="LC_heading_2">'.&mt('Credits earned by students').'</h2>'.
                    &Apache::lonhtmlcommon::row_closure(1).
                    &Apache::lonhtmlcommon::row_title(&mt('Default credits')).
                    $creditsrow.
@@ -2090,7 +2097,8 @@
 
     my @currsecs = &current_lc_sections();
 
-    my ($existtitle,$existops,$existmult,$newtitle,$seccolspan);
+    my ($existtitle,$existops,$existmult,$newtitle,$seccolspan,$seclabelexist,$seclabelnew);
+    $seclabelnew = &mt('Assign to a section');
     if (@currsecs) {
         my $existsize = scalar(@currsecs);
         if ($existsize > 3) {
@@ -2101,12 +2109,14 @@
         }
         @currsecs = sort { $a <=> $b } (@currsecs);
         $existtitle = &mt('Official').': ';
+        $seclabelexist = &mt('Assign to existing section(s)');
         $existops = '<option value="">'.&mt('None').'</option>';
         foreach my $sec (@currsecs) {
             $existops .= '<option value="'.$sec.'">'.$sec.'</option>'."\n";
         }
         $seccolspan = ' colspan="2"';
         $newtitle = &mt('Other').': ';
+        $seclabelnew = &mt('Assign to another section');
     }
 
     if ($persontotal) {
@@ -2118,7 +2128,8 @@
         $lt{'textbook'} = $lt{'official'};
         $lt{'placement'} = $lt{'official'};
         $output .= &Apache::lonhtmlcommon::row_headline().
-                  '<h3>'.&Apache::loncommon::help_open_topic('Course_Request_Personnel').' '.$lt{$crstype}.' '.&mt('Include other personnel?').'</h3>';
+                   '<h2 class="LC_heading_2">'.&Apache::loncommon::help_open_topic('Course_Request_Personnel').' '.$lt{$crstype}.' '.&mt('Include other personnel?').'</h2>'.
+                   &Apache::lonhtmlcommon::row_closure(1);
     }
     my $cansearch = 1;
     my @alldoms = &Apache::lonnet::all_domains();
@@ -2133,30 +2144,32 @@
         }
     }
     my ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$dom);
+    my $gridcolsty = ' style="grid-column-start: 2; grid-column-end: 4;"';
     for (my $i=0; $i<$persontotal; $i++) {
         my @linkargs = map { 'person_'.$i.'_'.$_ } (@items);
         my $linkargstr = join("','", at linkargs);
-        my $uname_form = '<input type="text" name="person_'.$i.'_uname" value="" size="20" />';
+        my $uname_form = '<input type="text" name="person_'.$i.'_uname" id="person_'.$i.'_uname" value="" size="20" />';
         my $onchange = 'javascript:fix_domain('."'$formname','person_".$i."_dom',".
                        "'person_".$i."_hidedom','person_".$i."_uname'".');';
         my $udom_form = &Apache::loncommon::select_dom_form($dom,'person_'.$i.'_dom','',
-                                                            1,$onchange,undef,$trusted,$untrusted).
+                                                            1,$onchange,$trusted,$untrusted,
+                                                            '','person_'.$i.'_dom').
                         '<input type="hidden" name="person_'.$i.'_hidedom" value="" />';
         my %form_elems;
         foreach my $item (@items) {
             next if (($item eq 'dom') || ($item eq 'uname') || ($item eq 'hidedom'));
             $form_elems{$item} = '<input type="text" name="person_'.$i.'_'.$item.'" '.
-                                 'value="" readonly="readonly" />';
+                                 'id="person_'.$i.'_'.$item.'" value="" readonly="readonly" />';
         }
-        my $roleselector = '<select name="person_'.$i.'_role">'."\n".
+        my $roleselector = '<select name="person_'.$i.'_role" id="person_'.$i.'_role">'."\n".
                            $roleoptions.'</select>';
         my $sectionselector;
         if (@currsecs) {
             $sectionselector = $existtitle.'<select name="person_'.$i.'_sec"'.
-                               $existmult.'>'."\n".$existops.'</select>'.(' ' x3);
+                               $existmult.' aria-label="'.$seclabelexist.'">'."\n".$existops.'</select>'.(' ' x3);
         }
         $sectionselector .= $newtitle.
-            '<input type="text" name="person_'.$i.'_newsec" size="15" value="" />'."\n";
+            '<input type="text" name="person_'.$i.'_newsec" size="15" value="" aria-label="'.$seclabelnew.'" />'."\n";
         my $usersrchlink;
         if ($cansearch) {
             my $usersrchlinktxt = &mt('Search for user');
@@ -2170,22 +2183,24 @@
                             $userchklinktxt,'checkusername');
         $output .= 
             &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel')).
-            '<table><tr><td align="center" valign="middle"><b>'.$usersrchlink.'</b></td>'."\n".
-            '<td align="left" valign="top" colspan="2"><span class="LC_nobreak">'.
-            &mt('Username').': '.$uname_form.' '.$userchklink.'</span><br />'."\n".
-            '<span class="LC_nobreak">'.&mt('Domain').': '.$udom_form.'</span></td>'.
-            '</tr>'."\n".'<tr>'.
-            '<td align="center" valign="top">'.&mt('First Name').'<br />'.$form_elems{'firstname'}.'</td>'."\n".
-            '<td align="center" valign="top">'.&mt('Last Name').'<br />'.$form_elems{'lastname'}.'</td>'."\n".
-            '<td align="center" valign="top">'.&mt('E-mail').'<br />'.$form_elems{'emailaddr'}.'</td></tr>'."\n".
-            '<tr><td align="center" valign="top">'.&Apache::loncommon::help_open_topic('Course_Roles').' '.&mt('Role').'<br />'.$roleselector.'</td>'."\n".
-            '<td'.$seccolspan.' align="center" valign="top">'.
-            &Apache::loncommon::help_open_topic('Course_Request_Rolesection').' '.&mt('LON-CAPA Section(s)').'<br />'.$sectionselector.'</td>'."\n".
-            '</tr></table>'.&Apache::lonhtmlcommon::row_closure();
+            '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+            &mt('Additional Personnel').'</legend>'.
+            '<div class="LC_reqcrs_people">'.
+            '<div class="LC_reqcrs_gridcell LC_center"><b>'.$usersrchlink.'</b></div>'."\n".
+            '<div'.$gridcolsty.' class="LC_reqcrs_gridcell"><div class="LC_touch_target"><span class="LC_nobreak">'.
+            '<label for="person_'.$i.'_uname">'.&mt('Username').'</label>: '.$uname_form.' '.$userchklink.'</span></div>'."\n".
+            '<div class="LC_touch_target"><span class="LC_nobreak"><label for="person_'.$i.'_dom">'.&mt('Domain').'</label>: '.$udom_form.'</span></div></div>'."\n".
+            '<div class="LC_reqcrs_gridcell LC_center"><label for="person_'.$i.'_firstname">'.&mt('First Name').'</label><br />'.$form_elems{'firstname'}.'</div>'."\n".
+            '<div class="LC_reqcrs_gridcell LC_center"><label for="person_'.$i.'_lastname">'.&mt('Last Name').'</label><br />'.$form_elems{'lastname'}.'</div>'."\n".
+            '<div class="LC_reqcrs_gridcell LC_center"><label for="person_'.$i.'_emailaddr">'.&mt('E-mail').'</label><br />'.$form_elems{'emailaddr'}.'</div>'."\n".
+            '<div class="LC_reqcrs_gridcell LC_center ">'.&Apache::loncommon::help_open_topic('Course_Roles').' <label for="person_'.$i.'_role">'.&mt('Role').'</label><br />'.$roleselector.'</div>'."\n".
+            '<div'.$gridcolsty.' class="LC_reqcrs_gridcell LC_center">'.
+            &Apache::loncommon::help_open_topic('Course_Request_Rolesection').' '.&mt('LON-CAPA Section(s)').'<br />'.$sectionselector.'</div>'."\n".
+            '</div></fieldset>'.&Apache::lonhtmlcommon::row_closure();
     }
-    $output .= &Apache::lonhtmlcommon::row_title(&mt('Add another')).
+    $output .= &Apache::lonhtmlcommon::row_title('<label for="addperson">'.&mt('Add another').'</label>').
                '<input name="persontotal" type="hidden" value="'.$persontotal.'" />'.
-               '<input name="addperson" type="checkbox" value="'.$persontotal.'"'.
+               '<input name="addperson" id="addperson" type="checkbox" value="'.$persontotal.'"'.
                ' onclick="javascript:nextPage(document.'.$formname.",'".$env{'form.state'}.
                "'".');" />'.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1).
                &Apache::lonhtmlcommon::end_pick_box().'</div>';
@@ -2491,7 +2506,8 @@
     } else {
         $title = 'Course Request Logs';
     }
-    $r->print(&header($title,$jscript,$loaditems).$crumb);
+    $r->print(&header($title,$jscript,$loaditems).$crumb."\n".
+              '<div class="LC_landmark" role="main" id="LC_main_content">'."\n");
     if ($usetabs) {
         &startContentScreen($r,'textbooklogs');
     }
@@ -2531,7 +2547,7 @@
     my $showntablehdr = 0;
     my $tablehdr = &Apache::loncommon::start_data_table().
                    &Apache::loncommon::start_data_table_header_row().
-                   '<th> </th><th>'.&mt('Request Date').'</th>'.
+                   '<th>#</th><th>'.&mt('Request Date').'</th>'.
                    '<th>'.&mt('Description').'</th>';
     if ($curr{'crstype'} eq 'any') {
         $tablehdr .= '<th>'.&mt('Course Type').'</th>';
@@ -2698,7 +2714,7 @@
     if ($usetabs) {
         &endContentScreen($r);
     }
-    $r->print(&Apache::loncommon::end_page());
+    $r->print('</div>'.&Apache::loncommon::end_page());
     return;
 }
 
@@ -2724,11 +2740,12 @@
 sub requestlog_display_filter {
     my ($formname,$curr) = @_;
     my $nolink = 1;
-    my $output = '<table><tr><td valign="top">'.
-                 '<span class="LC_nobreak"><b>'.&mt('Records/page:').'</b></span><br />'.
-                 &Apache::lonmeta::selectbox('show',$curr->{'show'},'','',undef,
+    my $output = '<div class="LC_left_float" style="padding: 0; vertical-align: top">'.
+                 '<span class="LC_nobreak"><b><label for="show">'.&mt('Records/page:').
+                 '</label></b></span><br />'.
+                 &Apache::lonmeta::selectbox('show',$curr->{'show'},'','show',undef,
                                               (&mt('all'),5,10,20,50,100,1000,10000)).
-                 '</td><td>  </td>';
+                 '</div>';
     my $startform =
         &Apache::lonhtmlcommon::date_setter($formname,'requested_after_date',
                                             $curr->{'requested_after_date'},undef,
@@ -2737,18 +2754,25 @@
         &Apache::lonhtmlcommon::date_setter($formname,'requested_before_date',
                                             $curr->{'requested_before_date'},undef,
                                             undef,undef,undef,undef,undef,undef,$nolink);
-    $output .= '<td valign="top"><b>'.&mt('Window during which course/community was requested:').'</b><br />'.
-               '<table><tr><td>'.&mt('After:').
-               '</td><td>'.$startform.'</td></tr>'.
-               '<tr><td>'.&mt('Before:').'</td>'.
-               '<td>'.$endform.'</td></tr></table>'.
-               '</td>'.
-               '<td>  </td>';
+    $output .= '<div class="LC_left_float" style="padding: 0 2px 0 0; vertical-align: top">'.
+               '<b>'.&mt('Window during which course/community was requested:').'</b>'.
+               '<div style="padding-top: 0; margin-top:0; vertical-align: top" role="grid" class="LC_grid">'.
+               '<div role="row" class="LC_grid_row">'.
+               '<div role="gridcell" class="LC_grid_cell">'.
+               &mt('After:').'</div>'.
+               '<div role="gridcell" class="LC_grid_cell">'.$startform.'</div>'.
+               '</div>'.
+               '<div role="row" class="LC_grid_row">'.
+               '<div role="gridcell" class="LC_grid_cell">'.
+               &mt('Before:').'</div>'.
+               '<div role="gridcell" class="LC_grid_cell">'.$endform.'</div>'.
+               '</div></div></div>';
     my ($types,$typenames) = &Apache::loncommon::course_types();
     if (ref($types) eq 'ARRAY') {
         if (@{$types} > 1) {
-            $output .= '<td valign="top"><b>'.
-                       &mt('Course Type:').'</b><br /><select name="crstype">';
+            $output .= '<div class="LC_left_float" style="padding: 0; vertical-align: top">'.
+                       '<b><label for="crstype">'.
+                       &mt('Course Type:').'</label></b><br /><select name="crstype" id="crstype">';
             my $selstr = '';
             if ($curr->{'crstype'} eq 'any') {
                 $selstr = ' selected="selected"';
@@ -2767,14 +2791,16 @@
                 }
                 $output .= '<option value="'.$crstype.'"'.$selstr.'>'.&mt($typename).'</option>'."\n";
             }
-            $output .= '</select></td>';
+            $output .= '</select></div>';
         }
     }
     my ($statuses,$statusnames) = &reqstatus_names($curr->{'crstype'});
     if (ref($statuses) eq 'ARRAY') {
         if (@{$statuses} > 1) {
-            $output .= '<td valign="top"><b>'.
-                       &mt('Request Status:').'</b><br /><select name="status">';
+            $output .= '<div class="LC_left_float" style="padding: 0; vertical-align: top">'.
+                       '<b><label for="status">'.
+                       &mt('Request Status:').'</label></b><br />'.
+                       '<select name="status" id="status">';
             my $selstr = '';
             if ($curr->{'status'} eq 'any') {
                 $selstr = ' selected="selected"';
@@ -2793,13 +2819,12 @@
                 }
                 $output .= '<option value="'.$status.'"'.$selstr.'>'.$statusname.'</option>'."\n";
             }
-            $output .= '</select></td>';
+            $output .= '</select></div>';
         }
     }
-    $output .= '</tr></table>';
 
     # Update Display button
-    $output .= '<p>'.
+    $output .= '<div style="padding:0;clear:both;margin:0;border:0"></div><p>'.
                '<input type="submit" value="'.&mt('Update Display').'" />'.
                '</p><hr />';
     return $output;
@@ -3168,29 +3193,31 @@
     }
     my $output .= $js_validate."\n".&Apache::lonhtmlcommon::start_pick_box().
                   &Apache::lonhtmlcommon::row_headline().
-                  '<h3>'.&Apache::loncommon::help_open_topic('Course_Request_Description').' '.$title.'</h3>'.
+                  '<h2 class="LC_heading_2">'.&Apache::loncommon::help_open_topic('Course_Request_Description').' '.$title.'</h2>'.
                   &Apache::lonhtmlcommon::row_closure(1).
-                  &Apache::lonhtmlcommon::row_title(&mt('Description')).
-                 '<input type="text" size="60" name="cdescr" value="'.$description.'" />';
+                  &Apache::lonhtmlcommon::row_title('<label for="cdescr">'.&mt('Description').'</label>').
+                 '<input type="text" size="60" name="cdescr" id="cdescr" value="'.$description.'" />';
     my ($home_server_pick,$numlib) =
         &Apache::loncommon::home_server_form_item($dom,'chome',
-                                                  'default','hide');
+                                                  'default','hide','chome');
     if ($numlib > 1) {
         $output .= &Apache::lonhtmlcommon::row_closure().
-                   &Apache::lonhtmlcommon::row_title(&mt('Home Server for Course'));
+                   &Apache::lonhtmlcommon::row_title('<label for="chome">'.&mt('Home Server for Course').'</label>');
     }
     $output .= $home_server_pick.
                &Apache::lonhtmlcommon::row_closure().
                &Apache::lonhtmlcommon::row_headline().
-               '<h3>'.&Apache::loncommon::help_open_topic('Course_Request_Clone').' '.$clonetitle.
+               '<h2 class="LC_heading_2">'.&Apache::loncommon::help_open_topic('Course_Request_Clone').' '.$clonetitle.'</h2>'.
                &Apache::lonhtmlcommon::row_closure(1).
                &Apache::lonhtmlcommon::row_title(&mt('Clone?')).
+               '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+               &mt('Clone?').'</legend>'.
                '<label><input type="radio" name="cloning" value="1" '.
                'onclick="javascript:toggleCloning()" />'.
                &mt('Yes').(' 'x2).'</label><label>'.
                '<input type="radio" name="cloning" value="0" checked="checked" '.
                'onclick="javascript:toggleCloning()" />'.&mt('No').'</label>'.
-               '</h3>'.
+               '</fieldset>'.
                &Apache::lonhtmlcommon::row_closure(1).
                &Apache::lonhtmlcommon::row_headline().
                '<div id="cloneoptions" style="display: none" >'.
@@ -3214,27 +3241,33 @@
         &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'<label>'.
         &Apache::loncommon::select_dom_form($dom,'clonedom').'</label>'.
         &Apache::lonhtmlcommon::row_closure(1).
-        &Apache::lonhtmlcommon::row_title($lt{'cid'}).'<label>'.
-        '<input type="text" size="25" name="clonecrs" value="" onfocus="this.blur();opencrsbrowser('."'$formname','clonecrs','clonedom','','','','$type'".')" />'.
-        '</label> '.
+        &Apache::lonhtmlcommon::row_title('<label for="clonecrs">'.$lt{'cid'}.'</label>').
+        '<input type="text" size="25" name="clonecrs" id="clonecrs" value="" onfocus="this.blur();opencrsbrowser('."'$formname','clonecrs','clonedom','','','','$type'".')" />'.
+        ' '.
         &Apache::loncommon::selectcourse_link($formname,'clonecrs','clonedom','','','',$type).
         &Apache::lonhtmlcommon::row_closure(1).
-        &Apache::lonhtmlcommon::row_title($lt{'dsh'}).'<label>'.
+        &Apache::lonhtmlcommon::row_title($lt{'dsh'}).
+        '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+        $lt{'dsh'}.'</legend><label>'.
         '<input type="radio" name="datemode" value="delete" /> '.$lt{'ncd'}.
         '</label><br /><label>'.
         '<input type="radio" name="datemode" value="preserve" /> '.$lt{'prd'}.
         '</label><br /><label>'.
         '<input type="radio" name="datemode" value="shift" checked="checked" /> '.
         $lt{'shd'}.'</label>'.
-        '<input type="text" size="5" name="dateshift" value="364" />'.
+        '<input type="text" size="5" name="dateshift" value="364" aria-label="'.$lt{'num'}.'" />'.
+        '</fieldset>'.
         &Apache::lonhtmlcommon::row_closure(1).
-        &Apache::lonhtmlcommon::row_title($lt{'dpl'}).'<label>'.
+        &Apache::lonhtmlcommon::row_title($lt{'dpl'}).
+        '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+        $lt{'dpl'}.'</legend><label>'.
         '<input type="radio" name="tinyurls" value="delete" /> '.$lt{'nsl'}.
         '</label><br /><label>'.
         '<input type="radio" name="tinyurls" value="transfer" /> '.$lt{'tsl'}.
         '</label><br /><label>'.
         '<input type="radio" name="tinyurls" value="create" checked="checked" /> '.$lt{'csl'}.
         '</label>'.
+        '</fieldset>'.
         &Apache::lonhtmlcommon::row_closure(1);
     return $output;
 }
@@ -3248,6 +3281,7 @@
                'ncd'  => 'Do not clone date parameters',
                'prd'  => 'Clone date parameters as-is',
                'shd'  => 'Shift date parameters by number of days',
+               'num'  => 'Number of days to shift dates forward',
                'dpl'  => 'URL shortcuts (for deep linking)',
                'nsl'  => 'Do not clone URL shortcuts',
                'tsl'  => 'Transfer URL shortcuts from existing course to new course',
@@ -5106,7 +5140,7 @@
     unless ($crstype eq 'lti') {
         &endContentScreen($r);
     }
-    $r->print(&Apache::loncommon::end_page());
+    $r->print('</div>'.&Apache::loncommon::end_page());
     return;
 }
 
@@ -5338,7 +5372,7 @@
     unless ($crstype eq 'lti') {
         &endContentScreen($r);
     }
-    $r->print(&Apache::loncommon::end_page());
+    $r->print('</div>'.&Apache::loncommon::end_page());
 }
 
 sub textbook_request_javascript {
@@ -5538,6 +5572,7 @@
          }
     }
     $r->print('</div>'.
+              '</div>'.
               &Apache::loncommon::end_page());
     return;
 }
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1508 loncom/interface/loncommon.pm:1.1509
--- loncom/interface/loncommon.pm:1.1508	Fri Feb  6 19:04:59 2026
+++ loncom/interface/loncommon.pm	Sun Feb  8 22:51:04 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1508 2026/02/06 19:04:59 raeburn Exp $
+# $Id: loncommon.pm,v 1.1509 2026/02/08 22:51:04 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -7949,6 +7949,19 @@
   background-color: $data_table_light;
 }
 
+div.LC_reqcrs_people {
+  display: grid;
+  grid-template-columns: auto auto auto;
+  place-items: center;
+  margin: 0;
+  padding: 0;
+}
+
+div.LC_reqcrs_gridcell {
+  margin: 0;
+  padding: 2px;
+}
+
 div.LC_autoenroll_heading {
   margin: 5px;
   padding: 5px;


More information about the LON-CAPA-cvs mailing list