[LON-CAPA-cvs] cvs: loncom /homework grades.pm /interface loncommon.pm lonhelper.pm lonpickcode.pm lonprintout.pm lonquickgrades.pm

raeburn raeburn at source.lon-capa.org
Fri Jun 19 09:19:49 EDT 2026


raeburn		Fri Jun 19 13:19:49 2026 EDT

  Modified files:              
    /loncom/interface	loncommon.pm lonhelper.pm lonpickcode.pm 
                     	lonprintout.pm lonquickgrades.pm 
    /loncom/homework	grades.pm 
  Log:
  - WCAG 2 compliance
    - Replace use of <table> for layout with <div>.
    - Include labels for form elements.
    - 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.
    - Satisfy minimum spacing between touch targets.
    - Contrast ratio of at least 4.5:1 for normal text.
    - Sequential headings.
  - Satisfy w3c validation
  - Landmark for page's main content to support "Skip to main content" placed
    after large Tabs (Points Overview ... Problem Grading) to simplify keyboard
    only intercations.
  
  
-------------- next part --------------
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1528 loncom/interface/loncommon.pm:1.1529
--- loncom/interface/loncommon.pm:1.1528	Tue Jun  9 05:57:42 2026
+++ loncom/interface/loncommon.pm	Fri Jun 19 13:19:46 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1528 2026/06/09 05:57:42 raeburn Exp $
+# $Id: loncommon.pm,v 1.1529 2026/06/19 13:19:46 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -5258,15 +5258,19 @@
           $msg = &mt('Nothing submitted - no attempts.');
       }
       $prevattempts=
-	  &start_data_table().&start_data_table_row().
-	  '<td>'.$msg.'</td>'.
-	  &end_data_table_row().&end_data_table();
+           '<div class="LC_grid" role="grid" style="border: 1px solid black;">'
+          .'<div class="LC_grid_row" role="row">'
+          .'<div class="LC_grid_cell" role="gridcell">'
+          .$msg
+          .'</div></div></div>';
     }
   } else {
     $prevattempts=
-	  &start_data_table().&start_data_table_row().
-	  '<td>'.&mt('No data.').'</td>'.
-	  &end_data_table_row().&end_data_table();
+           '<div class="LC_grid" role="grid" style="border: 1px solid black;">'
+          .'<div class="LC_grid_row" role="row">'
+          .'<div class="LC_grid_cell" role="gridcell">'
+          .&mt('No data.')
+          .'</div></div></div>'; 
   }
 }
 
@@ -5374,6 +5378,7 @@
   $userview=~s/\<\/html\>//gi;
   $userview=~s/\<head\>//gi;
   $userview=~s/\<\/head\>//gi;
+  $userview=~s/\Qhref="#LC_main_content" class="LC_skip-to-main-content-link"\E/href="#" class="LC_hidden"/;
   $userview=~s/\Q<div class="LC_landmark" role="main" id="LC_main_content"\E/<div class="LC_landmark"/; 
   $userview=~s/action\s*\=/would_be_action\=/gi;
   $userview=&relative_to_absolute($feedurl,$userview);
@@ -7742,7 +7747,7 @@
 }
 
 .LC_internal_info {
-  color: #999999;
+  color: #525252;
 }
 
 .LC_discussion {
@@ -8077,6 +8082,7 @@
   background-color: $data_table_darker;
 }
 
+table.LC_data_table tr th.LC_leftcol_header,
 table.LC_data_table tr td.LC_leftcol_header {
   background-color: $data_table_head;
   font-weight: bold;
Index: loncom/interface/lonhelper.pm
diff -u loncom/interface/lonhelper.pm:1.210 loncom/interface/lonhelper.pm:1.211
--- loncom/interface/lonhelper.pm:1.210	Tue May 12 04:24:57 2026
+++ loncom/interface/lonhelper.pm	Fri Jun 19 13:19:46 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # .helper XML handler to implement the LON-CAPA helper
 #
-# $Id: lonhelper.pm,v 1.210 2026/05/12 04:24:57 raeburn Exp $
+# $Id: lonhelper.pm,v 1.211 2026/06/19 13:19:46 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1512,7 +1512,7 @@
 	    $result .= '<div role="gridcell" class="LC_grid_cell">'
                       .'<input type="text" size="5" name="'
                       .$choice->[4].'_forminput" value="'
-                      .$choice->[5].'" /></div>';
+                      .$choice->[5].'" aria-label="'.$choiceLabel.'" /></div>';
 	}
 	$result .= "</div>\n";
     }
Index: loncom/interface/lonpickcode.pm
diff -u loncom/interface/lonpickcode.pm:1.18 loncom/interface/lonpickcode.pm:1.19
--- loncom/interface/lonpickcode.pm:1.18	Fri Jun 19 04:54:32 2026
+++ loncom/interface/lonpickcode.pm	Fri Jun 19 13:19:46 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Pick a CODE from the list of possible CODEs
 #
-# $Id: lonpickcode.pm,v 1.18 2026/06/19 04:54:32 raeburn Exp $
+# $Id: lonpickcode.pm,v 1.19 2026/06/19 13:19:46 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -73,7 +73,7 @@
 		  &Apache::loncommon::end_page());
         return OK;
     }
-    if      ($env{'form.command'} eq 'codelist') {
+    if ($env{'form.command'} eq 'codelist') {
 	&code_list($r);
     } elsif ($env{'form.command'} eq 'showcodes') {
 	&show_codes($r);
@@ -106,14 +106,19 @@
      '.&Apache::loncommon::start_data_table($extra_css).'
        '.&Apache::loncommon::start_data_table_header_row());
     $r->print('<th>');
-    $r->print($table_head);
+    $r->print('<label for="view_scantron_CODElist">'.$table_head.'</label>');
     $r->print('</th>');
     $r->print('
        '.&Apache::loncommon::end_data_table_header_row().'
        '.&Apache::loncommon::start_data_table_row());
     $r->print('<td>');
-    $r->print("<input type='submit' name='submit' value='".&mt("View:")."' /> ");
-    $r->print(&Apache::grades::scantron_CODElist());
+    my $code_selector = &Apache::grades::scantron_CODElist('view');
+    if ($code_selector eq '') {
+        print(&mt('No saved CODEs available'));
+    } else {
+        $r->print('<input type="submit" name="submit" value="'.&mt('View:').'" />'
+                 .$code_selector);
+    }
     $r->print('</td>');
     $r->print('
        '.&Apache::loncommon::end_data_table_row().'
@@ -122,21 +127,23 @@
     $r->print("<input type='hidden' name='symb' value='".$env{'form.symb'}."' />");
     $r->print("<input type='hidden' name='url' value='".$env{'form.url'}."' />");
     $r->print("</form>");
-    
+
 }
 
 sub show_codes {
     my ($r)=@_;
     $r->print(&Apache::loncommon::start_page("View CODEs",undef,
-					     {'no_nav_bar' => 1}));
+					     {'no_nav_bar' => 1}).
+              '<div class="LC_landmark" role="main" id="LC_main_content">');
     my %codes=&Apache::grades::get_codes();
-    $r->print("<h2>".$env{'form.scantron_CODElist'}."</h2>");
+    $r->print('<h1 class="LC_heading_2">'.$env{'form.scantron_CODElist'}.'</h1>');
     $r->print('<pre>');
     foreach my $code (sort(keys(%codes))) {
 	$r->print($code."\n");
     }
     $r->print('</pre>');
     &code_list($r,1);
+    $r->print('</div>');
 }
 
 sub picking_a_code {
Index: loncom/interface/lonprintout.pm
diff -u loncom/interface/lonprintout.pm:1.721 loncom/interface/lonprintout.pm:1.722
--- loncom/interface/lonprintout.pm:1.721	Mon May 11 23:31:31 2026
+++ loncom/interface/lonprintout.pm	Fri Jun 19 13:19:46 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Printout
 #
-# $Id: lonprintout.pm,v 1.721 2026/05/11 23:31:31 raeburn Exp $
+# $Id: lonprintout.pm,v 1.722 2026/06/19 13:19:46 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -600,7 +600,8 @@
     }
     return <<RESOURCE_SELECTOR;
     <state name="$this_state" title="$title">
-    <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
+    <message><br /><span class="LC_fontsize_large"><b>How should the results be printed?</b></span><br />
+    </message>
     <choices variable="EMPTY_PAGES">
       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
@@ -608,7 +609,7 @@
       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
     </choices>
     <nextstate>PAGESIZE</nextstate>
-    <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
+    <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b><br /></message>
     <choices variable="SPLIT_PDFS">
        <choice computer="all">All assignments in a single PDF file</choice>
        $secpdfoption
Index: loncom/interface/lonquickgrades.pm
diff -u loncom/interface/lonquickgrades.pm:1.133 loncom/interface/lonquickgrades.pm:1.134
--- loncom/interface/lonquickgrades.pm:1.133	Wed Dec 24 01:14:25 2025
+++ loncom/interface/lonquickgrades.pm	Fri Jun 19 13:19:46 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Quick Student Grades Display
 #
-# $Id: lonquickgrades.pm,v 1.133 2025/12/24 01:14:25 raeburn Exp $
+# $Id: lonquickgrades.pm,v 1.134 2026/06/19 13:19:46 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -441,7 +441,6 @@
        $r->print(&Apache::loncommon::head_subbox(join('  ', at notes)));
     }
 
-    $r->print("\n".'<div class="LC_landmark" role="main" id="LC_main_content">');
     $r->print("\n".'<ul class="LC_TabContentBigger" id="main">');
     $r->print("\n".'<li'.($mode eq 'quick'?' class="active"':'').'><a href="/adm/quickgrades"><b>    '.
                                           ($showPoints?&mt('Points Overview'):($showCategories?&mt('Grades Overview'):&mt('Completion Overview'))).
@@ -471,6 +470,7 @@
        }
     }
     $r->print("\n".'</ul>'."\n");
+    $r->print("\n".'<div class="LC_landmark" role="main" id="LC_main_content">');
     $r->print('<div class="LC_Box" style="clear:both;margin:0;"><div id="maincoursedoc" style="margin:0 0;padding:0 0;"><div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">');
 }
 
Index: loncom/homework/grades.pm
diff -u loncom/homework/grades.pm:1.832 loncom/homework/grades.pm:1.833
--- loncom/homework/grades.pm:1.832	Thu Jun 18 22:31:29 2026
+++ loncom/homework/grades.pm	Fri Jun 19 13:19:49 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.832 2026/06/18 22:31:29 raeburn Exp $
+# $Id: grades.pm,v 1.833 2026/06/19 13:19:49 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -998,9 +998,9 @@
     $receipt     =~ s/[^\-\d]//g;
 
     my $title =
-	'<h3><span class="LC_info">'.
+	'<h2 class="LC_heading_2"><span class="LC_info">'.
 	&mt('Verifying Receipt Number [_1]',$receipt).
-	'</span></h3>'."\n";
+	'</span></h2>'."\n";
 
     my ($string,$contents,$matches) = ('','',0);
     my (undef,undef,$fullname) = &getclasslist('all','0');
@@ -1195,9 +1195,9 @@
                        &mt("To send scores, check box(es) next to the student's name(s), then push 'Send Scores'.").
                        '</p>'.
                        &check_script('passbackusers', 'stuinfo')."\n".
-                       '<input type="button" '."\n".
+                       '<div><input type="button" '."\n".
                        'onclick="javascript:checkSelect(this.form.stuinfo);" '."\n".
-                       'value="'.&mt('Send Scores').'" /> <br />'."\n".
+                       'value="'.&mt('Send Scores').'" /></div>'."\n".
                        &check_buttons()."\n".
                        &Apache::loncommon::start_data_table().
                        &Apache::loncommon::start_data_table_header_row();
@@ -1226,9 +1226,9 @@
                         $result.= &Apache::loncommon::start_data_table_row();
                     }
                     $result .= '<td align="right">'.$ctr.' </td>'.
-                               '<td align="center"><label><input type="checkbox" name="stuinfo" value="'.
+                               '<td align="center"><input type="checkbox" name="stuinfo" value="'.
                                $student.':'.$$fullname{$student}.':::SECTION'.$section.
-                               '" />  </label></td>'."\n".'<td>'.
+                               '" aria-label="'.&mt('No. [_1] included',$ctr).'" />  </td>'."\n".'<td>'.
                                &nameUserString(undef,$$fullname{$student},$uname,$udom).
                                ' '.$section.($group ne '' ?'/'.$group:'').'</td>'."\n";
 
@@ -2050,20 +2050,22 @@
                                &mt("To update fractional credit applied to late submission(s), check box(es) for each part for student(s) for whom 'current' and 'new' differ, then push 'Update'.").
                                '</p>'."\n".
                                &check_script('graceusers','stuinfo')."\n".
-                               '<input type="button" '.
+                               '<div><input type="button" '.
                                'onclick="javascript:checkSelect(this.form.stuinfo);" '.
-                               'value="'.&mt('Update').'"'.$disabled.' /><br />'."\n".
+                               'value="'.&mt('Update').'"'.$disabled.' /></div>'."\n".
                                &check_buttons($disabled)."\n";
                 my $numrow = 0;
+                my $numcol = 2;
                 my $table = &Apache::loncommon::start_data_table_header_row().
                             '<th>'.&mt('No.').'</th>'.
                             '<th>'.&nameUserString('header')."</th>\n";
                 foreach my $part (sort(keys(%partlist))) {
+                    $numcol += 3;
                     $table.= '<th>'.&mt('Current post-due fraction').'<br />'.&mt('Part').
                              ': '.$part.'</th>'."\n".
                              '<th>'.&mt('New post-due fraction').'<br />'.&mt('Part').
                              ': '.$part.'</th>'."\n".
-                             '<th>'.&mt('Update to new').'<br />'.&mt('Part').
+                             '<th id="col'.$numcol.'">'.&mt('Update to new').'<br />'.&mt('Part').
                              ': '.$part.'</th>'."\n";
                 }
                 $table.=&Apache::loncommon::end_data_table_header_row();   
@@ -2084,10 +2086,11 @@
                     my %record =
                         &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname);
                     my $row = &Apache::loncommon::start_data_table_row().
-                              '<td>'.$shownum.'</td><td>'.
+                              '<td>'.$shownum.'</td><th class="LC_rowheader" scope="row" id="row'.$shownum.'">'.
                               &nameUserString(undef,$$fullname{$student},$uname,$udom).
-                              ' '.$section.($group ne '' ?'/'.$group:'').'</td>'."\n";
+                              ' '.$section.($group ne '' ?'/'.$group:'').'</th>'."\n";
                     my $count = 0;
+                    my $numcol = 2;
                     foreach my $part (sort(keys(%partlist))) {
                         if ((exists($record{'resource.'.$part.'.latefrac'})) &&
                             ($record{'resource.'.$part.'.latefrac'} ne '')) {
@@ -2105,10 +2108,12 @@
                             if (($newfrac eq '') || ($newfrac eq $currfrac)) {
                                 $row .= '<td> </td>';
                             } else {
+                                $numcol += 3;
                                 my $value = $uname.':'.$udom.':'.$part.':'.$newfrac.':'.
                                             &escape($fullname->{$student}).':::SECTION'.$section;
                                 $row .= '<td><input type="checkbox" name="stuinfo" value="'.
-                                        &HTML::Entities::encode($value,'\'"<>&').'"'.$disabled.' /></td>'."\n";
+                                        &HTML::Entities::encode($value,'\'"<>&').'"'.$disabled.
+                                        ' aria-labelledby="row'.$shownum.' col'.$numcol.'" /></td>'."\n";
                                 $partupdateable{$part} = 1;
                             }
                         } else {
@@ -2429,21 +2434,27 @@
     $gradeTable .= &Apache::lonhtmlcommon::start_pick_box();
     unless ($is_tool) {
         $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Problem Text'))
+                      .'<fieldset class="LC_borderless">'
+                      .'<legend class="LC_visually_hidden">'.&mt('Display Problem?').'</legend>'
                       .'<label><input type="radio" name="vProb" value="no" checked="checked" /> '.&mt('no').' </label>'."\n"
                       .'<label><input type="radio" name="vProb" value="yes" /> '.&mt('one student').' </label>'."\n"
-                      .'<label><input type="radio" name="vProb" value="all" /> '.&mt('all students').' </label><br />'."\n"
+                      .'<label><input type="radio" name="vProb" value="all" /> '.&mt('all students').' </label>'
+                      .'</fieldset><br />'."\n"
                       .&Apache::lonhtmlcommon::row_closure();
         $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Answer'))
+                      .'<fieldset class="LC_borderless">'
+                      .'<legend class="LC_visually_hidden">'.&mt('Display Answer?').'</legend>'
                       .'<label><input type="radio" name="vAns" value="no"  /> '.&mt('no').' </label>'."\n"
                       .'<label><input type="radio" name="vAns" value="yes" /> '.&mt('one student').' </label>'."\n"
-                      .'<label><input type="radio" name="vAns" value="all" checked="checked" /> '.&mt('all students').' </label><br />'."\n"
+                      .'<label><input type="radio" name="vAns" value="all" checked="checked" /> '.&mt('all students').' </label>'
+                      .'</fieldset><br />'."\n"
                       .&Apache::lonhtmlcommon::row_closure();
     }
 
     my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
     my $saveStatus = $stu_status eq '' ? 'Active' : $stu_status;
     $env{'form.Status'} = $saveStatus;
-    my %optiontext;
+    my (%optiontext,$legend);
     if ($is_tool) {
         %optiontext = &Apache::lonlocal::texthash (
                           lastonly => 'last transaction',
@@ -2451,6 +2462,7 @@
                           datesub  => 'all transactions',
                           all      => 'all transactions with details',
                       );
+        $legend = &mt('Transaction information to display');
     } else {
         %optiontext = &Apache::lonlocal::texthash (
                           lastonly => 'last submission',
@@ -2458,8 +2470,11 @@
                           datesub  => 'all submissions',
                           all      => 'all submissions with details',
                       );
+        $legend = &mt('Submission information to display');
     }
     my $submission_options =
+        '<fieldset class="LC_borderless">'.
+        '<legend class="LC_visually_hidden">'.$legend.'</legend>'.
         '<span class="LC_nobreak">'.
         '<label><input type="radio" name="lastSub" value="lastonly" /> '.
         $optiontext{'lastonly'}.' </label></span>'."\n".
@@ -2471,7 +2486,8 @@
         $optiontext{'datesub'}.'</label></span>'."\n".
         '<span class="LC_nobreak">'.
         '<label><input type="radio" name="lastSub" value="all" /> '.
-        $optiontext{'all'}.'</label></span>';
+        $optiontext{'all'}.'</label></span>'.
+        '</fieldset>';
     my $viewtitle;
     if ($is_tool) {
         $viewtitle = &mt('View Transactions');
@@ -2513,16 +2529,19 @@
         $gradeTable .=
                    &Apache::lonhtmlcommon::row_closure()
                   .&Apache::lonhtmlcommon::row_title(&mt('Send Messages'))
+                  .'<fieldset class="LC_borderless">'
+                  .'<legend class="LC_visually_hidden">'.&mt('Show option to send message(s)?').'</legend>'
                   .'<span class="LC_nobreak">'
                   .'<label><input type="radio" name="compmsg" value="0"'.$nocompmsg.' />'
                   .&mt('No').(' 'x2).'</label>'
                   .'<label><input type="radio" name="compmsg" value="1"'.$compmsg.' />'
                   .&mt('Yes').(' 'x2).'</label>'
+                  .'</span></fieldset>'
                   .&Apache::lonhtmlcommon::row_closure();
 
         $gradeTable .= 
-                   &Apache::lonhtmlcommon::row_title(&mt('Grading Increments'))
-                  .'<select name="increment">'
+                   &Apache::lonhtmlcommon::row_title('<label for="increment">'.&mt('Grading Increments').'</label>')
+                  .'<select name="increment" id="increment">'
                   .'<option value="1">'.&mt('Whole Points').'</option>'
                   .'<option value=".5">'.&mt('Half Points').'</option>'
                   .'<option value=".25">'.&mt('Quarter Points').'</option>'
@@ -2538,14 +2557,14 @@
 	$gradeTable .= '<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n";
     } else {
         $gradeTable .= &Apache::lonhtmlcommon::row_closure()
-                      .&Apache::lonhtmlcommon::row_title(&mt('Student Status'))
+                      .&Apache::lonhtmlcommon::row_title('<label for="studentstatus">'.&mt('Student Status').'</label>')
                       .&Apache::lonhtmlcommon::StatusOptions(
-                           $saveStatus,undef,1,'javascript:reLoadList(this.form);');
+                           $saveStatus,undef,1,'javascript:reLoadList(this.form);',undef,'studentstatus');
     }
     if ($numessay) {
         $gradeTable .= &Apache::lonhtmlcommon::row_closure()
-                      .&Apache::lonhtmlcommon::row_title(&mt('Check For Plagiarism'))
-                      .'<input type="checkbox" name="checkPlag" checked="checked" />';
+                      .&Apache::lonhtmlcommon::row_title('<label for="checkPlag">'.&mt('Check For Plagiarism').'</label>')
+                      .'<input type="checkbox" name="checkPlag" id="checkPlag" checked="checked" />';
     }
     $gradeTable .= &Apache::lonhtmlcommon::row_closure(1)
                   .&Apache::lonhtmlcommon::end_pick_box();
@@ -2562,9 +2581,9 @@
 
 # checkall buttons
     $gradeTable.=&check_script('gradesub', 'stuinfo');
-    $gradeTable.='<input type="button" '."\n".
+    $gradeTable.='<div><input type="button" '."\n".
         'onclick="javascript:checkSelect(this.form.stuinfo);" '."\n".
-        'value="'.&mt('Next').' →" /> <br />'."\n";
+        'value="'.&mt('Next').' →" /> </div>'."\n";
     $gradeTable.=&check_buttons();
     my ($classlist, undef, $fullname) = &getclasslist($getsec,'1',$getgroup);
     $gradeTable.= &Apache::loncommon::start_data_table().
@@ -2644,9 +2663,9 @@
 		$gradeTable.= &Apache::loncommon::start_data_table_row();
 	    }
 	    $gradeTable.='<td align="right">'.$ctr.' </td>'.
-               '<td align="center"><label><input type="checkbox" name="stuinfo" value="'.
+               '<td align="center"><input type="checkbox" name="stuinfo" value="'.
                $student.':'.$$fullname{$student}.':::SECTION'.$section.
-	       '" />  </label></td>'."\n".'<td>'.
+	       '" aria-label="'.&mt('No. [_1] included',$ctr).'" />  </td>'."\n".'<td>'.
 	       &nameUserString(undef,$$fullname{$student},$uname,$udom).
 	       ' '.$section.($group ne '' ?'/'.$group:'').'</td>'."\n";
 
@@ -2795,7 +2814,8 @@
     my $buttons.='<input type="button" onclick="checkall()" value="'.&mt('Check All').'"'.$disabled.' />';
     $buttons.='<input type="button" onclick="uncheckall()" value="'.&mt('Uncheck All').'"'.$disabled.' /> ';
     $buttons.='<input type="button" onclick="checksec()" value="'.&mt('Check Section/Group').'"'.$disabled.' />';
-    $buttons.='<input type="text" size="5" name="chksec"'.$disabled.' /> ';
+    $buttons.='<input type="text" size="5" name="chksec"'.$disabled.' aria-label="'.
+              &mt('Filter by specific Section or Group').'" /> ';
     return $buttons;
 }
 
@@ -3375,7 +3395,7 @@
 }
 
 sub gradeBox_start {
-    my ($parts_ref,$record,$has_late) = @_;
+    my ($parts_ref,$record,$has_late,$num) = @_;
     my $showlatefrac;
     if ((ref($parts_ref) eq 'HASH') && (ref($record) eq 'HASH') &&
         (ref($has_late))) {
@@ -3393,11 +3413,10 @@
        .&Apache::loncommon::start_data_table_header_row()
        .'<th>'.&mt('Part').'</th>'
        .'<th>'.&mt('Points').'</th>'
-       .'<th> </th>'
-       .'<th>'.&mt('Assign Grade').'</th>'
+       .'<th id="assignhdr_'.$num.'" colspan="2">   '.&mt('Assign Grade').'</th>'
        .'<th>'.&mt('Weight').'</th>'
        .$showlatefrac
-       .'<th>'.&mt('Grade Status').'</th>'
+       .'<th id="statushdr_'.$num.'">'.&mt('Grade Status').'</th>'
        .&Apache::loncommon::end_data_table_header_row()
     );
 }
@@ -3409,7 +3428,7 @@
 }
 #--- displays the grading box, used in essay type problem and grading by page/sequence
 sub gradeBox {
-    my ($request,$symb,$uname,$udom,$counter,$partid,$has_late,$record) = @_;
+    my ($request,$symb,$uname,$udom,$counter,$num,$partid,$has_late,$record) = @_;
     my $checkIcon = '<img alt="'.&mt('Check Mark').
 	'" src="'.&Apache::loncommon::lonhttpdurl($request->dir_config('lonIconsURL').'/check.gif').'" height="16" border="0" />';
     my $wgt    = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname);
@@ -3436,25 +3455,27 @@
     my $colspan = 6;
     my $increment = &get_increment();
 
-    my $radio.='<table border="0"><tr>'."\n";  # display radio buttons in a nice table 10 across
+    my $radio.='<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.&mt('Points').'</legend>'.
+               '<div class="LC_grid" role="grid" style="margin: 0;">'."\n".
+               '<div class="LC_grid_row" role="row">'."\n"; # display radio buttons in a nice grid 10 across
     while ($thisweight<=$wgt) {
-	$radio.= '<td><span class="LC_nobreak"><label><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
+	$radio.= '<div class="LC_grid_cell" role="gridcell"><span class="LC_nobreak"><label><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
         'onclick="javascript:writeBox(this.form,\''.$counter.'_'.$partid.'\','.
 	    $thisweight.')" value="'.$thisweight.'" '.
-	    ($score eq $thisweight ? 'checked="checked"':'').' /> '.$thisweight."</label></span></td>\n";
-	$radio.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
+	    ($score eq $thisweight ? 'checked="checked"':'').' /> '.$thisweight."</label></span></div>\n";
+	$radio.=(($ctr+1)%10 == 0 ? '</div><div class="LC_grid_row" role="row">' : '');
         $thisweight += $increment;
 	$ctr++;
     }
-    $radio.='</tr></table>';
+    $radio.='</div></div></fieldset>';
 
     my $line.='<input type="text" name="GD_BOX'.$counter.'_'.$partid.'"'.
 	($score ne ''? ' value = "'.$score.'"':'').' size="4" '.
 	'onchange="javascript:updateRadio(this.form,\''.$counter.'_'.$partid.'\','.
-	$wgt.')" /></td>'."\n";
+	$wgt.')" aria-labelledby="partrow_'.$num.'_'.$partid.' assignhdr_'.$num.'" /></td>'."\n";
     $line.='<td>/'.$wgt.' '.$wgtmsg.
 	($$record{'resource.'.$partid.'.solved'} eq 'correct_by_student' ? ' '.$checkIcon : '').
-	' </td>'."\n";
+	' '.$data_WGT.'</td>'."\n";
     if ($has_late) {
         $line.='<td>'.$latefrac.
                '<input type="hidden" name="latefrac'.$counter.'_'.$partid.'" value="'.$latefrac.'" />'."\n".
@@ -3465,7 +3486,8 @@
         $colspan ++;
     }
     $line.='<td><select name="GD_SEL'.$counter.'_'.$partid.'" '.
-	'onchange="javascript:clearRadBox(this.form,\''.$counter.'_'.$partid.'\')" >'."\n";
+	'onchange="javascript:clearRadBox(this.form,\''.$counter.'_'.$partid.'\')" '.
+        'aria-labelledby="partrow_'.$num.'_'.$partid.' statushdr_'.$num.'">'."\n";
     if ($$record{'resource.'.$partid.'.solved'} eq 'excused') {
 	$line.='<option></option>'.
 	    '<option value="excused" selected="selected">'.&mt('excused').'</option>';
@@ -3477,7 +3499,7 @@
 
 
     $result .= 
-	    '<td>'.$data_WGT.$display_part.'</td><td>'.$radio.'</td><td>'.&mt('or').'</td><td>'.$line.'</td>';
+	    '<th class="LC_rowheader" scope="row" id="partrow_'.$num.'_'.$partid.'">'.$display_part.'</th><td>'.$radio.'</td><td>'.&mt('or').'</td><td>'.$line.'</td>';
     $result.=&Apache::loncommon::end_data_table_row();
     $result.=&Apache::loncommon::start_data_table_row().'<td colspan="'.$colspan.'">';
     $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="" />'."\n".
@@ -4030,7 +4052,7 @@
        .'<h3 class="LC_hcell">'.&mt('Assign Grades').'</h3>'
     );
     map { $unique_parts{$_->[0]} = 1; } @part_response_id;
-    $request->print(&gradeBox_start(\%unique_parts,\%record,\$has_late));
+    $request->print(&gradeBox_start(\%unique_parts,\%record,\$has_late,$counter));
     foreach my $part_response_id (@part_response_id) {
     	my ($partid,$respid) = @{ $part_response_id };
 	my $part_resp = join('_',@{ $part_response_id });
@@ -4038,7 +4060,7 @@
 	$seen{$partid}++;
 	push(@partlist,$partid);
 	push(@gradePartRespid,$partid.'.'.$respid);
-	$request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,$has_late,\%record));
+	$request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$counter,$partid,$has_late,\%record));
     }
     $request->print(&gradeBox_end()); # </div>
     $request->print('</div>');
@@ -4065,11 +4087,13 @@
 
     # print end of form
     if ($counter == $total) {
-        my $endform='<br /><hr /><table border="0"><tr><td>'."\n";
+        my $endform='<br /><hr /><div class="LC_grid" role="grid" style="margin: 0;">'."\n".
+                    '<div class="LC_grid_row" role="row">'."\n".
+                    '<div class="LC_grid_cell" role="gridcell">'."\n";
 	$endform.='<input type="button" value="'.&mt('Save & Next').'" '.
 	    'onclick="javascript:checksubmit(this.form,\'Save & Next\','.
 	    $total.','.scalar(@partlist).');" target="_self" />  '."\n";
-	my $ntstu ='<select name="NTSTU">'.
+	my $ntstu ='<select name="NTSTU" aria-label="'.&mt('Number of students to show').'">'.
 	    '<option>1</option><option>2</option>'.
 	    '<option>3</option><option>5</option>'.
 	    '<option>7</option><option>10</option></select>'."\n";
@@ -4085,7 +4109,7 @@
                   '</span>'."\n" ;
         $endform.="<input type='hidden' value='".&get_increment().
             "' name='increment' />";
-	$endform.='</td></tr></table></form>';
+	$endform.='</div></div></div></form>';
 	$request->print($endform);
     }
     return '';
@@ -5556,7 +5580,7 @@
                  $env{'course.'.$env{'request.course.id'}.'.domain'});
     &Apache::lonnet::clear_EXT_cache_status();
 
-    my $result='<h3><span class="LC_info">'.&mt('Manual Grading').'</span></h3>';
+    my $result='<h2 class="LC_heading_2"><span class="LC_info">'.&mt('Manual Grading').'</span></h2>';
 
     #view individual student submission form - called using Javascript viewOneStudent
     $result.=&jscriptNform($symb);
@@ -5654,7 +5678,12 @@
         }
         $result.= '<h3>'.$common_header.' '.$text.'</h3>';
     }
-    $result .= &Apache::loncommon::start_data_table();
+    $result .= &Apache::loncommon::start_data_table().
+               &Apache::loncommon::start_data_table_header_row('LC_visually_hidden').
+               '<th aria-hidden="true"></th><th>'.&mt('Part').'</th><th aria-hidden="true"></th>'.
+               '<th>'.&mt('Points').'</th><th colspan="2" id="commonassign">'.&mt('Assign grade').'</th>'.
+               '<th id="commonstatus">'.&mt('Status').'</th><th>'.&mt('Override Correct').'</th>'.
+               &Apache::loncommon::end_data_table_header_row();
     #radio buttons/text box for assigning points for a section or class.
     #handles different parts of a problem
     my $res_error;
@@ -5680,24 +5709,28 @@
 	$weight{$partid} = $wgt eq '' ? '1' : $wgt;
 
 	my $display_part=&get_display_part($partid,$symb);
-	my $radio.='<table border="0"><tr>';  
+	my $radio .= '<fieldset class="LC_borderless">'.
+                     '<legend class="LC_visually_hidden">'.&mt('Points').'</legend>'.
+                     '<div class="LC_grid" role="grid" style="margin: 0;">'.
+                     '<div class="LC_grid_row" role="row">';
 	my $ctr = 0;
 	while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
-	    $radio.= '<td><label><input type="radio" name="RADVAL_'.$partid.'" '.
+	    $radio.= '<div class="LC_grid_cell" role="gridcell">'.
+                '<label><input type="radio" name="RADVAL_'.$partid.'" '.
 		'onclick="javascript:writePoint(\''.$partid.'\','.$weight{$partid}.
-		','.$ctr.')" />'.$ctr."</label></td>\n";
-	    $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
+		','.$ctr.')" />'.$ctr."</label></div>\n";
+	    $result.=(($ctr+1)%10 == 0 ? '</div><div class="LC_grid_row" role="row">' : '');
 	    $ctr++;
 	}
-	$radio.='</tr></table>';
+	$radio.='</div></div>';
 	my $line = '<input type="text" name="TEXTVAL_'.
 	    $partid.'" size="4" '.'onchange="javascript:writePoint(\''.
-		$partid.'\','.$weight{$partid}.',\'textval\')" /> /'.
+		$partid.'\','.$weight{$partid}.',\'textval\')" aria-labelledby="part'.$partid.' commonassign" /> /'.
 	    $weight{$partid}.' '.&mt('(problem weight)').'</td>'."\n";
         $line.= '<td><b>'.&mt('Grade Status').':</b>'.
             '<select name="SELVAL_'.$partid.'" '.
             'onchange="javascript:writeRadText(\''.$partid.'\','.
-                $weight{$partid}.')"> '.
+                $weight{$partid}.')" aria-labelledby="part'.$partid.' commonstatus"> '.
 	    '<option selected="selected"> </option>'.
 	    '<option value="excused">'.&mt('excused').'</option>'.
 	    '<option value="reset status">'.&mt('reset status').'</option>'.
@@ -5710,7 +5743,7 @@
 
 	$result.=
 	    &Apache::loncommon::start_data_table_row()."\n".
-	    '<td><b>'.&mt('Part:').'</b></td><td>'.$display_part.'</td><td><b>'.&mt('Points:').'</b></td><td>'.$radio.'</td><td>'.&mt('or').'</td><td>'.$line.'</td>'.
+	    '<td aria-hidden="true"><b>'.&mt('Part:').'</b></td><th scope="row" class="LC_rowheader" id="part'.$partid.'">'.$display_part.'</th><td aria-hidden="true"><b>'.&mt('Points:').'</b></td><td>'.$radio.'</td><td>'.&mt('or').'</td><td>'.$line.'</td>'.
 	    &Apache::loncommon::end_data_table_row()."\n";
 	$ctsparts++;
     }
@@ -5748,7 +5781,9 @@
     }
     my (undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
     my @partids = ();
+    my $colnum = 2;
     foreach my $part (@parts) {
+        $colnum ++;
 	my $display=&Apache::lonnet::metadata($url,$part.'.display',$toolsymb);
         my $narrowtext = &mt('Tries');
 	$display =~ s|^Number of Attempts|$narrowtext <br />|; # makes the column narrower
@@ -5760,10 +5795,11 @@
 #
 	my $display_part=&get_display_part($partid,$symb);
 	if ($display =~ /^Partial Credit Factor/) {
-	    $result.='<th>'.
+	    $result.='<th id="col'.$colnum.'">'.
 		&mt('Score Part: [_1][_2](weight = [_3])',
 		    $display_part,'<br />',$weight{$partid}).'</th>'."\n";
             if ($symbpartgrace{"$symb\0$partid"}) {
+                $colnum ++;
                 $result.='<th>'.&mt('Grace (fraction)').'<br />'.&mt('Part:').
                          ' '.$display_part.'</th>'."\n";
                 $hasgracecol = 1;
@@ -5777,7 +5813,7 @@
 	    my $part_mt = &mt('Part:');
 	    $display =~s{\[Part: \Q$partid\E\]}{$part_mt $display_part};
 	}
-	$result.='<th>'.$display.'</th>'."\n";
+	$result.='<th id="col'.$colnum.'">'.$display.'</th>'."\n";
     }
     $result.=&Apache::loncommon::end_data_table_header_row();
 
@@ -5929,9 +5965,11 @@
     }
     $$ctr++;
     my %aggregates = ();
-    my $result=&Apache::loncommon::start_data_table_row().'<td align="right">'.
-	'<input type="hidden" name="ctr'.($$ctr-1).'" value="'.$student.'" />'.
-	"\n".$$ctr.' </td><td> '.
+    my $colnum = 2;
+    my $result=&Apache::loncommon::start_data_table_row().
+        '<th scope="row" id="row'.$$ctr.'" class="LC_rowheader" align="right">'.
+        "\n".$$ctr.' </th><td><input type="hidden" name="ctr'.($$ctr-1).'" '.
+        'value="'.$student.'" /> '.
 	'<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
 	'\');" target="_self">'.$fullname.'</a> '.
 	'<span class="LC_internal_info">('.$uname.($env{'user.domain'} eq $udom ? '' : ':'.$udom).')</span></td>'."\n";
@@ -5940,6 +5978,7 @@
 	my ($part,$type) = &split_part_type($apart);
 	my $score=$record{"resource.$part.$type"};
         my $latefrac=$record{"resource.$part.latefrac"};
+        $colnum ++;
         $result.='<td align="center">';
         my ($aggtries,$totaltries);
         unless (exists($aggregates{$part})) {
@@ -5962,8 +6001,9 @@
 	    $result.='<input type="text" name="'.
 		'GD_'.$student.'_'.$part.'_awarded" '.
                 'onchange="javascript:changeSelect(\''.$part.'\',\''.$student.
-		'\')" value="'.$pts.'" size="5" /></td>'."\n";
+		'\')" value="'.$pts.'" size="5" aria-labelledby="row'.$$ctr.' col'.$colnum.'" /></td>'."\n";
             if ($hasgracecol) {
+                $colnum ++;
                 $result.= '<td align="center">';
                 if (($latefrac ne '') && ($latefrac < 1) && ($latefrac >= 0)) {
                    $result.= $latefrac.'<input type="hidden" name="'.
@@ -5978,7 +6018,7 @@
 		$part.'_solved_s" value="'.$status.'" />'."\n";
 	    $result.=' <select name="'.
 		'GD_'.$student.'_'.$part.'_solved" '.
-                'onchange="javascript:changeOneScore(\''.$part.'\',\''.$student.'\')" >'."\n";
+                'onchange="javascript:changeOneScore(\''.$part.'\',\''.$student.'\')" aria-labelledby="row'.$$ctr.' col'.$colnum.'">'."\n";
 	    $result.= (($status eq 'excused') ? '<option> </option><option selected="selected" value="excused">'.&mt('excused').'</option>' 
 		: '<option selected="selected"> </option><option value="excused">'.&mt('excused').'</option>')."\n";
 	    $result.='<option value="reset status">'.&mt('reset status').'</option>';
@@ -5989,7 +6029,7 @@
 		    "\n";
 	    $result.='<input type="text" name="'.
 		'GD_'.$student.'_'.$part.'_'.$type.'" '.
-		'value="'.$score.'" size="4" /></td>'."\n";
+		'value="'.$score.'" size="4" aria-labelledby="row'.$$ctr.' col'.$colnum.'" /></td>'."\n";
 	}
     }
     $result.=&Apache::loncommon::end_data_table_row();
@@ -6470,16 +6510,20 @@
              '<th>'.&mt('Specify a file containing the class scores for current resource.').'</th>'.
              &Apache::loncommon::end_data_table_header_row().
              &Apache::loncommon::start_data_table_row().'<td>';
-    my $upload=&mt("Upload Scores");
+    my %lt = &Apache::lonlocal::texthash (
+                                           upload => 'Upload Scores',
+                                           ignore => 'Ignore First Line',
+                                           file   => 'File',
+    );
     my $upfile_select=&Apache::loncommon::upfile_select_html();
-    my $ignore=&mt('Ignore First Line');
     $symb = &Apache::lonenc::check_encrypt($symb);
     $result.=<<ENDUPFORM;
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
 <input type="hidden" name="symb" value="$symb" />
 <input type="hidden" name="command" value="csvuploadmap" />
+<label for="upfile">$lt{'file'}</label>: 
 $upfile_select
-<br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$upload" />
+<br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$lt{'upload'}" />
 </form>
 ENDUPFORM
     $result.=&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
@@ -6554,7 +6598,7 @@
     my %fields=&get_fields();
     if (!defined($fields{'domain'})) {
 	my $domform = &Apache::loncommon::select_dom_form($env{'request.role.domain'},'default_domain');
-	$request->print("\n<p>".&mt('Users are in domain: [_1]',$domform)."</p>\n");
+	$request->print("\n<p><label>".&mt('Users are in domain: [_1]',$domform)."</label></p>\n");
     }
     foreach my $key (sort(keys(%env))) {
 	if ($key !~ /^form\.(.*)$/) { next; }
@@ -7025,9 +7069,9 @@
             '</span>');
         return;
     }
-    my $result='<h3><span class="LC_info"> '.$env{'form.title'}.'</span></h3>';
-    $result.='<h3> '.&mt('Student: [_1]',&nameUserString(undef,$$fullname{$env{'form.student'}},$uname,$udom)).
-	'</h3>'."\n";
+    my $result='<h2 class="LC_heading_2"><span class="LC_info"> '.$env{'form.title'}.'</span></h2>';
+    $result.='<h2 class="LC_heading_2"> '.&mt('Student: [_1]',&nameUserString(undef,$$fullname{$env{'form.student'}},$uname,$udom)).
+	'</h2>'."\n";
     $env{'form.CODE'} = uc($env{'form.CODE'});
     if (&Apache::lonnet::validCODE(uc($env{'form.CODE'}))) {
 	$result.='<h3> '.&mt('CODE: [_1]',$env{'form.CODE'}).'</h3>'."\n";
@@ -7153,9 +7197,9 @@
                 my $has_late;
                 my %unique_parts;
                 map { $unique_parts{$_} = 1; } @{$parts};
-                $studentTable.=&gradeBox_start(\%unique_parts,\%record,\$has_late);
+                $studentTable.=&gradeBox_start(\%unique_parts,\%record,\$has_late,$prob);
 		foreach my $partid (@{$parts}) {
-		    $studentTable.=&gradeBox($request,$symbx,$uname,$udom,$question,$partid,$has_late,\%record);
+		    $studentTable.=&gradeBox($request,$symbx,$uname,$udom,$question,$prob,$partid,$has_late,\%record);
 		    $studentTable.='<input type="hidden" name="q_'.$question.'" value="'.$partid.'" />'."\n";
 		    $question++;
 		}
@@ -7724,14 +7768,18 @@
  
  Arguments:
    $symb - $symb of the current resource
+   $panel - grade if used for "Grading" panel, or review if used for "Review" panel.
    $map_error - ref to scalar which will container error if
                 $navmap object is unavailable in &getSymbMap().
 
+   The "$panel" arg is used as the prefix in the value of the id attribute
+   in the selectpage drop-down list to ensure uniqueness.
+
 =cut
 
 sub getSequenceDropDown {
-    my ($symb,$map_error)=@_;
-    my $result='<select name="selectpage">'."\n";
+    my ($symb,$panel,$map_error)=@_;
+    my $result='<select name="selectpage" id="'.$panel.'_selectpage">'."\n";
     my ($titles,$symbx) = &getSymbMap($map_error);
     if (ref($map_error)) {
         return if ($$map_error);
@@ -7839,12 +7887,16 @@
 
  Arguments:
    $file2grade - filename to set as selected in the dropdown
+   $panel - grade if file selector is for grading panel; review if for review panel.
+
+   The "$panel" arg is used as the prefix in the value of the id attribute
+   in the scantron_selectfile drop-down list to ensure uniqueness.
 
 =cut
 
 sub scantron_uploads {
-    my ($file2grade) = @_;
-    my $result=	'<select name="scantron_selectfile">';
+    my ($file2grade,$panel) = @_;
+    my $result=	'<select name="scantron_selectfile" id="'.$panel.'_scantron_selectfile">';
     $result.="<option></option>";
     foreach my $filename (sort(&scantron_filenames())) {
 	$result.="<option".($filename eq $file2grade ? ' selected="selected"':'').">$filename</option>\n";
@@ -7857,13 +7909,19 @@
 
 =item scantron_scantab
 
+  Arguments:
+  $panel - grades if used in grading panel; review if used in review panel
+           upload if used in upload panel.
+
   Returns html drop down of the scantron formats in the scantronformat.tab
-  file.
+  file. The "$panel" arg is used as the prefix in the value of the id attribute
+  in the scantron_format drop-down list to ensure uniqueness.
 
 =cut
 
 sub scantron_scantab {
-    my $result='<select name="scantron_format">'."\n";
+    my ($panel) = @_;
+    my $result='<select name="scantron_format" id="'.$panel.'_scantron_format">'."\n";
     $result.='<option></option>'."\n";
     my @lines = &Apache::lonnet::get_scantronformat_file();
     if (@lines > 0) {
@@ -7881,23 +7939,32 @@
 
 =item scantron_CODElist
 
+  Arguments:
+  $panel - grades if used in grading panel; view if used in "CODEs to view" panel
+
   Returns html drop down of the saved CODE lists from current course,
   generated from earlier printings.
 
 =cut
 
 sub scantron_CODElist {
+    my ($panel) = @_;
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
     my $namechoice='<option></option>';
+    my $numsaved = 0;
     foreach my $name (sort {uc($a) cmp uc($b)} @names) {
 	if ($name =~ /^error: 2 /) { next; }
 	if ($name =~ /^type\0/) { next; }
 	$namechoice.='<option value="'.$name.'">'.$name.'</option>';
+        $numsaved ++;
     }
-    $namechoice='<select name="scantron_CODElist">'.$namechoice.'</select>';
-    return $namechoice;
+    if ($numsaved) {
+        $namechoice='<select name="scantron_CODElist" id="'.$panel.'_scantron_CODElist">'.$namechoice.'</select>';
+        return $namechoice;
+    }
+    return;
 }
 
 =pod 
@@ -7941,15 +8008,21 @@
     my ($r,$file2grade,$symb) = @_;
     if (!$symb) {return '';}
     my $map_error;
-    my $sequence_selector=&getSequenceDropDown($symb,\$map_error);
+    my $sequence_selector=&getSequenceDropDown($symb,'grade',\$map_error);
     if ($map_error) {
         $r->print('<br />'.&navmap_errormsg().'<br />');
         return;
     }
     my $default_form_data=&defaultFormData($symb);
-    my $file_selector=&scantron_uploads($file2grade);
-    my $format_selector=&scantron_scantab();
-    my $CODE_selector=&scantron_CODElist();
+    my $file_selector=&scantron_uploads($file2grade,'grade');
+    my $format_selector=&scantron_scantab('grade');
+    my $CODE_selector=&scantron_CODElist('grade');
+    my $CODE_info = &mt('Saved CODEs to validate against:');
+    if ($CODE_selector ne '') {
+        $CODE_info = '<label for="grade_scantron_CODElist">'.$CODE_info.'</label>';
+    } else {
+        $CODE_selector = &mt('No saved CODEs available');
+    }
     my $CODE_unique=&scantron_CODEunique();
     my $result;
 
@@ -7989,8 +8062,8 @@
                 </th>
               '.&Apache::loncommon::end_data_table_header_row().'
               '.&Apache::loncommon::start_data_table_row().'
-            <td>
-                '.&mt('File to upload: [_1]','<input type="file" name="upfile" size="50" />').'<br />'."\n");
+            <td><label>
+                '.&mt('File to upload: [_1]','<input type="file" name="upfile" size="50" />').'</label><br />'."\n");
     if ($formatoptions) {
         $r->print('</td>
                  '.&Apache::loncommon::end_data_table_row().'
@@ -8027,26 +8100,32 @@
             </th>
        '.&Apache::loncommon::end_data_table_header_row().'
        '.&Apache::loncommon::start_data_table_row().'
-            <td> '.&mt('Sequence to grade:').' </td><td> '.$sequence_selector.' </td>
+            <td> <label for="grade_selectpage">'.&mt('Sequence to grade:').'</label> </td><td> '.$sequence_selector.' </td>
        '.&Apache::loncommon::end_data_table_row().'
        '.&Apache::loncommon::start_data_table_row().'
-            <td> '.&mt('Filename of bubblesheet data file:').' </td><td> '.$file_selector.' </td>
+            <td> <label for="grade_scantron_selectfile">'.&mt('Filename of bubblesheet data file:').'</label> </td><td> '.$file_selector.' </td>
        '.&Apache::loncommon::end_data_table_row().'
        '.&Apache::loncommon::start_data_table_row().'
-            <td> '.&mt('Format of bubblesheet data file:').' </td><td> '.$format_selector.' </td>
+            <td> <label for="grade_scantron_format">'.&mt('Format of bubblesheet data file:').'</label> </td><td> '.$format_selector.' </td>
        '.&Apache::loncommon::end_data_table_row().'
        '.&Apache::loncommon::start_data_table_row().'
-            <td> '.&mt('Saved CODEs to validate against:').' </td><td> '.$CODE_selector.' </td>
+            <td> '.$CODE_info.' </td><td> '.$CODE_selector.' </td>
        '.&Apache::loncommon::end_data_table_row().'
        '.&Apache::loncommon::start_data_table_row().'
-            <td> '.&mt('Each CODE is only to be used once:').'</td><td> '.$CODE_unique.' </td>
+            <td> '.&mt('Each CODE is only to be used once:').'</td>
+            <td>
+              <fieldset class="LC_borderless">
+              <legend class="LC_visually_hidden">'.&mt('Each CODE can only be used for one bubblesheet').'</legend>'.$CODE_unique.'</fieldset> </td>
        '.&Apache::loncommon::end_data_table_row().'
        '.&Apache::loncommon::start_data_table_row().'
 	    <td> '.&mt('Options:').' </td>
             <td>
+               <fieldset class="LC_borderless" style="line-height: 185%;">
+               <legend class="LC_visually_hidden">'.&mt('Options for skipping items during grading').'</legend>
 	       <label><input type="checkbox" name="scantron_options_redo" value="redo_skipped"/> '.&mt('Do only previously skipped records').'</label> <br />
                <label><input type="checkbox" name="scantron_options_ignore" value="ignore_corrections"/> '.&mt('Remove all existing corrections').'</label> <br />
                <label><input type="checkbox" name="scantron_options_hidden" value="ignore_hidden"/> '.&mt('Skip hidden resources when grading').'</label>
+               </fieldset>
 	    </td>
        '.&Apache::loncommon::end_data_table_row().'
        '.&Apache::loncommon::start_data_table_row().'
@@ -8063,6 +8142,7 @@
     # Chunk of the form that prompts to view a scoring office file,
     # corrected file, skipped records in a file.
 
+    my $download_file_selector=&scantron_uploads($file2grade,'download');
     $r->print('
    <br />
    <form action="/adm/grades" name="scantron_download">
@@ -8075,9 +8155,10 @@
               </th>
        '.&Apache::loncommon::end_data_table_header_row().'
        '.&Apache::loncommon::start_data_table_row().'
-              <td> '.&mt('Filename of scoring office file: [_1]',$file_selector).' 
+              <td> <label>'.
+              &mt('Filename of scoring office file: [_1]',$download_file_selector).'</label> 
                 <br />
-                <input type="submit" value="'.&mt('Download: Show List of Associated Files').'" />
+                <div style="margin: 2px 0 0 0"><input type="submit" value="'.&mt('Download: Show List of Associated Files').'" /></div></td>
        '.&Apache::loncommon::end_data_table_row().'
      '.&Apache::loncommon::end_data_table().'
    </form>
@@ -8086,6 +8167,10 @@
 
     &Apache::lonpickcode::code_list($r,2);
 
+    my $sequence_selector_review = &getSequenceDropDown($symb,'review',\$map_error);
+    my $file_selector_review = &scantron_uploads($file2grade,'review');
+    my $format_selector_review = &scantron_scantab('review');
+
     $r->print('<br /><form method="post" name="checkscantron" action="">'.
              $default_form_data."\n".
              &Apache::loncommon::start_data_table('LC_scantron_action')."\n".
@@ -8095,16 +8180,16 @@
              '</th>'."\n".
               &Apache::loncommon::end_data_table_header_row()."\n".
               &Apache::loncommon::start_data_table_row()."\n".
-              '<td> '.&mt('Graded folder/sequence:').' </td>'."\n".
-              '<td> '.$sequence_selector.' </td>'.
+              '<td> <label for="review_selectpage">'.&mt('Graded folder/sequence:').'</label> </td>'."\n".
+              '<td> '.$sequence_selector_review.' </td>'.
               &Apache::loncommon::end_data_table_row()."\n".
               &Apache::loncommon::start_data_table_row()."\n".
-              '<td> '.&mt('Filename of scoring office file:').' </td>'."\n".
-              '<td> '.$file_selector.' </td>'."\n".
+              '<td> <label for="review_scantron_selectfile">'.&mt('Filename of scoring office file:').'</label> </td>'."\n".
+              '<td> '.$file_selector_review.' </td>'."\n".
               &Apache::loncommon::end_data_table_row()."\n".
               &Apache::loncommon::start_data_table_row()."\n".
-              '<td> '.&mt('Format of data file:').' </td>'."\n".
-              '<td> '.$format_selector.' </td>'."\n".
+              '<td> <label for="review_scantron_format">'.&mt('Format of data file:').'</label> </td>'."\n".
+              '<td> '.$format_selector_review.' </td>'."\n".
               &Apache::loncommon::end_data_table_row()."\n".
               &Apache::loncommon::start_data_table_row()."\n".
               '<td> '.&mt('Options').' </td>'."\n".
@@ -9039,27 +9124,37 @@
 	$CODElist=$env{'form.scantron_CODElist'};
 	if ($env{'form.scantron_CODElist'} eq '') { $CODElist='<span class="LC_warning">'.&mt('None').'</span>'; }
 	$CODElist=
-	    '<tr><td><b>'.&mt('List of CODES to validate against:').'</b></td><td><tt>'.
-	    $env{'form.scantron_CODElist'}.'</tt></td></tr>';
+            '<div class="LC_grid_row" role="row">'.
+            '<div class="LC_grid_cell" role="gridcell"><b>'.
+            &mt('List of CODES to validate against:').'</b></div>'.
+            '<div class="LC_grid_cell" role="gridcell"><tt>'.
+            $env{'form.scantron_CODElist'}.'</tt></div></div>';
     }
     my $lastbubblepoints;
     if ($env{'form.scantron_lastbubblepoints'} ne '') {
         $lastbubblepoints =
-            '<tr><td><b>'.&mt('Hand-graded items: points from last bubble in row').'</b></td><td><tt>'.
-            $env{'form.scantron_lastbubblepoints'}.'</tt></td></tr>';
+            '<div class="LC_grid_row" role="row">'.
+            '<div class="LC_grid_cell" role="gridcell">'.
+            '<b>'.&mt('Hand-graded items: points from last bubble in row').'</b></div>'.
+            '<div><tt>'.$env{'form.scantron_lastbubblepoints'}.'</tt></div></div>';
     }
     return '
 <p>
 <span class="LC_warning">
 '.&mt("Please double check the information below before clicking on '[_1]'",&mt($button_text)).'</span>
 </p>
-<table>
-<tr><td><b>'.&mt('Sequence to be Graded:').'</b></td><td>'.$title.'</td></tr>
-<tr><td><b>'.&mt('Data File that will be used:').'</b></td><td><tt>'.$env{'form.scantron_selectfile'}.'</tt></td></tr>
+<div class="LC_grid" role="grid">
+<div class="LC_grid_row" role="row">
+<div class="LC_grid_cell" role="gridcell">
+<b>'.&mt('Sequence to be Graded:').'</b></div>
+<div class="LC_grid_cell" role="gridcell">'.$title.'</div></div>
+<div class="LC_grid_row" role="row">
+<div class="LC_grid_cell" role="gridcell"><b>'.&mt('Data File that will be used:').'</b></div>
+<div class="LC_grid_cell" role="gridcell"><tt>'.$env{'form.scantron_selectfile'}.'</tt></div></div>
 '.$CODElist.$lastbubblepoints.'
-</table>
+</div>
 <p> '.&mt("If this information is correct, please click on '[_1]'.",&mt($button_text)).'<br />
-'.&mt('If something is incorrect, please return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','<a href="/adm/grades?symb='.$symb.'&command=scantron_selectphase" class="LC_info">','</a>').'</p>
+'.&mt('If something is incorrect, please return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','<a href="'.&HTML::Entities::encode('/adm/grades?symb='.$symb.'&command=scantron_selectphase','&<>"\'').'" class="LC_info">','</a>').'</p>
 ';
 }
 
@@ -9314,11 +9409,13 @@
 	$r->print(&mt('Validation process complete.').'<br />'.
                   $secinfo.$warning.
                   &mt('Perform verification for each student after storage of submissions?').
-                  ' <span class="LC_nobreak"><label>'.
+                  ' <fieldset class="LC_borderless">'.
+                  '<legend class="LC_visually_hidden">'.&mt('Verify each student?').'</legend>'.
+                  '<span class="LC_nobreak"><label>'.
                   '<input type="radio" name="verifyrecord" value="1" />'.&mt('Yes').'</label>'.
                   (' 'x3).'<label>'.
                   '<input type="radio" name="verifyrecord" value="0" checked="checked" />'.&mt('No').
-                  '</label></span><br />'.
+                  '</label></span></fieldset><br />'.
                   &mt('Grading will take longer if you use verification.').'<br />'.
                   &mt('Otherwise, Grade/Manage/Review Bubblesheets [_1] Review bubblesheet data can be used once grading is complete.','»').'<br /><br />'.
                   '<input type="submit" name="submit" value="'.&mt('Start Grading').'" />'.
@@ -9339,9 +9436,9 @@
             } else {
                 $r->print('<input type="submit" name="submit" value="'.&mt('Continue').' →" />');
             }
-	    $r->print(' '.&mt('using corrected info').' <br />');
+	    $r->print(' '.&mt('using corrected info').' <div style="margin: 2px 0 0 0;">');
 	    $r->print("<input type='submit' value='".&mt("Skip")."' name='scantron_skip_record' />");
-	    $r->print(" ".&mt("this scanline saving it for later."));
+	    $r->print(" ".&mt("this scanline saving it for later.").'</div>');
 	}
     }
     $r->print(" </form><br />");
@@ -9914,16 +10011,23 @@
                 "<b>$error</b>", $i, "<pre>$line</pre>")
            ."</p> \n");
     }
-    my $message =
-        '<p>'
-       .&mt('The ID on the form is [_1]',
-            "<tt>$$scan_record{'scantron.ID'}</tt>")
-       .'<br />'
-       .&mt('The name on the paper is [_1], [_2]',
-            $$scan_record{'scantron.LastName'},
-            $$scan_record{'scantron.FirstName'})
-       .'</p>';
-
+    my $message = '<p>';
+    if ($$scan_record{'scantron.ID'} =~ /\S/) {
+        $message .= &mt('The ID on the form is [_1]',
+                "<tt>$$scan_record{'scantron.ID'}</tt>");
+    } else {
+        $message .= &mt('There is no ID on the form');
+    }
+    $message .= '<br />';
+    if (($$scan_record{'scantron.LastName'} =~ /\S/) ||
+        ($$scan_record{'scantron.FirstName'} =~ /\S/)) {
+        $message .= &mt('The name on the form is [_1], [_2]',
+                        $$scan_record{'scantron.LastName'},
+                        $$scan_record{'scantron.FirstName'});
+    } else {
+        $message .= &mt('There is no name on the form');
+    }
+    $message .= '</p>';
     $r->print('<input type="hidden" name="scantron_corrections" value="'.$error.'" />'."\n");
     $r->print('<input type="hidden" name="scantron_line" value="'.$i.'" />'."\n");
                            # Array populated for doublebubble or
@@ -9938,17 +10042,19 @@
             $r->print('<p class="LC_warning">'.&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."</p>\n");
 	}
 	$r->print($message);
-	$r->print("<p>".&mt("How should I handle this?")." <br /> \n");
+	$r->print("<p>".&mt("How should I handle this?")." </p> \n");
 	$r->print("\n<ul><li> ");
 	#FIXME it would be nice if this sent back the user ID and
 	#could do partial userID matches
+        my $arialabel = &mt('correct username for this bubblesheet line');
 	$r->print(&Apache::loncommon::selectstudent_link('scantronupload',
 				       'scantron_username','scantron_domain'));
-	$r->print(": <input type='text' name='scantron_username' value='' />");
-	$r->print("\n:\n".
-		 &Apache::loncommon::select_dom_form($env{'request.role.domain'},'scantron_domain'));
+	$r->print(": <input type='text' name='scantron_username' value='' aria-label='$arialabel' />");
+        $r->print("\n:\n".'<span class="LC_visually_hidden"><label for="scantron_domain">'.&mt('in domain').'</label></span>'.
+                  &Apache::loncommon::select_dom_form($env{'request.role.domain'},'scantron_domain',
+                                                      '','','','','','','scantron_domain'));
 
-	$r->print('</li>');
+	$r->print('</li></ul>');
     } elsif ($error =~ /CODE$/) {
 	if ($error eq 'incorrectCODE') {
 	    $r->print('<p class="LC_warning">'.&mt("The encoded CODE is not in the list of possible CODEs.")."</p>\n");
@@ -9960,7 +10066,8 @@
                  ."</p>\n");
 	$r->print($message);
 	$r->print("<p>".&mt("How should I handle this?")."</p>\n");
-	$r->print("\n<br /> ");
+	$r->print("\n".'<fieldset class="LC_borderless" style="line-height: 185%;">'."\n"
+                 .'<legend class="LC_visually_hidden">'.&mt('CODE options').'</legend>');
 	my $i=0;
 	if ($error eq 'incorrectCODE' 
 	    && $$scan_record{'scantron.CODE'}=~/\S/ ) {
@@ -10003,10 +10110,10 @@
 ENDSCRIPT
 	my $href="/adm/pickcode?".
 	   "form=".&escape("scantronupload").
-	   "&scantron_format=".&escape($env{'form.scantron_format'}).
-	   "&scantron_CODElist=".&escape($env{'form.scantron_CODElist'}).
-	   "&curCODE=".&escape($$scan_record{'scantron.CODE'}).
-	   "&scantron_selectfile=".&escape($env{'form.scantron_selectfile'});
+	   "&scantron_format=".&escape($env{'form.scantron_format'}).
+	   "&scantron_CODElist=".&escape($env{'form.scantron_CODElist'}).
+	   "&curCODE=".&escape($$scan_record{'scantron.CODE'}).
+	   "&scantron_selectfile=".&escape($env{'form.scantron_selectfile'});
 	if ($env{'form.scantron_CODElist'} =~ /\S/) { 
 	    $r->print("
     <label>
@@ -10014,15 +10121,17 @@
        ".&mt("[_1]Select[_2] a CODE from the list of all CODEs and use it.",
 	     "<a target='_blank' href='$href' rel='opener'>","</a>")."
     </label> 
-    ".&mt("Selected CODE is [_1]",'<input readonly="readonly" type="text" size="8" name="scantron_CODE_selectedvalue" onfocus="javascript:change_radio(\'use_found\')" onchange="javascript:change_radio(\'use_found\')" />'));
+    ".&mt("[_1]Selected CODE[_2] is [_3]",
+          '<label for="scantron_CODE_selectedvalue">','</label>',
+          '<input readonly="readonly" id="scantron_CODE_selectedvalue" type="text" size="8" name="scantron_CODE_selectedvalue" onfocus="javascript:change_radio(\'use_found\')" onchange="javascript:change_radio(\'use_found\')" />'));
 	    $r->print("\n<br />");
 	}
 	$r->print("
     <label>
        <input type='radio' name='scantron_CODE_resolution' value='use_typed' />
        ".&mt("Use [_1] as the CODE.",
-	     "</label><input type='text' size='8' name='scantron_CODE_newvalue' onfocus=\"javascript:change_radio('use_typed')\" onkeypress=\"javascript:change_radio('use_typed')\" />"));
-	$r->print("\n<br /><br />");
+	     "</label><input type='text' size='8' name='scantron_CODE_newvalue' onfocus=\"javascript:change_radio('use_typed')\" onkeypress=\"javascript:change_radio('use_typed')\" aria-label='".&mt('Specified code')."' />"));
+	$r->print("\n</fieldset><br /><br />");
     } elsif ($error eq 'doublebubble') {
 	$r->print('<p class="LC_warning">'.&mt("There have been multiple bubbles scanned for some question(s)")."</p>\n");
 
@@ -10043,7 +10152,7 @@
                                                    $respnumlookup,$startline);
             push(@lines_to_correct, at linenums);
 	}
-        $r->print(&verify_bubbles_checked(@lines_to_correct));
+        $r->print(&verify_bubbles_checked(@lines_to_correct).'<br />');
     } elsif ($error eq 'missingbubble') {
 	$r->print('<p class="LC_warning">'.&mt("There have been [_1]no[_2] bubbles scanned for some question(s)",'<b>','</b>')."</p>\n");
 	$r->print($message);
@@ -10066,11 +10175,8 @@
                                                    $respnumlookup,$startline);
             push(@lines_to_correct, at linenums);
 	}
-        $r->print(&verify_bubbles_checked(@lines_to_correct));
-    } else {
-	$r->print("\n<ul>");
+        $r->print(&verify_bubbles_checked(@lines_to_correct).'<br />');
     }
-    $r->print("\n</li></ul>");
 }
 
 sub verify_bubbles_checked {
@@ -10331,7 +10437,7 @@
     my @alphabet=('A'..'Z');
     $r->print(&Apache::loncommon::start_data_table().
               &Apache::loncommon::start_data_table_row());
-    $r->print('<td rowspan="2" class="LC_leftcol_header">'.$line.'</td>');
+    $r->print('<th rowspan="2" class="LC_leftcol_header">'.$line.'</th>');
     for (my $i=0;$i<$max+1;$i++) {
 	$r->print("\n".'<td align="center">');
 	if ($selected[0] eq $alphabet[$i]) { $r->print('X'); shift(@selected) }
@@ -10874,10 +10980,13 @@
     if ($needs_hand_bubbles) {
         my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
         my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);
-        return &mt('The sequence to be graded contains response types which are handgraded.').'<p>'.
+        return &mt('The sequence to be graded contains response types which are handgraded.').'<br />'.
+               '<div>'.
                &mt('If you have already graded these by bubbling sheets to indicate points awarded, [_1]what point value is assigned to a filled last bubble in each row?','<br />').
-               '<label><input type="radio" name="scantron_lastbubblepoints" value="'.$bubbles_per_row.'" checked="checked" />'.&mt('[quant,_1,point]',$bubbles_per_row).'</label> '.&mt('or').' '.
-               '<label><input type="radio" name="scantron_lastbubblepoints" value="0" />'.&mt('0 points').'</label></p>';
+               '<fieldset class="LC_borderless">'
+              .'<legend class="LC_visually_hidden">'.&mt('Point value for last bubble in row').'</legend>'
+              .'<label><input type="radio" name="scantron_lastbubblepoints" value="'.$bubbles_per_row.'" checked="checked" />'.&mt('[quant,_1,point]',$bubbles_per_row).'</label> '.&mt('or').' '
+              .'<label><input type="radio" name="scantron_lastbubblepoints" value="0" />'.&mt('0 points').'</label></fieldset><br /></div>';
     }
     return;
 }
@@ -11411,8 +11520,9 @@
                             if ($count > 1) {
                                 $formatextra = '<div style="display:none" id="bubbletype">'.
                                                '<span class="LC_nobreak">'.
-                                               &mt('Bubblesheet type').': '.
-                                               &scantron_scantab().'</span></div>';
+                                               '<label for="upload_scantron_format">'.&mt('Bubblesheet type').
+                                               '</label>: '.
+                                               &scantron_scantab('upload').'</span></div>';
                                 $onclick = ' onclick="toggleScantab(this.form);"';
                                 $formatjs = <<"END";
 function toggleScantab(form) {
@@ -11442,11 +11552,13 @@
                                 $formatextra = '<input type="hidden" name="scantron_format" value="'.$formatname.'" />';
                             }
                             $formattitle = &mt('File format');
-                            $formatoptions = '<label><input name="fileformat" type="radio" value="dat" checked="checked"'.$onclick.' />'.
+                            $formatoptions = '<fieldset class="LC_borderless">'."\n".
+                                             '<legend class="LC_visually_hidden">'.$formattitle.'</legend>'.
+                                             '<label><input name="fileformat" type="radio" value="dat" checked="checked"'.$onclick.' />'.
                                              &mt('Plain Text (no delimiters)').
                                              '</label>'.(' 'x2).
                                              '<label><input name="fileformat" type="radio" value="csv"'.$onclick.' />'.
-                                             &mt('Comma separated values').'</label>'.$formatextra;
+                                             &mt('Comma separated values').'</label>'.$formatextra.'</fieldset>';
                         }
                     }
                 }
@@ -11454,7 +11566,7 @@
                 if (ref($domconfig{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {
                     if (keys(%{$domconfig{'scantron'}{'config'}{'csv'}{'fields'}})) {
                         $formattitle = &mt('Bubblesheet type');
-                        $formatoptions = &scantron_scantab();
+                        $formatoptions = &scantron_scantab('upload');
                     }
                 }
             }
@@ -12575,39 +12687,55 @@
   #
    &Apache::lonstatistics::PrepareClasslist();
 
+   my %lt = &Apache::lonlocal::texthash(
+                                         sec => 'Sections',
+                                         grp => 'Groups',
+                                         acc => 'Access Status',
+                                         sub => 'Submission Status',
+                                         tra => 'Transaction Status',
+   );
+
    my $result='<div class="LC_columnSection">
   
     <fieldset>
       <legend>
-       '.&mt('Sections').'
+        <label for="section">
+        '.$lt{'sec'}.'
+        </label>
       </legend>
-      '.&Apache::lonstatistics::SectionSelect('section','multiple',5).'
+      '.&Apache::lonstatistics::SectionSelect('section','multiple',5,'section').'
     </fieldset>
   
     <fieldset>
       <legend>
-        '.&mt('Groups').'
+        <label for="group">
+        '.$lt{'grp'}.'
+        </label>
       </legend>
-      '.&Apache::lonstatistics::GroupSelect('group','multiple',5).'
+      '.&Apache::lonstatistics::GroupSelect('group','multiple',5,'group').'
     </fieldset>
   
     <fieldset>
       <legend>
-        '.&mt('Access Status').'
+        <label for="status">
+        '.$lt{'acc'}.'
+        </label>
       </legend>
-      '.&Apache::lonhtmlcommon::StatusOptions(undef,undef,5,undef,'mult').'
+      '.&Apache::lonhtmlcommon::StatusOptions(undef,undef,5,undef,'mult','status').'
     </fieldset>';
     if ($full) {
-        my $heading = &mt('Submission Status');
+        my $heading = $lt{'sub'};
         if ($is_tool) {
-            $heading = &mt('Transaction Status');
+            $heading = $lt{'tra'};
         }
         $result.='
     <fieldset>
       <legend>
+        <label for="submitonly">
         '.$heading.'
+        </label>
       </legend>'.
-       &Apache::loncommon::select_form('all','submitonly',\%options).
+       &Apache::loncommon::select_form('all','submitonly',\%options,undef,undef,'submitonly').
    '</fieldset>';
     }
     $result.='</div><br />';
@@ -12734,11 +12862,6 @@
     my ($r,$symb)=@_;
     if (!$symb) {return '';}
     my $result=&checkforfile_js();
-    $result.=&Apache::loncommon::start_data_table().
-             &Apache::loncommon::start_data_table_header_row().
-             '<th>'.&mt('Specify a file containing clicker information and set grading options.').'</th>'.
-             &Apache::loncommon::end_data_table_header_row().
-             &Apache::loncommon::start_data_table_row()."<td>\n";
 # Attempt to restore parameters from last session, set defaults if not present
     my %Saveable_Parameters=&clicker_grading_parameters();
     &Apache::loncommon::restore_course_settings('grades_clicker',
@@ -12754,22 +12877,31 @@
           $checked{$gradingmechanism}=' checked="checked"';
        }
     }
+    my %lt = &Apache::lonlocal::texthash(
+                 heading => 'Specify a file containing clicker information and set grading options.',
+                 file => 'Upload file and specify type',
+                 upload => 'Evaluate File',
+                 type => 'Type',
+                 attendance => 'Award points just for participation',
+                 personnel => 'Correctness determined from response by course personnel',
+                 specific => 'Correctness determined from response with clicker ID(s)',
+                 respid => 'ID of clicker with correct response',
+                 given => 'Correctness determined from given list of answers',
+                 comma => 'Provide comma-separated list.',
+                 useskip => "Use '*' for any answer correct, '-' for skip",
+                 answers => 'List of correct answers',
+                 pcorrect => 'Percentage points for correct solution',
+                 pincorrect => 'Percentage points for incorrect solution',
+                 mechanism => 'Grading Mechanism',
+                 points => 'Points Allocation',
 
-    my $upload=&mt("Evaluate File");
-    my $type=&mt("Type");
-    my $attendance=&mt("Award points just for participation");
-    my $personnel=&mt("Correctness determined from response by course personnel");
-    my $specific=&mt("Correctness determined from response with clicker ID(s)"); 
-    my $given=&mt("Correctness determined from given list of answers").' '.
-              '<font size="-2"><tt>('.&mt("Provide comma-separated list. Use '*' for any answer correct, '-' for skip").')</tt></font>';
-    my $pcorrect=&mt("Percentage points for correct solution");
-    my $pincorrect=&mt("Percentage points for incorrect solution");
+    );
     my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',
-						   {'iclicker' => 'i>clicker',
+                                                   {'iclicker' => 'i>clicker',
                                                     'interwrite' => 'interwrite PRS',
                                                     'turning' => 'Turning Technologies'});
     $symb = &Apache::lonenc::check_encrypt($symb);
-    $result.= &Apache::lonhtmlcommon::scripttag(<<ENDUPFORM);
+    $result.= &Apache::lonhtmlcommon::scripttag(<<ENDUPSCRIPT);
 function sanitycheck() {
 // Accept only integer percentages
    document.forms.gradesupload.pcorrect.value=Math.round(document.forms.gradesupload.pcorrect.value);
@@ -12807,35 +12939,50 @@
 // Remember the old state
    document.forms.gradesupload.waschecked.value=newgradingchoice;
 }
-ENDUPFORM
-    $result.= <<ENDUPFORM;
-<form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
-<input type="hidden" name="symb" value="$symb" />
-<input type="hidden" name="command" value="processclickerfile" />
-<input type="file" name="upfile" size="50" />
-<br /><label>$type: $selectform</label>
-ENDUPFORM
-    $result.='</td>'.&Apache::loncommon::end_data_table_row().
-                     &Apache::loncommon::start_data_table_row().'<td>'.(<<ENDGRADINGFORM);
-      <label><input type="radio" name="gradingmechanism" value="attendance"$checked{'attendance'} onclick="sanitycheck()" />$attendance </label>
-<br /><label><input type="radio" name="gradingmechanism" value="personnel"$checked{'personnel'} onclick="sanitycheck()" />$personnel</label>
-<br /><label><input type="radio" name="gradingmechanism" value="specific"$checked{'specific'} onclick="sanitycheck()" />$specific </label>
-<input type="text" name="specificid" value="$env{'form.specificid'}" size="20" />
-<br /><label><input type="radio" name="gradingmechanism" value="given"$checked{'given'} onclick="sanitycheck()" />$given </label>
+ENDUPSCRIPT
+    $result.=<<ENDUPFORMHEADER;
+        <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
+        <input type="hidden" name="symb" value="$symb" />
+        <input type="hidden" name="command" value="processclickerfile" />
+ENDUPFORMHEADER
+    $result.= &Apache::loncommon::start_data_table().
+              &Apache::loncommon::start_data_table_header_row().
+              '<th>'.$lt{'heading'}.'</th>'.
+              &Apache::loncommon::end_data_table_header_row()."\n".
+              &Apache::loncommon::start_data_table_row()."\n".'<td>'.(<<ENDUPLOADFORM);
+      <fieldset style="line-height: 180%;">
+      <legend>$lt{'file'}</legend>
+      <input type="file" name="upfile" size="50" aria-label="'.$lt{'file'}.'" />
+      <br /><label>$lt{'type'}: $selectform</label>
+      </fieldset>
+ENDUPLOADFORM
+    $result.='</td>'.&Apache::loncommon::end_data_table_row()."\n".
+              &Apache::loncommon::start_data_table_row().'<td>'.(<<ENDGRADINGFORM);
+      <fieldset style="line-height: 185%;">
+      <legend>$lt{'mechanism'}</legend>
+      <label><input type="radio" name="gradingmechanism" value="attendance"$checked{'attendance'} onclick="sanitycheck()" />$lt{'attendance'} </label>
+<br /><label><input type="radio" name="gradingmechanism" value="personnel"$checked{'personnel'} onclick="sanitycheck()" />$lt{'personnel'}</label>
+<br /><label><input type="radio" name="gradingmechanism" value="specific"$checked{'specific'} onclick="sanitycheck()" />$lt{'specific'} </label>
+<input type="text" name="specificid" value="$env{'form.specificid'}" size="20" aria-label="'.$lt{'respid'}.'" />
+<br /><label><input type="radio" name="gradingmechanism" value="given"$checked{'given'} onclick="sanitycheck()" />$lt{'given'} <span style="font-size: 90%;"><tt>$lt{'comma'} $lt{'useskip'}</tt></span>  </label>
 <br />   
-<input type="text" name="givenanswer" size="50" />
+<input type="text" name="givenanswer" size="50" aria-label="'.$lt{'answers'}.'" />
 <input type="hidden" name="waschecked" value="$env{'form.gradingmechanism'}" />
+</fieldset>
 ENDGRADINGFORM
     $result.='</td>'.&Apache::loncommon::end_data_table_row().
                      &Apache::loncommon::start_data_table_row().'<td>'.(<<ENDPERCFORM);
-      <label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onchange="sanitycheck()" /></label>
-<br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="$env{'form.pincorrect'}" onchange="sanitycheck()" /></label>
-<br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$upload" />
-</form>
+      <fieldset style="line-height: 180%;">
+      <legend>$lt{'points'}</legend>
+      <label>$lt{'pcorrect'}: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onchange="sanitycheck()" /></label>
+      <br /><label>$lt{'pincorrect'}: <input type="text" name="pincorrect" size="4" value="$env{'form.pincorrect'}" onchange="sanitycheck()" /></label>
+      </fieldset>
 ENDPERCFORM
     $result.='</td>'.
-             &Apache::loncommon::end_data_table_row().
-             &Apache::loncommon::end_data_table();
+             &Apache::loncommon::end_data_table_row()."\n".
+             &Apache::loncommon::end_data_table()."\n".
+             '<br /><input type="button" onclick="javascript:checkUpload(this.form);" value="'.$lt{'upload'}.'" />'.
+             '</form>';
     return $result;
 }
 


More information about the LON-CAPA-cvs mailing list