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

raeburn raeburn at source.lon-capa.org
Fri Jan 16 10:43:01 EST 2026


raeburn		Fri Jan 16 15:43:01 2026 EDT

  Modified files:              
    /loncom/interface	courseprefs.pm 
  Log:
  - WCAG 2 compliance.
    - Replace use of <table> with <div> for layout
    - Include labels for form elements
    - Replace <td> ... </td> with <th> ... </th> for row titles on left
      side of inner (nested) tables.
    - Remove "<b> ... </b> from values for text items in row definitions,
    - Add link, subtext, label, legend, and id as keys in row definitions to
      facilitate formatting of row titles and creation of labels and fieldset
      legends for form elements in each row.
    - Sequential headings.
  
  
-------------- next part --------------
Index: loncom/interface/courseprefs.pm
diff -u loncom/interface/courseprefs.pm:1.140 loncom/interface/courseprefs.pm:1.141
--- loncom/interface/courseprefs.pm:1.140	Fri Jan 16 01:50:05 2026
+++ loncom/interface/courseprefs.pm	Fri Jan 16 15:43:01 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set configuration settings for a course
 #
-# $Id: courseprefs.pm,v 1.140 2026/01/16 01:50:05 raeburn Exp $
+# $Id: courseprefs.pm,v 1.141 2026/01/16 15:43:01 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -457,7 +457,10 @@
                     { text => 'Feedback messages',
                       help => 'Course_Prefs_Feedback',
                       header => [{col1 => 'Questions about:',
-                                  col2 => 'Recipients'}],
+                                  col2 => 'Recipients'},
+                                 {col1 => 'Replace default text:',
+                                  col2 => 'Custom text'},
+                                ],
                       ordered => ['question.email','comment.email','policy.email'],
                       itemtext => {
                                      'question.email' => 'Resource Content',
@@ -2640,7 +2643,7 @@
                 );
     foreach my $item (@{$prefs_order}) {
         if (grep(/^\Q$item\E$/,@{$actions})) {
-            $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';
+            $output .= '<h2 class="LC_heading_2">'.&mt($prefs->{$item}{'text'}).'</h2>';
             if (ref($changes->{$item}) eq 'HASH') {
                 if (keys(%{$changes->{$item}}) > 0) {
                     $output .= &mt('Changes made:').'<ul style="list-style:none;">';
@@ -4146,77 +4149,83 @@
         $editmap = (' 'x2).
                    '<a href="javascript:openbrowser'.
                    "('display','url','sequence')\">".
-                   &mt('Select Map').'</a><br /><span class="LC_warning"> '.
-                   &mt('Modification may make assessment data inaccessible!').
-                   '</span>';
+                   &mt('Select Map').'</a>';
         $editsyllabus = &mt('[_1]Edit[_2]','<a href="/public/'.$cdom.'/'.$cnum.'/syllabus?forceedit=1">',
                             '</a>');
     }
     my %items = (
         'url' => {
-                   text => '<b>'.&mt($itemtext->{'url'}).'</b>'.$editmap,
+                   text => &mt($itemtext->{'url'}),
+                   link => $editmap,
+                   subtext => '<span class="LC_warning">'.
+                               &mt('Modification may make assessment data inaccessible!').
+                               '</span>',
                    input => 'textbox',
                    size  => '55',
-                   advanced => 1
+                   advanced => 1,
+                   label => 'url',
                  },
         'description'  => { 
-                   text => '<b>'.&mt($itemtext->{'description'}).'</b>',
+                   text => &mt($itemtext->{'description'}),
                    input => 'textbox',
                    size  => '55',
+                   label => 'description',
                           },
         'owner'        => {
-                   text => '<b>'.&mt($itemtext->{'owner'}).'</b>',
+                   text => &mt($itemtext->{'owner'}),
                           },
         'co-owners'    => {
-                   text => '<b>'.&mt($itemtext->{'co-owners'}).'</b>',
+                   text => &mt($itemtext->{'co-owners'}),
                           },
         'clonedfrom'   => {
-                   text => '<b>'.&mt($itemtext->{'clonedfrom'}).'</b>',
+                   text => &mt($itemtext->{'clonedfrom'}),
                           },
         'courseid'     => { 
-                   text => '<b>'.&mt($itemtext->{'courseid'}).'</b><br />'.'('.
-                           &mt('internal, optional').')',
+                   text => &mt($itemtext->{'courseid'}),
+                   subtext => '('.&mt('internal, optional').')',
                    input => 'textbox',
                    size  => '25',
+                   label => 'courseid',
                           },
         'uniquecode'   => {
-                   text => '<b>'.&mt($itemtext->{'uniquecode'}).'</b>',
+                   text => &mt($itemtext->{'uniquecode'}),
                           },
         'cloners'      => { 
-                   text => '<b>'.&mt($itemtext->{'cloners'}).'</b><br />'.
-                           &mt('Owner and Coordinators included automatically').
-                           $clonedefaults,
+                   text => &mt($itemtext->{'cloners'}),
+                   subtext => &mt('Owner and Coordinators included automatically').$clonedefaults,
                    input => 'textbox',
                    size  => '40'
                          },
         'rolenames'  => { 
-                   text  => '<b>'.&mt($itemtext->{'rolenames'}).'</b><br />'.
-                            '('.$replace.')',
+                   text  => &mt($itemtext->{'rolenames'}),
+                   subtext => '('.$replace.')',
                    input => 'textbox',
                    size  => '20',
-                   advanced => 1
+                   advanced => 1,
                         },
         'syllabus' => {
-                   text => '<b>'.&mt($itemtext->{'syllabus'}).'</b><br />'.
-                           &mt('(Syllabus type in use)').(' ' x2).
-                           $editsyllabus,
-                        },
+                   text => &mt($itemtext->{'syllabus'}),
+                   subtext => &mt('(Syllabus type in use)').(' ' x2).
+                              $editsyllabus,
+                      },
         'hidefromcat' => {
-                   text => '<b>'.&mt($itemtext->{'hidefromcat'}).'</b><br />'.
-                           ' ('.&mt('included by default if assigned institutional code, or categorized').')',
+                   text => &mt($itemtext->{'hidefromcat'}),
+                   subtext => ' ('.&mt('included by default if assigned institutional code, or categorized').')',
                    input => 'radio',
+                   legend => &mt($itemtext->{'hidefromcat'}),
                          },
         'categories' => {
-                   text => '<b>'.&mt($itemtext->{'categories'}).'</b> <a href="javascript:catsbrowser()">'.
+                   text => &mt($itemtext->{'categories'}),
+                   link => '<a href="javascript:catsbrowser()">'.
                            &mt('Display Categories').'</a>',
                    input => 'textbox',
                    size  => '25',
                         },
         'loncaparev' => {
-                   text => '<b>'.&mt($itemtext->{'loncaparev'}).'</b>',
+                   text => &mt($itemtext->{'loncaparev'}),
                         },
         'defaultcredits' => {
-                   text => '<b>'.&mt($itemtext->{'defaultcredits'}).'</b>',
+                   text => &mt($itemtext->{'defaultcredits'}),
                         },
     );
     my $datatable;
@@ -4235,21 +4244,25 @@
         }
         $count ++;
         if (exists $items{$item}{advanced} && $items{$item}{advanced} == 1) {
-        	$datatable .= &item_table_row_start($items{$item}{text},$count,"advanced",$colspan);
+            $datatable .= &item_table_row_start($items{$item}{text},$items{$item}{link},$items{$item}{subtext},
+                                                $items{$item}{label},$count,"advanced",$colspan);
         } else {
-        	$datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
+            $datatable .= &item_table_row_start($items{$item}{text},$items{$item}{link},$items{$item}{subtext},
+                                                $items{$item}{label},$count,undef,$colspan);
         }
         if ($items{$item}{input} eq 'radio') {
-            $datatable .= &yesno_radio($item,$settings,undef,undef,undef,$noedit);
+            $datatable .= &yesno_radio($item,$items{$item}{legend},$settings,undef,undef,undef,$noedit);
         } elsif ($item eq 'cloners') {
             my $includeempty = 1;
             my $num = 0;
             $datatable .= '</td><td align="right">'.
-                          &Apache::loncommon::start_data_table().
-                          &Apache::loncommon::start_data_table_row().
-                          '<td><span class="LC_nobreak"><label>'.
-                          &mt('Any user in any domain:').
-                          ' <input type="radio" name="cloners_all" value="1" ';
+                          '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.$items{$item}{text}.'</legend>'.
+                          '<div role="grid" class="LC_grid" style="border: 1px solid black;">'.
+                          '<div role="row" class="LC_grid_row">'.
+                          '<div role="cell" class="LC_grid_cell">'.
+                          '<span class="LC_nobreak">'. 
+                          &mt('Any user in any domain:').' '.
+                          '<label><input type="radio" name="cloners_all" value="1" ';
             if ($settings->{$item} eq '*') {
                 $datatable .= ' checked="checked" ';
             }
@@ -4261,12 +4274,10 @@
                 $datatable .= ' checked="checked" ';
             }
             $datatable .= ' onchange="javascript:update_cloners('.
-                          "'cloners_all'".');"'.$disabled.' />'.&mt('No').'</label></td>'.
-                          &Apache::loncommon::end_data_table_row().
-                          &Apache::loncommon::end_data_table().
-                          '<table><tr><td align="left"><b>'.&mt('Or').
-                          '</b></td></tr></table>'.
-                          &Apache::loncommon::start_data_table();
+                          "'cloners_all'".');"'.$disabled.' />'.&mt('No').'</label>'.
+                          '</span></div></div></div>'.
+                          '<div><b>'.&mt('Or').'</b></div>'.
+                          '<div role="grid" class="LC_grid" style="border: 1px solid black;">';
             my @cloners;
             if ($settings->{$item} eq '') {
                 unless ($noedit) {
@@ -4290,15 +4301,18 @@
                         }
                         if ($uname eq '*') {
                             $datatable .= 
-                                &Apache::loncommon::start_data_table_row().
-                                '<td valign="top" align="left"><span class="LC_nobreak">'.
-                                &mt('Any user in domain:').'<b> '.$udom.
-                                '</b><input type="hidden" name="cloners_dom_'.$num.
+                                '<div role="row" class="LC_grid_row">'.
+                                '<div role="gridcell" class="LC_grid_cell" '.
+                                'style="vertical-align: top; text-align: left;">'.
+                                '<span class="LC_nobreak">'.
+                                &mt('Any user in domain:').
+                                ' <b>'.$udom.'</b>'.
+                                '<input type="hidden" name="cloners_dom_'.$num.
                                 '" value="'.$udom.'" /></span><br />'.
                                 '<span class="LC_nobreak"><label><input type="checkbox" '.
                                 'name="cloners_delete" value="'.$num.'" onchange="javascript:update_cloners('."'cloners_delete','$num'".');"'.$disabled.' />'.
-                                &mt('Delete').'</label></span></td>'.
-                                &Apache::loncommon::end_data_table_row();
+                                &mt('Delete').'</label></span></div>'.
+                                '</div>';
                             $num ++;
                         } elsif (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
                             unless (grep(/^\Q$entry\E$/, at cloners)) {
@@ -4310,31 +4324,31 @@
             }
             my $add_domtitle = &mt('Any user in additional domain:');
             if ($settings->{$item} eq '*') {
-                $add_domtitle = &mt('Any user in specific domain:');
-            } elsif ($settings->{$item} eq '') {
+                $add_domtitle = &mt('Any user in specific domain');
+            } elsif (($settings->{$item} eq '') || ($settings->{$item} !~ /\Q*:\E$match_domain/)) {
                 $add_domtitle = &mt('Any user in other domain:');
             }
             my $cloners_str = join(',', at cloners);
-            $datatable .= &Apache::loncommon::start_data_table_row().
-                          '<td align="left"><span class="LC_nobreak">'.
-                          $add_domtitle.'</span><br />'.
+            my $id = ' id="'.$item.'"';
+            $datatable .= '<div role="row" class="LC_grid_row">'.
+                          '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">'.
+                          '<span class="LC_nobreak"><label for="cloners_newdom">'.
+                          $add_domtitle.'</label></span><br />'.
                           &Apache::loncommon::select_dom_form('','cloners_newdom',
                                                               $includeempty,undef,undef,
-                                                              undef,undef,$noedit).
+                                                              undef,undef,$noedit,'cloners_newdom').
                           '<input type="hidden" name="cloners_total" value="'.$num.'" />'.
-                          '</td>'.&Apache::loncommon::end_data_table_row().
-                          &Apache::loncommon::end_data_table().
-                          '<table><tr><td align="left"><b>'.&mt('And').
-                          '</b></td></tr></table>'.
-                          &Apache::loncommon::start_data_table().
-                          &Apache::loncommon::start_data_table_row().
-                          '<td align="left">'.
-                          &mt('Specific users').' (<tt>'.
+                          '</div></div></div>'.
+                          '<div><b>'.&mt('And').'</b></div>'.
+                          '<div role="grid" class="LC_grid" style="border: 1px solid black;">'.
+                          '<div role="row" class="LC_grid_row">'.
+                          '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">'.
+                          '<label for="'.$item.'">'.
+                          &mt('Specific users').'</label> (<tt>'.
                           &mt('user:domain,user:domain').'</tt>)<br />'.
                           &Apache::lonhtmlcommon::textbox($item,$cloners_str,
-                                                          $items{$item}{'size'},$disabled).
-                          '</td>'.&Apache::loncommon::end_data_table_row().
-                          &Apache::loncommon::end_data_table();
+                                                          $items{$item}{'size'},$disabled.$id).
+                          '</div></div></div>';
             if (@code_order > 0) {
                 my (%cat_items, at codetitles,%cat_titles,%cat_order);
                 my ($jscript,$totcodes,$numtitles,$lasttitle) =
@@ -4349,11 +4363,11 @@
                     $checkedoff = '';
                     $showncodes = 'on';
                 }
-                $datatable .= '<table><tr><td align="left"><b>'.&mt('And').
-                              '</b></td></tr></table>'.
-                              &Apache::loncommon::start_data_table().
-                              &Apache::loncommon::start_data_table_row().
-                              '<td align="left"><span class="LC_nobreak">'.
+                $datatable .= '<div><b>'.&mt('And').'</b></div>'.
+                              '<div role="grid" class="LC_grid">'.
+                              '<div role="row" class="LC_grid_row">'.
+                              '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">'.
+                              '<span class="LC_nobreak">'.
                               &mt('Cloning by official course(s) based on course category').(' 'x2).
                               '<label>'.
                               '<input type="radio" name="cloners_instcode" value="1" onclick="toggleCloners(this);"'.$checkedon.$disabled.' />'.&mt('Yes').'</label>'.
@@ -4363,12 +4377,15 @@
                               &Apache::courseclassifier::build_instcode_selectors($numtitles,
                                   $lasttitle,\%cat_items,\@codetitles,\%cat_titles,\%cat_order,
                                   $showncodes,'LC_cloners_instcodes','LC_cloners_instcode',$noedit).
-                              '</td>'.&Apache::loncommon::end_data_table_row().
-                              &Apache::loncommon::end_data_table();
+                              '</div></div></div>';
             }
+            $datatable .= '</fieldset>'; 
         } elsif ($item eq 'rolenames') {
             $datatable .= '</td><td align="right">'.
-                          &Apache::loncommon::start_data_table();
+                          &Apache::loncommon::start_data_table().
+                          &Apache::loncommon::start_data_table_header_row().
+                          '<th>'.&mt('Standard title').'</th><th>'.&mt('Custom title').'</th>'.
+                          &Apache::loncommon::end_data_table_header_row();
             my @roles;
             if ($crstype eq 'Community') {
                 @roles = ('co');
@@ -4377,16 +4394,19 @@
             }
             push (@roles,('in','ta','ep','ad','st'));
             foreach my $role (@roles) {
+                my $name = 'rolenames_'.$role;
+                my $id = ' id="'.$name.'"';
                 $datatable .= &Apache::loncommon::start_data_table_row().
                               '<td align="left"><span class="LC_nobreak">'.
+                              '<label for="'.$name.'">'. 
                               &Apache::lonnet::plaintext($role,$crstype,undef,1).
-                              '</span></td><td align="left">'.
+                              '</label></span></td><td align="left">'.
                               &Apache::lonhtmlcommon::textbox('rolenames_'.$role,
                                                  $settings->{$role.'.plaintext'},
-                                                 $items{$item}{size},$disabled).'</td>'.
+                                                 $items{$item}{size},$disabled.$id).'</td>'.
                               &Apache::loncommon::end_data_table_row();
             }
-            $datatable .= &Apache::loncommon::end_data_table().'</td>';
+            $datatable .= &Apache::loncommon::end_data_table();
         } elsif ($item eq 'categories') {
             my $launcher;
             if ($noedit) {
@@ -4483,7 +4503,9 @@
             }
             $datatable .= $showreqd;
         } else {
-            $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size},$disabled);
+            my $id = ' id ="'.$item.'"';
+            $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},
+                                                          $items{$item}{size},$disabled.$id);
         }
         $datatable .= &item_table_row_end();
     }
@@ -4500,8 +4522,8 @@
         } else {
            $checkedoff = 'checked="checked" ';
         }
-        $output .= &Apache::loncommon::start_data_table_row().
-                   '<td valign="top"><span class="LC_nobreak">'.
+        $output .= '<div role="gridcell" class="LC_grid_cell" style="vertical-align: top;">'.
+                   '<span class="LC_nobreak">'.
                    &mt('Any user in domain:').' <b>'.$newdom.'</b>'.
                    (' 'x2).'<label><input type="radio" '.
                    'name="cloners_activate" value="'.$num.'" '.$checkedon.
@@ -4513,8 +4535,7 @@
                    'onchange="javascript:update_cloners('.
                    "'cloners_activate','$num'".');" />'.
                    &mt('No').'</label><input type="hidden" name="cloners_dom_'.
-                   $num.'" value="'.$newdom.'" /></span></td>'.
-                   &Apache::loncommon::end_data_table_row();
+                   $num.'" value="'.$newdom.'" /></span></div>';
     }
     return $output;
 }
@@ -5523,17 +5544,19 @@
     }
     my %items = (
         languages => {
-                        text => '<b>'.&mt($itemtext->{'languages'}).'</b><br />'.
-                                &mt("(overrides individual user preference)"),
+                        text => &mt($itemtext->{'languages'}),
+                        subtext => &mt("(overrides individual user preference)"),
                         input => 'selectbox',
                      }, 
         timezone => {
-                        text  => '<b>'.&mt($itemtext->{'timezone'}).'</b>',
+                        text  => &mt($itemtext->{'timezone'}),
                         input => 'selectbox',
+                        legend => &mt('Override user preference'),
                     },
         datelocale  => { 
-                         text => '<b>'.&mt($itemtext->{'datelocale'}).'</b>',
+                         text => &mt($itemtext->{'datelocale'}),
                          input => 'selectbox',
+                         label => 'datelocale',
                        },
     );
     my ($datatable,$disabled);
@@ -5547,7 +5570,8 @@
         unless ($item eq 'languages') {
             $colspan = 2;
         }
-        $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
+        $datatable .= &item_table_row_start($items{$item}{text},$items{$item}{link},$items{$item}{subtext},
+                                            $items{$item}{label},$count,undef,$colspan);
         if ($item eq 'timezone') {
             my $includeempty = 1;
             my $timezone = &Apache::lonlocal::gettimezone();
@@ -5564,10 +5588,9 @@
                 $tzsty = 'block';
             }
             $datatable .= '<div id="LC_tzoverdiv" style="display:'.$tzsty.';">'.
-                          '<span class="LC_nobreak">'.
                           &mt('Override individual user preference?').
-                          &yesno_radio('tzover',$settings,undef,1,'',$noedit).
-                          '</span></div>';
+                          &yesno_radio('tzover',$items{$item}{legend},$settings,undef,1,'',$noedit).
+                          '</div>';
         } elsif ($item eq 'datelocale') {
             my $includeempty = 1;
             my $locale_obj = &Apache::lonlocal::getdatelocale();
@@ -5577,18 +5600,24 @@
             }
             $datatable .= 
                 &Apache::loncommon::select_datelocale($item,$currdatelocale,
-                                                      undef,$includeempty,$disabled);
+                                                      undef,$includeempty,$disabled,$item);
         } else {
             if ($settings->{$item} eq '') {
                 unless ($noedit) {
+                    my $labeltext = &mt('Choose language');
                     $datatable .= '</td><td align="right">'.
-                        &Apache::loncommon::select_language('languages_0','',1);
+                        &Apache::loncommon::select_language('languages_0','',1,'','','',$labeltext);
                 }
             } else {
                 my $num = 0;
                 my @languages = split(/\s*[,;:]\s*/,$settings->{$item});
-                $datatable .= '</td><td align="right"><br />'.
-                              &Apache::loncommon::start_data_table();
+                $datatable .= '</td><td align="right"><br />';
+                if (@languages > 0) {
+                    $datatable .=
+                        '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+                        &mt('Add or remove languages').'</legend>';
+                }
+                $datatable .= &Apache::loncommon::start_data_table();
                 if (@languages > 0) {
                     my %langchoices = &get_lang_choices();
                     foreach my $lang (@languages) {
@@ -5597,6 +5626,9 @@
                             $showlang = $langchoices{$lang};
                         }
                         $datatable .=
+                            &Apache::loncommon::start_data_table_header_row('LC_visually_hidden').
+                            '<th>'.$items{$item}{text}.'</th>'.
+                            &Apache::loncommon::end_data_table_header_row()."\n".
                             &Apache::loncommon::start_data_table_row().
                             '<td align="left"><span class="LC_nobreak">'.
                             &mt('Language:').'<b> '.$showlang.
@@ -5605,20 +5637,24 @@
                             '<span class="LC_nobreak"><label><input type="checkbox" '.
                             'name="languages_delete" value="'.$num.'"'.$disabled.' />'.
                             &mt('Delete').'</label></span></td>'.
-                            &Apache::loncommon::end_data_table_row();
+                            &Apache::loncommon::end_data_table_row()."\n";
                             $num ++;
                     }
                 }
                 unless ($noedit) {
                     $datatable .=
                               &Apache::loncommon::start_data_table_row().
-                              '<td align="left"><span class="LC_nobreak">'.
-                              &mt('Additional language:'). '</span><br />'.
-                              &Apache::loncommon::select_language('languages_'.$num,'',1).
+                              '<td align="left"><label>'.
+                              &mt('Additional language:').'<br />'.
+                              &Apache::loncommon::select_language('languages_'.$num,'',1).'</label>'.
                               '<input type="hidden" name="languages_total" value="'.$num.'" />'.
-                              '</td>'.&Apache::loncommon::end_data_table_row();
+                              '</td>'.&Apache::loncommon::end_data_table_row()."\n";
                 }
-                $datatable .= &Apache::loncommon::end_data_table().'<br />';
+                $datatable .= &Apache::loncommon::end_data_table();
+                if (@languages > 0) {
+                    $datatable .= '</fieldset>';
+                }
+                $datatable .= '<br />';
             }
         }
         $datatable .= &item_table_row_end();
@@ -5645,21 +5681,27 @@
     }
     my %items = (
         'question.email' => {
-                   text => '<b>'.&mt($itemtext->{'question.email'}).'</b>',
+                   text => &mt($itemtext->{'question.email'}),
+                   subtext => '('.&mt('Custom text').')',
                    input => 'textbox',
                    size  => '50',
+                   label => 'question.email.text',
                  },
 
         'comment.email'  => {
-                   text => '<b>'.&mt($itemtext->{'comment.email'}).'</b>',
+                   text => &mt($itemtext->{'comment.email'}),
+                   subtext => '('.&mt('Custom text').')',
                    input => 'textbox',
                    size  => '50',
+                   label => 'comment.email.text',
                  },
 
         'policy.email'   => {
-                   text => '<b>'.&mt($itemtext->{'policy.email'}).'</b>',
+                   text => &mt($itemtext->{'policy.email'}),
+                   subtext => '('.&mt('Custom text').')',
                    input => 'textbox',
                    size  => '50',
+                   label => 'policy.email.text',
                  },
     );
     my $datatable;
@@ -5681,9 +5723,10 @@
     foreach my $item (@{$ordered}) {
         $count ++;
         if ($position eq 'top') {
-        	$datatable .= &item_table_row_start($items{$item}{text},$count);
+            $datatable .= &item_table_row_start($items{$item}{text},'','','',$count);
         } else {
-        	$datatable .= &item_table_row_start($items{$item}{text}."<br/>(Custom text)",$count, "advanced",2);
+            $datatable .= &item_table_row_start($items{$item}{text},'',$items{$item}{subtext},
+                                                $items{$item}{label},$count, "advanced",2);
         }
         if ($position eq 'top') {
             my $includeempty = 0;
@@ -5691,8 +5734,9 @@
                           &user_table($cdom,$item,\@sections,
                                       $settings->{$item},\%lt,$noedit);
         } else {
+            my $id = ' id="'.$item.'.text'.'"';
             $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
-                              $settings->{$item.'.text'},$items{$item}{size},$disabled);  
+                              $settings->{$item.'.text'},$items{$item}{size},$disabled.$id);
         }
         $datatable .= &item_table_row_end();
     }
@@ -5710,7 +5754,7 @@
     } else {
         my $num = 0;
         my @curr = split(/,/,$currvalue);
-        $output .= '<table class="LC_data_table">';
+        $output .= '<div role="grid" class="LC_grid">';
         my ($currusers);
         my $disabled;
         if ($noedit) {
@@ -5724,10 +5768,10 @@
                 $seclist =~ s/(^\(|\)$)//g;
                 @selsec = split(/\s*;\s*/,$seclist);
             }
-            $currusers .= '<tr>'.
-                        '<td valign="top"><span class="LC_nobreak">'.
-                        '<label><input type="checkbox" '.
-                        'name="'.$item.'_delete" value="'.$num.'"'.$disabled.' />'.
+            $currusers .= '<div role="row" class="LC_grid_row">'.
+                        '<div role="gridcell" class="LC_grid_cell" style="vertical-align: top;">'.
+                        '<span class="LC_nobreak"><label>'.
+                        '<input type="checkbox" name="'.$item.'_delete" value="'.$num.'"'.$disabled.' />'.
                         $lt->{'del'}.'</label>'.
                         '<input type="hidden" name="'.$item.'_user_'.
                         $num.'" value="'.$uname.':'.$udom.'" />'.(' 'x2).
@@ -5738,61 +5782,68 @@
                 if (@{$sections}) {
                     $currusers.= (' 'x3).$lt->{'sec'}.' '.
                                   &select_sections($item,$num,$sections,
-                                  \@selsec,$noedit);
+                                  \@selsec,$noedit,'','',$item);
                 }
             }
-            $currusers .= '</span></td></tr>';
+            $currusers .= '</span></div></div>';
             $num ++;
         }
         if ($num) {
-            $output .= '<tr>'.
-                       '<td align="left"><i>';
+            $output .= '<div role="row" class="LC_grid_row">'.
+                       '<div role="gridcell" style="text-align: left"><i>';
             if ($num == 1) {
                 $output .= $lt->{'currone'};
             } else {
                 $output .= $lt->{'currmult'};
             }
             $output .= '</i><br />'.
-                          '<table>'.$currusers.'</table></td>'.
-                          '</tr>';
+                          '<div role="grid" class="LC_grid">'.$currusers.'</div></div>'.
+                          '</div>';
         }
         unless ($noedit) {
             $output .= 
-                  '<tr>'.
-                  '<td align="left"><span class="LC_nobreak"><i>'.
-                  $lt->{'add'}.'</i></span><br />'.
+                  '<div role="row" class="LC_grid_row">'.
+                  '<div role="gridcell" style="text-align: left">'.
+		  '<span class="LC_nobreak"><i>'.$lt->{'add'}.'</i></span><br />'.
                   &select_recipient($item,$num,$cdom,$sections).
                   '<input type="hidden" name="'.$item.'_total" value="'.$num.'" />'.
-                  '</td></tr>';
+                  '</div></div>';
         }
-        $output .= '</table>';
+        $output .= '</div>';
     }
     return $output;
 }
 
 sub select_recipient {
     my ($item,$num,$cdom,$sections,$selected,$includeempty) = @_;
-    my $domform = &Apache::loncommon::select_dom_form($cdom,$item.'_udom_'.$num,$includeempty);
+    my $domelem = $item.'_udom_'.$num;
+    my $domform = &Apache::loncommon::select_dom_form($cdom,$domelem,$includeempty,
+                                                      '','','','','',$domelem);
     my $selectlink =
         &Apache::loncommon::selectstudent_link('display',$item.'_uname_'.$num,
                                                $item.'_udom_'.$num,'only');
     my $output = 
-        '<table><tr><td align="center">'.&mt('Username').'<br />'.
-        '<input type="text" name="'.$item.'_uname_'.$num.'" value="" /></td>'.
-        '<td align="center">'.&mt('Domain').'<br />'.$domform.'</td>';
+        '<div role="grid" class="LC_grid" style="margin: 1px; padding: 0;">'.
+        '<div role="row" class="LC_grid_row">'.
+        '<div role="gridcell" class="LC_grid_cell" style="text-align: center">'.
+        '<label>'.&mt('Username').'<br />'.
+        '<input type="text" name="'.$item.'_uname_'.$num.'" value="" /></label></div>'.
+        '<div role="gridcell" class="LC_grid_cell" style="text-align: center">'.
+        '<label for="'.$domelem.'">'.&mt('Domain').'</label><br />'.$domform.'</div>';
     if (ref($sections) eq 'ARRAY') {
         if (@{$sections}) {
-            $output .= '<td align="center">'.&mt('Sections').'<br />'.
-                       &select_sections($item,$num,$sections,$selected).'</td>'; 
+            $output .= '<div role="gridcell" class="LC_grid_cell" style="text-align: center">'.
+                       &mt('Sections').'<br />'.
+                       &select_sections($item,$num,$sections,$selected,'','','',$item).'</div>'; 
         }
     }
-    $output .= '<td valign="top">'.
-               $selectlink.'</td></tr></table>';
+    $output .= '<div role="gridcell" class="LC_grid_cell" style="vertical-align: top;">'.
+               $selectlink.'</div></div></div>';
     return $output;
 }
 
 sub select_sections {
-    my ($item,$num,$sections,$selected,$noedit,$allval) = @_;
+    my ($item,$num,$sections,$selected,$noedit,$allval,$id,$arialabel) = @_;
     my ($output, at currsecs,$allsec,$disabled);
     if (ref($selected) eq 'ARRAY') {
         @currsecs = @{$selected};
@@ -5820,16 +5871,22 @@
             unless ($item eq 'hidetotals') {
                 $name .= '_'.$num;
             }
-            $output = '<select name="'.$name.'"'.$mult.$disabled.'>'.
-                      ' <option value="'.$allval.'"'.$allsec.'>'.&mt('All').'</option>';
+            $output = '<select name="'.$name.'"'.$mult.$disabled;
+            if ($id ne '') {
+                $output .= ' id="'.$id.'"';
+            }
+            if ($arialabel ne '') {
+                $output .= ' aria-label="'.$arialabel.'"';
+            }
+            $output .= '>'."\n".'<option value="'.$allval.'"'.$allsec.'>'.&mt('All').'</option>';
             foreach my $sec (@{$sections}) {
                 my $is_sel;
                 if ((@currsecs) && (grep(/^\Q$sec\E$/, at currsecs))) {
                     $is_sel = ' selected="selected"';
                 }
-                $output .= '<option value="'.$sec.'"'.$is_sel.'>'.$sec.'</option>';
+                $output .= '<option value="'.$sec.'"'.$is_sel.'>'.$sec.'</option>'."\n";
             }
-            $output .= '</select>';
+            $output .= '</select>'."\n";
         }
     }
     return $output;
@@ -5842,55 +5899,60 @@
     }
     my %items = (
         'plc.roles.denied' => {
-                   text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'plc.roles.denied'}).'</b>'.
-                           &Apache::loncommon::help_open_topic("Course_Disable_Discussion").'</span><br />'.
-                           &mt('(role-based)'),
+                   text => '<span class="LC_nobreak">'.&mt($itemtext->{'plc.roles.denied'}).
+                           &Apache::loncommon::help_open_topic("Course_Disable_Discussion").
+                           '</span>',
+                   subtext => &mt('(role-based)'),
                    input => 'checkbox',
                  },
 
         'plc.users.denied'  => {
-                   text => '<b>'.&mt($itemtext->{'plc.users.denied'}).'</b><br />'.
-                           &mt('(specific user(s))'),
+                   text => &mt($itemtext->{'plc.users.denied'}),
+                   subtext => &mt('(specific user(s))'),
                    input => 'checkbox',
                  },
 
         'pch.roles.denied'   => {
-                   text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'pch.roles.denied'}).'</b>'.
-                           &Apache::loncommon::help_open_topic("Course_Disable_Discussion").'</span><br />'.
-                           &mt('(role-based)'),
+                   text => '<span class="LC_nobreak">'.&mt($itemtext->{'pch.roles.denied'}).
+                           &Apache::loncommon::help_open_topic("Course_Disable_Discussion").
+                           '</span>',
+                   subtext => &mt('(role-based)'),
                    input => 'checkbox',
                  },
 
         'pch.users.denied'   => {
-                   text => '<b>'.&mt($itemtext->{'pch.users.denied'}).'</b><br />'.
-                           &mt('(specific user(s))'),
+                   text => &mt($itemtext->{'pch.users.denied'}),
+                   subtext => &mt('(specific user(s))'),
                    input => 'checkbox',
                  },
 
         'pac.roles.denied' => {
-                   text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'pac.roles.denied'}).'</b>'.
-                           &Apache::loncommon::help_open_topic("Course_Disable_Anonymous_Discussion").'</span><br />'.
-                           &mt('(role-based)'),
+                   text => '<span class="LC_nobreak">'.&mt($itemtext->{'pac.roles.denied'}).
+                           &Apache::loncommon::help_open_topic("Course_Disable_Anonymous_Discussion").
+                           '</span>',
+                   subtext => &mt('(role-based)'),
                    input => 'checkbox',
                  },
 
         'pac.users.denied'   => {
-                   text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'pac.users.denied'}).'</b><br />'.
-                           &mt('(specific user(s))'),
+                   text => &mt($itemtext->{'pac.users.denied'}),
+                   subtext => &mt('(specific user(s))'),
                    input => 'checkbox',
                  },
 
         'allow_limited_html_in_feedback' => {
-                   text => '<b>'.&mt($itemtext->{'allow_limited_html_in_feedback'}).'</b>',
+                   text => &mt($itemtext->{'allow_limited_html_in_feedback'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'allow_limited_html_in_feedback'}),
                  },
 
         'allow_discussion_post_editing' => {
-                   text => '<b>'.&mt($itemtext->{'allow_discussion_post_editing'}).'</b>',
+                   text => &mt($itemtext->{'allow_discussion_post_editing'}),
                    input => 'checkbox',
                  },
+
         'discussion_post_fonts' => {
-                   text => '<b>'.&mt($itemtext->{'discussion_post_fonts'}).'</b>',
+                   text => &mt($itemtext->{'discussion_post_fonts'}),
                    input => 'textbox',
                    size  => '20',
                  },
@@ -5913,52 +5975,64 @@
         if ($item eq 'allow_limited_html_in_feedback') {
             $colspan = 2;
         }
-        $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
+        $datatable .= &item_table_row_start($items{$item}{text},$items{$item}{link},$items{$item}{subtext},
+                                            $items{$item}{label},$count,undef,$colspan);
         if ($item eq 'plc.roles.denied') {
             $datatable .= '</td><td align="right">'.
-                          '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit).
-                          '</table>';
+                          '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+                          $items{$item}{text}.' '.$items{$item}{subtext}.'</legend>'. 
+                          '<div role="grid" class="LC_grid" style="margin: 1px; padding: 0;">'.
+                          &role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit).
+                          '</div></fieldset>';
         } elsif ($item eq 'plc.users.denied') {
             $datatable .= '</td><td align="right">'.
                           &user_table($cdom,$item,undef,
                                       $settings->{$item},\%lt,$noedit);
         } elsif ($item eq 'pch.roles.denied') {
             $datatable .= '</td><td align="right">'.
-                          '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit).
-                          '</table>';
+                          '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+                          $items{$item}{text}.' '.$items{$item}{subtext}.'</legend>'.
+                          '<div role="grid" class="LC_grid" style="margin: 1px; padding: 0;">'.
+                          &role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit).
+                          '</div></fieldset>';
         } elsif ($item eq 'pch.users.denied') {
             $datatable .= '</td><td align="right">'.
                           &user_table($cdom,$item,undef,
                                       $settings->{$item},\%lt,$noedit);
         } elsif ($item eq 'pac.roles.denied') {
             $datatable .= '</td><td align="right">'.
-                          '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit).
-                          '</table>';
+                          '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+                          $items{$item}{text}.' '.$items{$item}{subtext}.'</legend>'.
+                          '<div role="grid" class="LC_grid" style="margin: 1px; padding: 0;">'.
+                          &role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit).
+                          '</div></fieldset>';
         } elsif ($item eq 'pac.users.denied') {
             $datatable .=  '</td><td align="right">'.
                            &user_table($cdom,$item,undef,
                                       $settings->{$item},\%lt,$noedit);
         } elsif ($item eq 'allow_limited_html_in_feedback') {
-            $datatable .= &yesno_radio($item,$settings,undef,undef,undef,$noedit);
+            $datatable .= &yesno_radio($item,$items{$item}{legend},$settings,undef,undef,undef,$noedit);
         } elsif ($item eq 'allow_discussion_post_editing') {
-            $datatable .= '</td><td align="right"><br />'.
-                          &Apache::loncommon::start_data_table().
-                          &Apache::loncommon::start_data_table_row().
-                          '<th align="left">'.&mt('Role').'</th><th>'.
-                          &mt('Sections').'</th>'.
-                          &Apache::loncommon::end_data_table_row().
+            $datatable .= '</td><td align="right"><br /><fieldset class="LC_borderless">'.
+                          '<legend class="LC_visually_hidden">'.
+                          &mt($itemtext->{$item}).'</legend>'.
+                          &Apache::loncommon::start_data_table('LC_nested_inner').
+                          &Apache::loncommon::start_data_table_header_row().
+                          '<th align="left">'.&mt('Role').'</th>'.
+                          '<th>'.&mt('Sections').'</th>'.
+                          &Apache::loncommon::end_data_table_header_row().
                           &role_checkboxes($cdom,$cnum,$item,$settings,1,undef,$noedit).
-                          &Apache::loncommon::end_data_table().'<br />';
+                          &Apache::loncommon::end_data_table().'</fieldset><br />';
         } elsif ($item eq 'discussion_post_fonts') {
             $datatable .= '</td><td align="right"><br />'.
-                          &Apache::loncommon::start_data_table().
-                          &Apache::loncommon::start_data_table_row().
-                          '<th align="center">'.&mt('Sum of likes/dislikes').'</th>'.
-                          '<th align="center">'.&mt('font-size').'</th>'.
-                          '<th align="center">'.&mt('font-weight').'</th>'.
-                          '<th align="center">'.&mt('font-style').'</th>'.
-                          '<th align="center">'.&mt('Other css').'</th>'.
-                          &Apache::loncommon::end_data_table_row().
+                          &Apache::loncommon::start_data_table('LC_nested_inner').
+                          &Apache::loncommon::start_data_table_header_row().
+                          '<th>'.&mt('Sum of likes/dislikes').'</th>'.
+                          '<th>'.&mt('font-size').'</th>'.
+                          '<th>'.&mt('font-weight').'</th>'.
+                          '<th>'.&mt('font-style').'</th>'.
+                          '<th>'.&mt('Other css').'</th>'.
+                          &Apache::loncommon::end_data_table_header_row().
                           &set_discussion_fonts($cdom,$cnum,$item,$settings,$noedit).
                           &Apache::loncommon::end_data_table().'<br />';
         }
@@ -6018,23 +6092,27 @@
         }
         my $plrole=&Apache::lonnet::plaintext($role,$crstype);
         if ($showsections) {
-            $output .= &Apache::loncommon::start_data_table_row();
+            $output .= &Apache::loncommon::start_data_table_row().
+                       '<td align="left">';
         } else {
             my $rem = $count%($numinrow);
             if ($rem == 0) {
                 if ($count > 0) {
-                    $output .= '</tr>';
+                    $output .= '</div>';
                 }
-                $output .= '<tr>';
+                $output .= '<div role="row" class="LC_grid_row">';
             }
+            $output .= '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">';
         }
-        $output .= '<td align="left"><span class="LC_nobreak"><label><input type="checkbox" name="'.
+        $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="'.
                    $item.'" value="'.$role.'"'.$checked.$disabled.'/> '.
-                   $plrole.'</label></span></td>';
+                   $plrole.'</label></span>';
         if ($showsections) {
-            $output .= '<td align="left">'.
-                       &select_sections($item,$role,\@sections,$currsec{$role},$noedit).
+            $output .= '</td><td align="left">'.
+                       &select_sections($item,$role,\@sections,$currsec{$role},$noedit,'','',$item).
                        '</td></tr>';
+        } else {
+            $output .= '</div>';
         }
         $count ++;
     }
@@ -6050,38 +6128,33 @@
                 $checked = ' checked="checked" ';
             }
             if ($showsections) {
-                $output .= &Apache::loncommon::start_data_table_row();
+                $output .= &Apache::loncommon::start_data_table_row().'<td>';
             } else {
                 my $rem = $count%($numinrow);
                 if ($rem == 0) {
                     if ($count > 0) {
-                        $output .= '</tr>';
+                        $output .= '</div>';
                     }
-                    $output .= '<tr>';
+                    $output .= '<div role="row" class="LC_grid_row">';
                 }
+                $output .= '<div role="gridcell" class="LC_grid_cell">';
             }
-            $output .= '<td><span class="LC_nobreak"><label><input type="checkbox" name="'.
+            $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="'.
                        $item.'" value="'.$value.'"'.$checked.$disabled.' /> '.$rolename.
-                       '</label></span></td>';
+                       '</label></span>';
             if ($showsections) {
-                $output .= '<td>'.
-                           &select_sections($item,$role,\@sections,$currsec{$role},$noedit).
+                $output .= '</td><td>'.
+                           &select_sections($item,$role,\@sections,$currsec{$role},$noedit,'','',$item).
                            '</td>'.&Apache::loncommon::end_data_table_row();
+            } else {
+                $output .= '</div>';
             }
             $total ++;
             $count ++;
         }
     }
     if (!$showsections) {
-        my $rem = $total%($numinrow);
-        my $colsleft = $numinrow - $rem;
-        if ($colsleft > 1 ) {
-            $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
-                       ' </td>';
-        } elsif ($colsleft == 1) {
-            $output .= '<td class="LC_left_item"> </td>';
-        }
-        $output .= '</tr>';
+        $output .= '</div>';
     }
     return $output;
 }
@@ -6112,12 +6185,12 @@
                             ($currsize,$currunit) = ($1,$2);
                             $curr{'size'} = $currunit;
                         }
-                        $output .= '<input type="textbox" name="discussion_post_fonts_'.$cat.'_'.$item.'" value="'.$currsize.'" size="5"'.$disabled.' />'.
+                        $output .= '<input type="text" name="discussion_post_fonts_'.$cat.'_'.$item.'" value="'.$currsize.'" size="5"'.$disabled.' aria-label="'.&mt("$item for $cat").'" />'.
                                    ' ';
                         $selitem = 'unit';
                     }
                     if ((ref($styleitems) eq 'HASH') && (ref($styleitems->{$item}) eq 'ARRAY')) {
-                        $output .= '<select name="discussion_post_fonts_'.$cat.'_'.$selitem.'"'.$disabled.'>';
+                        $output .= '<select name="discussion_post_fonts_'.$cat.'_'.$selitem.'"'.$disabled.' aria-label="'.&mt("$selitem for $cat").'">';
                         foreach my $val (@{$styleitems->{$item}}) {
                             my $sel;
                             if ($val eq $curr{$item}) {
@@ -6130,7 +6203,9 @@
                     $output .= '</span></td>'."\n";
                 }
             }
-            $output .= '<td><input type="textbox" size="10" name="discussion_post_fonts_'.$cat.'_other" value="'.$curr{'other'}.'"'.$disabled.' /></td>'.&Apache::loncommon::end_data_table_row();
+            $output .= '<td><input type="text" size="10" name="discussion_post_fonts_'.$cat.'_other" '.
+                       'value="'.$curr{'other'}.'"'.$disabled.' aria-label="'.&mt("Other css for $cat").'" />'.
+                       '</td>'.&Apache::loncommon::end_data_table_row();
         }
     }
     return $output;
@@ -6194,42 +6269,44 @@
 
     my %items = (
         'default_enrollment_start_date' => {
-                   text => '<b>'.&mt($itemtext->{'default_enrollment_start_date'}).'</b>',
+                   text => &mt($itemtext->{'default_enrollment_start_date'}),
                    input => 'dates',
                  },
         'default_enrollment_end_date'  => {
-                   text => '<b>'.&mt($itemtext->{'default_enrollment_end_date'}).'</b>',
+                   text => &mt($itemtext->{'default_enrollment_end_date'}),
                    input => 'dates',
                  },
         'defaultcredits' => {
-                   text => '<b>'.&mt($itemtext->{'defaultcredits'}).'</b>',
+                   text => &mt($itemtext->{'defaultcredits'}),
                  },
 
         'nothideprivileged'   => {
-                   text => '<b>'.&mt($itemtext->{'nothideprivileged'}).'</b>',
+                   text => &mt($itemtext->{'nothideprivileged'}),
                    input => 'checkbox',
                  },
 
         'checkforpriv' => {
-                   text => '<b>'.&mt($itemtext->{'checkforpriv'}).'</b>',
+                   text => &mt($itemtext->{'checkforpriv'}),
                    input => 'selectbox',
                  },
 
         'student_classlist_view'   => {
-                   text => '<b>'.&mt($itemtext->{'student_classlist_view'}).'</b>',
+                   text => &mt($itemtext->{'student_classlist_view'}),
                    input => 'selectbox',
                    options => \%lt,
                    order => ['disabled','all','section'],
                    id => 'student_classlist_view',
                  },
         'student_classlist_opt_in' => {
-                   text => '<b>'.&mt($itemtext->{'student_classlist_opt_in'}).'</b>',
+                   text => &mt($itemtext->{'student_classlist_opt_in'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'student_classlist_opt_in'}),
                  },
 
         'student_classlist_portfiles' => {
-                   text => '<b>'.&mt($itemtext->{'student_classlist_portfiles'}).'</b>',
+                   text => &mt($itemtext->{'student_classlist_portfiles'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'student_classlist_portfiles'}),
                  },
     );
     unless (($settings->{'student_classlist_view'} eq 'all') || 
@@ -6252,24 +6329,27 @@
     }
     my %items = (
         'default_xml_style' => {
-                   text => '<b>'.&mt($itemtext->{'default_xml_style'}).'</b> '.
-                           '<a href="javascript:openbrowser'.
+                   text => &mt($itemtext->{'default_xml_style'}),
+                   link => '<span class="LC_nobreak"><a href="javascript:openbrowser'.
                            "('display','default_xml_style'".
-                           ",'sty')".'">'.&mt('Select Style File').'</a>',
+                           ",'sty')".'">'.&mt('Select Style File').'</a></span>',
                    input => 'textbox',
                    size => 35,
+                   id => 'default_xml_style',         
                  },
 
         'pageseparators'  => {
-                   text => '<b>'.&mt($itemtext->{'pageseparators'}).'</b>',
+                   text => &mt($itemtext->{'pageseparators'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'pageseparators'}),
                  },
         'disable_receipt_display' => {
-                   text => '<b>'.&mt($itemtext->{'disable_receipt_display'}).'</b>',
+                   text => &mt($itemtext->{'disable_receipt_display'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'disable_receipt_display'})
                  },
         'texengine'  => {
-                   text => '<b>'.&mt($itemtext->{'texengine'}).'</b>',
+                   text => &mt($itemtext->{'texengine'}),
                    input => 'selectbox',
                    options => {
                                 MathJax  => 'MathJax',
@@ -6278,26 +6358,31 @@
                               },
                    order  => ['MathJax','mimetex','tth'],
                    nullval => $mathdef,
+                   id => 'texengine',
                  },
         'tthoptions' => {
-                   text => '<b>'.&mt($itemtext->{'tthoptions'}).'</b>',
+                   text => &mt($itemtext->{'tthoptions'}),
                    input => 'textbox',
                    size => 40,
+                   id => 'tthoptions', 
                  },
          'uselcmath' => {
-                   text => '<b>'.&mt($itemtext->{'uselcmath'}).'</b>',
+                   text => &mt($itemtext->{'uselcmath'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'uselcmath'}),
                  },
          'usejsme'  => {
-                   text => '<b>'.&mt($itemtext->{'usejsme'}).'</b>',
+                   text => &mt($itemtext->{'usejsme'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'usejsme'}),
                  },
          'inline_chem' => {
-                   text => '<b>'.&mt($itemtext->{'inline_chem'}).'</b>',
+                   text => &mt($itemtext->{'inline_chem'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'inline_chem'}),
                  },
          'extresource' => {
-                   text => '<b>'.&mt($itemtext->{'extresource'}).'</b>',
+                   text => &mt($itemtext->{'extresource'}),
                    input => 'selectbox',
                    options => {
                                 iframe => 'In iframe',
@@ -6305,6 +6390,7 @@
                                 window => 'In pop-up window',
                               },
                    order  => ['iframe','tab','window'],
+                   id => 'LC_extresource',
                  },
     );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'appearance',$noedit);
@@ -6317,7 +6403,7 @@
     }
     my %items = (
         'grading'  => {
-                   text => '<b>'.&mt($itemtext->{'grading'}).'</b>'.
+                   text => &mt($itemtext->{'grading'}).
                            &Apache::loncommon::help_open_topic('GradingOptions'),
                    input => 'selectbox',
                    options => {
@@ -6328,12 +6414,13 @@
                                 spreadsheet => &mt('Spreadsheet: (with link to detailed scores)'), 
                               },
                    order => ['standard','categories','external','externalnototals','spreadsheet'],
+                   id => 'grading',
                  },
         'rndseed' => {
-                   text => '<b>'.&mt($itemtext->{'rndseed'}).'</b>'.
-                           '<br /><span class="LC_warning LC_nobreak">'.
-                           &mt('Modifying this will make problems have different numbers and answers!').
-                           '</span>',
+                   text => &mt($itemtext->{'rndseed'}),
+                   subtext => '<span class="LC_warning LC_nobreak">'.
+                              &mt('Modifying this will make problems have different numbers and answers!').
+                              '</span>',
                    input => 'selectbox',
                    options => {
                                 '32bit'  => '32bit',
@@ -6344,11 +6431,12 @@
                                 '64bit5' => '64bit5',
                               },
                    order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],
-                   advanced => 1
+                   advanced => 1,
+                   id => 'rndseed',
                  },
         'receiptalg'  => {
-                   text => '<b>'.&mt($itemtext->{'receiptalg'}).'</b><br />'.
-                           &mt('This controls how receipt numbers are generated'),
+                   text => &mt($itemtext->{'receiptalg'}),
+                   subtext => &mt('This controls how receipt numbers are generated'),
                    input => 'selectbox',
                    options => {
                                 receipt  => 'receipt',
@@ -6356,11 +6444,13 @@
                                 receipt3 => 'receipt3',
                               },
                    order => ['receipt','receipt2','receipt3'],
-                   advanced => 1
+                   advanced => 1,
+                   id => 'receiptalg',
                  },
         'disablesigfigs' => {
-                   text => '<b>'.&mt($itemtext->{'disablesigfigs'}).'</b>',
+                   text => &mt($itemtext->{'disablesigfigs'}),
                    input => 'radio',
+                   legend => &mt($itemtext->{'disablesigfigs'}),
                  },
     );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'grading',$noedit,$cnum);
@@ -6373,15 +6463,17 @@
     }
     my %items = (
         problem_stream_switch => {
-            text => '<b>'.&mt($itemtext->{'problem_stream_switch'}).'</b>',
+            text => &mt($itemtext->{'problem_stream_switch'}),
             input => 'radio',
+            legend => &mt($itemtext->{'problem_stream_switch'}),
                                  },
         suppress_tries => {
-            text => '<b>'.&mt($itemtext->{'suppress_tries'}).'</b>',
+            text => &mt($itemtext->{'suppress_tries'}),
             input => 'radio',
+            legend => &mt($itemtext->{'suppress_tries'}),
                           },
         default_paper_size => {
-            text => '<b>'.&mt($itemtext->{'default_paper_size'}).'</b>',
+            text => &mt($itemtext->{'default_paper_size'}),
             input => 'selectbox',
             options => {
                          Letter    => &mt('Letter').' [8 1/2x11 in]',
@@ -6396,17 +6488,19 @@
                        },
             order => ['Letter','Legal','Tabloid','Executive','A2','A3','A4','A5','A6'],
             nullval => &mt('None specified'),
+            id => 'default_paper_size',
                               },
         print_header_format => {
-            text => '<b>'.&mt($itemtext->{'print_header_format'}).'</b>',
+            text => &mt($itemtext->{'print_header_format'}),
             input => 'checkbox',
                                },
         disableexampointprint => {
-            text => '<b>'.&mt($itemtext->{'disableexampointprint'}).'</b>',
+            text => &mt($itemtext->{'disableexampointprint'}),
             input => 'radio',
+            legend => &mt($itemtext->{'disableexampointprint'}),
                                  },
         canuse_pdfforms => {
-            text  => '<b>'.&mt($itemtext->{'canuse_pdfforms'}).'</b>',
+            text  => &mt($itemtext->{'canuse_pdfforms'}),
             input => 'selectbox',
             options => {
                          1    => &mt('Yes'),
@@ -6414,6 +6508,7 @@
                        },
             order => ['1','0'],
             nullval => &mt('None specified - use domain default'),
+            id => 'canuse_pdfforms',
                     }
     );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'printouts',$noedit);
@@ -6427,29 +6522,33 @@
     my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
     my %items = (
         spreadsheet_default_classcalc => {
-            text => '<b>'.&mt($itemtext->{'spreadsheet_default_classcalc'}).'</b> '.
-                    '<span class="LC_nobreak"><a href="javascript:openbrowser'.
+            text => &mt($itemtext->{'spreadsheet_default_classcalc'}),
+            link => '<span class="LC_nobreak"><a href="javascript:openbrowser'.
                     "('display','spreadsheet_default_classcalc'".
                     ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
             input => 'textbox',
+            id    => 'spreadsheet_default_classcalc',
                                          },
         spreadsheet_default_studentcalc => {
-            text => '<b>'.&mt($itemtext->{'spreadsheet_default_studentcalc'}).'</b> '.
-                    '<span class="LC_nobreak"><a href="javascript:openbrowser'.
+            text => &mt($itemtext->{'spreadsheet_default_studentcalc'}),
+            link => '<span class="LC_nobreak"><a href="javascript:openbrowser'.
                     "('display','spreadsheet_default_calc'".
                     ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
             input => 'textbox',
+            id    => 'spreadsheet_default_studentcalc',
                                            },
         spreadsheet_default_assesscalc => {
-            text => '<b>'.&mt($itemtext->{'spreadsheet_default_assesscalc'}).'</b> '.
-                    '<span class="LC_nobreak"><a href="javascript:openbrowser'.
+            text => &mt($itemtext->{'spreadsheet_default_assesscalc'}),
+            link => '<span class="LC_nobreak"><a href="javascript:openbrowser'.
                     "('display','spreadsheet_default_assesscalc'".
                     ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
             input => 'textbox',
+            id    => 'spreadsheet_default_assesscalc',
                                           },
         hideemptyrows => {
-            text => '<b>'.&mt($itemtext->{'hideemptyrows'}).'</b>',
+            text => &mt($itemtext->{'hideemptyrows'}),
             input => 'radio',
+            legend => &mt($itemtext->{'hideemptyrows'}),
                          },
                 );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'spreadsheet',$noedit);
@@ -6470,7 +6569,7 @@
     }
     my %items = (
          task_messages => {
-              text => '<b>'.&mt($itemtext->{'task_messages'}).'</b>',
+              text => &mt($itemtext->{'task_messages'}),
               input => 'selectbox',
               options => {
                            only_student => $stumsg,
@@ -6478,20 +6577,23 @@
                          },
               order   => ['only_student','student_and_user_notes_screen'],
               nullval => &mt('No message or record in user notes'),
+              id => 'task_messages',
                           },
          task_grading => {
-              text => '<b>'.&mt($itemtext->{'task_grading'}).'</b>',
+              text => &mt($itemtext->{'task_grading'}),
               input => 'selectbox',
               options => {
                            any => &mt('Grade BTs in any section'),
                            section => &mt('Grade BTs only in own section')
                          },
               order => ['any','section'],
+              id => 'task_grading',
                          },
          suppress_embed_prompt => {
-             text => '<b>'.&mt($itemtext->{'suppress_embed_prompt'}).'</b><span class="LC_nobreak">'.
-                     ' '.&mt('(applies when current role is student)').'</span>',
+             text => &mt($itemtext->{'suppress_embed_prompt'}),
+             subtext => &mt('(applies when current role is student)'),
              input => 'radio',
+             legend => &mt($itemtext->{'suppress_embed_prompt'}),
                                   },
                 );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'bridgetasks',$noedit);
@@ -6601,37 +6703,37 @@
                 &mt('Delete?').'</label></span></td>'.
                 '<td colspan="2">'.
                 '<fieldset><legend>'.&mt('Required settings').'</legend>'.
-                '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '.
+                '<span class="LC_nobreak"><label>'.$lt{'title'}.':<input type="text" size="20" name="ltitools_title_'.$i.'" value="'.$title.'" /></label></span> '.
                 (' 'x2).
-                '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'.
+                '<span class="LC_nobreak"><label for="ltitools_version_'.$i.'">'.$lt{'version'}.'</label>:<select name="ltitools_version_'.$i.'" id="ltitools_version_'.$i.'">'.
                 '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
                 (' 'x2).
-                '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'.
+                '<span class="LC_nobreak"><label for="ltitools_msgtype_'.$i.'">'.$lt{'msgtype'}.'</label>:<select name="ltitools_msgtype_'.$i.'" id="ltitools_msgtype_'.$i.'">'.
                 '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
                 (' 'x2).
-                '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_sigmethod_'.$i.'">'.
+                '<span class="LC_nobreak"><label for="ltitools_sigmethod_'.$i.'">'.$lt{'sigmethod'}.'</label>:<select name="ltitools_sigmethod_'.$i.'" id="ltitools_sigmethod_'.$i.'">'.
                 '<option value="HMAC-SHA1"'.$sigsel{'HMAC-SHA1'}.'>HMAC-SHA1</option>'.
                 '<option value="HMAC-SHA256"'.$sigsel{'HMAC-SHA256'}.'>HMAC-SHA256</option></select></span>'.
                 '<br /><br />'.
                 '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="60" name="ltitools_url_'.$i.'"'.
                 ' value="'.$url.'" /></span>'.
                 (' 'x2).
-                '<span class="LC_nobreak">'.$lt{'lifetime'}.':'.
-                '<input type="text" size="5" name="ltitools_lifetime_'.$i.'" value="'.$lifetime.'" /></span><br /><br />';
+                '<span class="LC_nobreak"><label>'.$lt{'lifetime'}.':'.
+                '<input type="text" size="5" name="ltitools_lifetime_'.$i.'" value="'.$lifetime.'" /></label></span><br /><br />';
             if ($key ne '') {
-                $datatable .= '<span class="LC_nobreak">'.$lt{'key'};
+                $datatable .= '<span class="LC_nobreak">';
                 if ($noedit) {
-                    $datatable .= ': ['.&mt('not shown').']';
+                    $datatable .= $lt{'key'}.': ['.&mt('not shown').']';
                 } elsif ($switchserver) {
-                    $datatable .= ': ['.&mt('[_1] to view/edit',$switchserver).']';
+                    $datatable .= $lt{'key'}.': ['.&mt('[_1] to view/edit',$switchserver).']';
                 } else {
-                    $datatable .= ':<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" autocomplete="off"'.$disabled.' />';
+                    $datatable .= '<label>'.$lt{'key'}.':<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" autocomplete="off"'.$disabled.' /></label>';
                 }
                 $datatable .= '</span> '.(' 'x2);
             } elsif (!$switchserver) {
-                $datatable .= '<span class="LC_nobreak">'.$lt{'key'}.':'.
+                $datatable .= '<span class="LC_nobreak"><label>'.$lt{'key'}.':'.
                               '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" autocomplete="off"'.$disabled.' />'.
-                              '</span> '.(' 'x2);
+                              '</label></span> '.(' 'x2);
             }
             if ($switchserver) {
                 if ($usable ne '') {
@@ -6903,7 +7005,7 @@
     my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_add_pos'".');"';
     $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                   '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n".
-                  '<select name="ltitools_add_pos"'.$chgstr.'>';
+                  '<select name="ltitools_add_pos"'.$chgstr.' aria-label="'.&mt('position in ordered list of external tools (new tool)').'">';
     for (my $k=0; $k<$maxnum+1; $k++) {
         my $vpos = $k+1;
         my $selstr;
@@ -6913,29 +7015,29 @@
         $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
     }
     $datatable .= '</select> '."\n".
-                  '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</span></td>'."\n".
+                  '<label><input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</label></span></td>'."\n".
                   '<td colspan="2">'.
                   '<fieldset><legend>'.&mt('Required settings').'</legend>'.
-                  '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_add_title" value="" /></span> '."\n".
+                  '<span class="LC_nobreak"><label>'.$lt{'title'}.':<input type="text" size="20" name="ltitools_add_title" value="" /></label></span> '."\n".
                   (' 'x2).
-                  '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'.
+                  '<span class="LC_nobreak"><label for="ltitools_add_version">'.$lt{'version'}.'</label>:<select name="ltitools_add_version" id="ltitools_add_version">'.
                   '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
                   (' 'x2).
-                  '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'.
+                  '<span class="LC_nobreak"><label for="ltitools_add_msgtype">'.$lt{'msgtype'}.'</label>:<select name="ltitools_add_msgtype" id="ltitools_add_msgtype">'.
                   '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
-                  '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_add_sigmethod">'.
+                  '<span class="LC_nobreak"><label for="ltitools_add_sigmethod">'.$lt{'sigmethod'}.'</label>:<select name="ltitools_add_sigmethod" id="ltitools_add_sigmethod">'.
                   '<option value="HMAC-SHA1" selected="selected">HMAC-SHA1</option>'.
                   '<option value="HMAC-SHA256">HMAC-SHA256</option></select></span>'.
                   '<br />'.
-                  '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="60" name="ltitools_add_url" value="" /></span> '."\n".
+                  '<span class="LC_nobreak"><label>'.$lt{'url'}.':<input type="text" size="60" name="ltitools_add_url" value="" /></label></span> '."\n".
                   (' 'x2).
-                  '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="5" name="ltitools_add_lifetime" value="300" /></span><br />';
+                  '<span class="LC_nobreak"><label>'.$lt{'lifetime'}.':<input type="text" size="5" name="ltitools_add_lifetime" value="300" /></label></span><br />';
     if ($switchserver) {
         $datatable .= '<span class="LC_nobreak">'.&mt('Key and Secret are required').' - '.$switchmessage.'</span>'."\n";
     } else {
-        $datatable .= '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" autocomplete="off"'.$disabled.' /></span> '."\n".
+        $datatable .= '<span class="LC_nobreak"><label>'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" autocomplete="off"'.$disabled.' /></label></span> '."\n".
                       (' 'x2).
-                      '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_secret_add" value="" autocomplete="new-password"'.$disabled.' />'.
+                      '<span class="LC_nobreak"><label>'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_secret_add" value="" autocomplete="new-password"'.$disabled.' /></label>'.
                       '<label><input type="checkbox" name="ltitools_add_visible" id="ltitools_add_visible" onclick="if (this.checked) { this.form.ltitools_secret_add.type='."'text'".' } else { this.form.ltitools_secret_add.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label></span> '."\n";
     }
     $datatable .= '<br /><br />'.
@@ -6955,11 +7057,11 @@
                       (' 'x2);
     }
     $datatable .= '</span><br />'.
-                  '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.
-                  '<input type="text" name="ltitools_add_linktext" size="5" /></div>'.
-                  '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.
+                  '<div class="LC_left_float"><label>'.$lt{'linktext'}.'<br />'.
+                  '<input type="text" name="ltitools_add_linktext" size="5" /></label></div>'.
+                  '<div class="LC_left_float"><label>'.$lt{'explanation'}.'<br />'.
                   '<textarea name="ltitools_add_explanation" rows="5" cols="40"></textarea>'.
-                  '</div><div style=""></div><br />';
+                  '</label></div><div style=""></div><br />';
     my %units = (
                   'passback' => 'days',
                   'roster'   => 'seconds',
@@ -6984,9 +7086,9 @@
                           &mt('Yes').'</label>';
         } else {
             $datatable .= '<div class="LC_floatleft" style="display:none;" id="ltitools_'.$extra.'time_add">'.
-                          '<span class="LC_nobreak">'.
+                          '<span class="LC_nobreak"><label>'.
                           &mt("until at least [_1] $units{$extra} after launch",
-                              '<input type="text" name="ltitools_'.$extra.'valid_add" value="'.$defaulttimes{$extra}.'" />');
+                              '<input type="text" name="ltitools_'.$extra.'valid_add" value="'.$defaulttimes{$extra}.'" /></label>');
         }
         $datatable .= '</span></div><div style="padding:0;clear:both;margin:0;border:0"></div>';
         if ($extra eq 'desturl') {
@@ -6999,12 +7101,12 @@
                           '(s)</label></span></div><br />';
         }
     }
-    $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': '.
+    $datatable .= '<span class="LC_nobreak"><label for="ltitools_add_image">'.$lt{'icon'}.'</label>: '.
                   '('.&mt('if larger than 21x21 pixels, image will be scaled').') ';
     if ($switchserver) {
         $datatable .= &mt('Upload to library server: [_1]',$switchserver);
     } else {
-        $datatable .= '<input type="file" name="ltitools_add_image" value="" />';
+        $datatable .= '<input type="file" name="ltitools_add_image" id="ltitools_add_image" value="" />';
     }
     $datatable .= '</span></fieldset>'.
                   '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
@@ -7024,24 +7126,27 @@
     $datatable .= '</span>'.
                   '<div style="display:none;" id="ltitools_user_div_add">'.
                   '<span class="LC_nobreak"> : '.
-                  '<select name="ltitools_add_userincdom">'.
+                  '<select name="ltitools_add_userincdom" aria-label="'.&mt('username data sent on launch').'">'.
                   '<option value="" selected="selected">'.&mt('Select').'</option>'.
                   '<option value="0">'.&mt('username').'</option>'.
                   '<option value="1">'.&mt('username:domain').'</option>'.
                   '</select></span></div></fieldset>';
-    $datatable .= '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
+    $datatable .= '<fieldset><legend>'.&mt('Role mapping').'</legend>'.
+                  '<div role="grid" class="LC_grid">'.
+                  '<div role="row" class="LC_grid_row">';
     foreach my $role (@courseroles) {
         my ($checked,$checkednone);
-        $datatable .= '<td style="text-align: center">'.
-                      &Apache::lonnet::plaintext($role,'Course').'<br />'.
-                      '<select name="ltitools_add_roles_'.$role.'">'.
+        $datatable .= '<div role="gridcell" class="LC_grid_cell" style="text-align: center">'.
+                      '<label for="ltitools_add_roles_'.$role.'">'.
+		      &Apache::lonnet::plaintext($role,'Course').'</label><br />'.
+                      '<select name="ltitools_add_roles_'.$role.'" id="ltitools_add_roles_'.$role.'">'.
                       '<option value="" selected="selected">'.&mt('Select').'</option>';
         foreach my $ltirole (@ltiroles) {
             $datatable .= '<option value="'.$ltirole.'">'.$ltirole.'</option>';
         }
-        $datatable .= '</select></td>';
+        $datatable .= '</select></div>';
     }
-    $datatable .= '</tr></table></fieldset>'.
+    $datatable .= '</div></div></fieldset>'.
                   '<fieldset><legend>';
     if ($context eq 'domain') {
         $datatable .= &mt('Configurable in course');
@@ -7059,8 +7164,8 @@
                   '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'.
                   '<tr><td><span class="LC_nobreak">'.
                   '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'.
-                  &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'.
-                  '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'.
+                  &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" aria-label="'.&mt('Custom launch item name').'" />'.
+                  '</td><td><input type="text" name="ltitools_add_custom_value" aria-label="'.&mt('Custom launch item value').'" /></td></tr>'.
                   '</table></fieldset>'."\n".
                   '</td>'."\n".
                   '</tr>'."\n";
@@ -7157,27 +7262,33 @@
     }
     my %items = (
         'lti.override' => {
-            text => '<b>'.&mt($itemtext->{'lti.override'}).'</b>'.$domdefs,
+            text => &mt($itemtext->{'lti.override'}),
+	    subtext => $domdefs,
             input => 'radio',
+            legend => &mt($itemtext->{'lti.override'}),
                    },
         'lti.topmenu' => {
-            text => '<b>'.&mt($itemtext->{'lti.topmenu'}).'</b>',
+            text => &mt($itemtext->{'lti.topmenu'}),
             input => 'radio',
+            legend => &mt($itemtext->{'lti.topmenu'}),
                    },
         'lti.inlinemenu' => {
-            text => '<b>'.&mt($itemtext->{'lti.inlinemenu'}).'</b>',
+            text => &mt($itemtext->{'lti.inlinemenu'}),
             input => 'radio',
+            legend => &mt($itemtext->{'lti.inlinemenu'}),
                       },
         'lti.lcmenu' => {
-            text => '<b>'.&mt($itemtext->{'lti.lcmenu'}).'</b><br />'.$displaydefs,
+            text => &mt($itemtext->{'lti.lcmenu'}),
+	    subtext => $displaydefs,
             input => 'custom',
+            legend => &mt($itemtext->{'lti.lcmenu'}),
                   },
                 );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'lti',$noedit);
 }
 
 sub lcmenu_checkboxes {
-    my ($cdom,$caller,$settings,$crstype,$noedit) = @_;
+    my ($cdom,$caller,$settings,$crstype,$noedit,$legend) = @_;
     my @menuitems = ('fullname','coursetitle','role','logout','grades');
     my %menutitles = &ltimenu_titles();
     my (@current, at domdefs);
@@ -7206,7 +7317,8 @@
     if ($noedit) {
         $disabled = ' disabled="disabled"';
     }
-    my $output = '<table>';
+    my $output = '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+                 $legend.'</legend><div role="grid" class="LC_grid" style="margin:0; padding: 1px;">';
     foreach my $item (@menuitems) {
         my $checked = '';
         if (grep(/^\Q$item\E$/, at current)) {
@@ -7215,24 +7327,17 @@
         my $rem = $count%($numinrow);
         if ($rem == 0) {
             if ($count > 0) {
-                $output .= '</tr>';
+                $output .= '</div>';
             }
-            $output .= '<tr>';
+            $output .= '<div role="row" class="LC_grid_row">';
         }
-        $output .= '<td align="left"><span class="LC_nobreak"><label><input type="checkbox" '.
+        $output .= '<div role="gridcell" class="LC_grid_cell">'.
+                   '<span class="LC_nobreak"><label><input type="checkbox" '.
                    'name="lti.lcmenu" value="'.$item.'"'.$checked.$disabled.'/> '.
-                   $menutitles{$item}.'</label></span></td>';
+                   $menutitles{$item}.'</label></span></div>';
         $count ++;
     }
-    my $rem = $count%($numinrow);
-    my $colsleft = $numinrow - $rem;
-    if ($colsleft > 1 ) {
-        $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
-                   ' </td>';
-    } elsif ($colsleft == 1) {
-        $output .= '<td class="LC_left_item"> </td>';
-    }
-    $output .= '</tr></table>';
+    $output .= '</div></div></fieldset>';
 }
 
 sub ltimenu_titles {
@@ -7267,12 +7372,13 @@
         $defaultmenu_options{$addcollection} = $addcollection;
         my %items = (
             'menudefault' => {
-                   text => '<b>'.&mt($itemtext->{'menudefault'}).'</b><br />'.
-                           &mt("(can be overriden in deep-link context)"),
+                   text => &mt($itemtext->{'menudefault'}),
+                   subtext => &mt('(can be overriden in deep-link context)'),
                    input => 'selectbox',
                    options => \%defaultmenu_options,
                    order  => \@defaultmenu_order,
                    nullval => &mt('Standard (all menus shown)'),
+                   id => 'menudefault',
                             },
         );
         return &make_item_rows($cdom,\%items,['menudefault'],$settings,$rowtotal,$crstype,'menuitems',$noedit);
@@ -7322,7 +7428,7 @@
                         }
                     }
                     if (ref($menu{$num}) eq 'HASH') {
-                        $datatable .= &item_table_row_start('<em class="LC_nav_bar">'.$num.'</em>',$count,'','','','LC_left_item');
+                        $datatable .= &item_table_row_start('<em class="LC_nav_bar">'.$num.'</em>','','','',$count,'','','','LC_left_item');
                         foreach my $category (@order) {
                             if ((ref($categories{$category}) eq 'ARRAY') && (@{$categories{$category}} > 0)) {
                                 $datatable .= '<fieldset style="vertical-align:top; display:inline-block"><legend>'.$menutitles{$category}.'</legend>'."\n";
@@ -7346,12 +7452,12 @@
             }
         } elsif ($noedit) {
             my $text = &mt('No menu collections defined for this course.');
-            $datatable .= &item_table_row_start($text,$count);
+            $datatable .= &item_table_row_start($text,'','','',$count);
         }
         unless ($noedit) {
             my $add = '<label><input type="checkbox" name="menucollections_add" id="menucollections_add" value="'.$next.'" '.
                       'onclick="javascript:toggleAddmenucoll();" />'.&mt('Add').'</label>';
-            $datatable .= &item_table_row_start($add,$count,'','','','LC_left_item');
+            $datatable .= &item_table_row_start($add,'','','',$count,'','','','LC_left_item');
             foreach my $category (@order) {
                 if ((ref($categories{$category}) eq 'ARRAY') && (@{$categories{$category}} > 0)) {
                     $datatable .= '<fieldset id="addmenucoll_'.$category.'" style="display:none; vertical-align:top;"><legend>'.$menutitles{$category}.'</legend>'."\n";
@@ -7618,28 +7724,28 @@
                     $checkedreturnurl{'no'} = '';
                 }
                 $datatable .=
-                    '<span class="LC_nobreak">'.$desc{'name'}.
-                    ':<input type="text" size="15" name="linkprot_name_'.$i.'" value="'.$values{'name'}.'" autocomplete="off"'.$disabled.' /></span> '.
+                    '<span class="LC_nobreak"><label>'.$desc{'name'}.
+                    ':<input type="text" size="15" name="linkprot_name_'.$i.'" value="'.$values{'name'}.'" autocomplete="off"'.$disabled.' /></label></span> '.
                     (' 'x2).
-                    '<span class="LC_nobreak">'.$desc{'version'}.':<select name="linkprot_version_'.$i.'"'.$disabled.'>'.
+                    '<span class="LC_nobreak"><label for="linkprot_version_'.$i.'">'.$desc{'version'}.'</label>:<select name="linkprot_version_'.$i.'" id="linkprot_version_'.$i.'"'.$disabled.'>'.
                     '<option value="LTI-1p0" '.$selected.'>1.1</option></select></span> '."\n".
                     (' 'x2).
-                    '<span class="LC_nobreak">'.$desc{'lifetime'}.':<input type="text" name="linkprot_lifetime_'.$i.'"'.
-                    ' value="'.$values{'lifetime'}.'" size="3"'.$disabled.' /></span><br /><br />';
+                    '<span class="LC_nobreak"><label>'.$desc{'lifetime'}.':<input type="text" name="linkprot_lifetime_'.$i.'"'.
+                    ' value="'.$values{'lifetime'}.'" size="3"'.$disabled.' /></label></span><br /><br />';
                 if ($values{'key'} ne '') {
-                    $datatable .= '<span class="LC_nobreak">'.$desc{'key'};
+                    $datatable .= '<span class="LC_nobreak">';
                     if ($noedit) {
-                        $datatable .= ': ['.&mt('not shown').']';
+                        $datatable .= $desc{'key'}.': ['.&mt('not shown').']';
                     } elsif ($switchserver) {
-                        $datatable .= ': ['.&mt('[_1] to view/edit',$switchserver).']';
+                        $datatable .= $desc{'key'}.': ['.&mt('[_1] to view/edit',$switchserver).']';
                     } else {
-                        $datatable .= ':<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'" autocomplete="off"'.$disabled.' />';
+                        $datatable .= '<label>'.$desc{'key'}.':<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'" autocomplete="off"'.$disabled.' /></label>';
                     }
                     $datatable .= '</span> '.(' 'x2);
                 } elsif (!$switchserver) {
-                    $datatable .= '<span class="LC_nobreak">'.$desc{'key'}.':'.
+                    $datatable .= '<span class="LC_nobreak"><label>'.$desc{'key'}.':'.
                                   '<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'" autocomplete="off"'.$disabled.' />'.
-                                  '</span> '.(' 'x2);
+                                  '</label></span> '.(' 'x2);
                 }
                 if ($switchserver) {
                     if ($values{'usable'} ne '') {
@@ -7667,14 +7773,14 @@
                                       (' 'x2).
                                       '<label><input type="radio" value="1" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleChgSecret(this.form,'."'$i','secret','linkprot'".');"'.$disabled.' />'.&mt('Yes').
                                       '</label>  </span><div id="linkprot_divchgsecret_'.$i.'" style="display:none" />'.
-                                      '<span class="LC_nobreak">'.&mt('New Secret').':'.
-                                      '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="new-password"'.$disabled.' />'.
+                                      '<span class="LC_nobreak"><label>'.&mt('New Secret').':'.
+                                      '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="new-password"'.$disabled.' /></label>'.
                                       '<label><input type="checkbox" name="linkprot_visible_'.$i.'" id="linkprot_visible_'.$i.'" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label>'.
                                       '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span></div>';
                     } else {
                         $datatable .=
-                            '<span class="LC_nobreak">'.$desc{'secret'}.':'.
-                            '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="new-password"'.$disabled.' />'.
+                            '<span class="LC_nobreak"><label>'.$desc{'secret'}.':'.
+                            '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="new-password"'.$disabled.' /></label>'.
                             '<label><input type="checkbox" name="linkprot_visible_'.$i.'" id="linkprot_visible_'.$i.'" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label>'.
                             '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span>';
                     }
@@ -7699,8 +7805,8 @@
                               '<label><input type="radio" name="linkprot_returnurl_'.$i.'" value="1"'.
                               $onclickreturnurl.$checkedreturnurl{'yes'}.$disabled.' />'.&mt('Yes').'</label></span>'.
                               '  <div id="linkprot_divurlparam_'.$i.'" style="display:none">'.
-                              '<span class="LC_nobreak">'.&mt('Parameter name').':'.
-                              '<input type="text" size="15" name="linkprot_urlparam_'.$i.'" value="'.$values{'returnurl'}.'" autocomplete="off"'.$disabled.' />'.
+                              '<span class="LC_nobreak"><label>'.&mt('Parameter name').':'.
+                              '<input type="text" size="15" name="linkprot_urlparam_'.$i.'" value="'.$values{'returnurl'}.'" autocomplete="off"'.$disabled.' /></label>'.
                               '</span></div> ';
                 if ($ltiauth) {
                     $datatable .= (' 'x2).'<span class="LC_nobreak">'.$desc{'requser'}.'?'.
@@ -7721,7 +7827,7 @@
     $css_class = $itemcount%2?' class="LC_odd_row"':'';
     $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                   '<input type="hidden" name="linkprot_maxnum" value="'.$next.'" />'."\n".
-                  '<input type="checkbox" name="linkprot_add" value="1"'.$disabled.' />'.&mt('Add').'</span></td>'."\n".
+                  '<label><input type="checkbox" name="linkprot_add" value="1"'.$disabled.' />'.&mt('Add').'</label></span></td>'."\n".
                   '<td width="100%">';
     my ($usersty,$onclickrequser,%checkedrequser,$onclickreturnurl,%checkedreturnurl,
        $onclickpassback,%checkedpassback,%checkedpassbackfmt);
@@ -7748,20 +7854,20 @@
         no => ' checked="checked"',
         yes => '',
     );
-    $datatable .= '<span class="LC_nobreak">'.$desc{'name'}.
-                  ':<input type="text" size="15" name="linkprot_name_add" value="" autocomplete="off"'.$disabled.' /></span> '."\n".
+    $datatable .= '<span class="LC_nobreak"><label>'.$desc{'name'}.
+                  ':<input type="text" size="15" name="linkprot_name_add" value="" autocomplete="off"'.$disabled.' /></label></span> '."\n".
                   (' 'x2).
-                  '<span class="LC_nobreak">'.$desc{'version'}.':<select name="linkprot_version_add"'.$disabled.'>'.
+                  '<span class="LC_nobreak"><label for="linkprot_version_add">'.$desc{'version'}.'</label>:<select name="linkprot_version_add" id="linkprot_version_add"'.$disabled.'>'.
                   '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
                   (' 'x2).
-                  '<span class="LC_nobreak">'.$desc{'lifetime'}.':<input type="text" size="3" name="linkprot_lifetime_add" value="300"'.$disabled.' /></span> '."\n".
+                  '<span class="LC_nobreak"><label>'.$desc{'lifetime'}.':<input type="text" size="3" name="linkprot_lifetime_add" value="300"'.$disabled.' /></label></span> '."\n".
                   '<br /><br />';
     if ($switchserver) {
         $datatable .= '<span class="LC_nobreak">'.&mt('Key and Secret are required').' - '.$switchmessage.'</span>'."\n";
     } else {
-        $datatable .= '<span class="LC_nobreak">'.$desc{'key'}.':<input type="text" size="25" name="linkprot_key_add" value="" autocomplete="off"'.$disabled.' /></span> '."\n".
+        $datatable .= '<span class="LC_nobreak"><label>'.$desc{'key'}.':<input type="text" size="25" name="linkprot_key_add" value="" autocomplete="off"'.$disabled.' /></label></span> '."\n".
                       (' 'x2).
-                      '<span class="LC_nobreak">'.$desc{'secret'}.':<input type="password" size="20" name="linkprot_secret_add" value="" autocomplete="new-password"'.$disabled.' />'.
+                      '<span class="LC_nobreak"><label>'.$desc{'secret'}.':<input type="password" size="20" name="linkprot_secret_add" value="" autocomplete="new-password"'.$disabled.' /></label>'.
                       '<label><input type="checkbox" name="linkprot_visible_add" id="linkprot_visible_add" onclick="if (this.checked) { this.form.linkprot_secret_add.type='."'text'".' } else { this.form.linkprot_secret_add.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label></span> '."\n";
     }
     $datatable .= '<br /><br />'.
@@ -7784,9 +7890,9 @@
                   '<label><input type="radio" name="linkprot_returnurl_add" value="1"'.
                   $onclickreturnurl.$checkedreturnurl{'yes'}.$disabled.' />'.&mt('Yes').'</label></span>'.
                   '  <div id="linkprot_divurlparam_add" style="display:none">'.
-                  '<span class="LC_nobreak">'.&mt('Parameter name').':'.
+                  '<span class="LC_nobreak"><label>'.&mt('Parameter name').':'.
                   '<input type="text" size="15" name="linkprot_urlparam_add" value="" autocomplete="off"'.$disabled.' />'.
-                  '</span></div> ';
+                  '</label></span></div> ';
     if ($ltiauth) {
         $datatable .= (' 'x2).'<span class="LC_nobreak">'.$desc{'requser'}.'?'.
                       '<label><input type="radio" name="linkprot_requser_add" value="0"'.
@@ -7818,6 +7924,7 @@
                                           'other'     => 'Other',
                                           'auth'      => 'Display LON-CAPA login page',
                                           'reject'    => 'Discontinue launch process',
+                                          'oth'       => 'Other username source',
                                         );
 }
 
@@ -7878,7 +7985,7 @@
     $output .= '</span></div>'.
                '<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="linkprot_userfield_'.$num.'">'.
                '<input type="text" name="linkprot_customuser_'.$num.'" '.
-               'value="'.$userfield.'"'.$disabled.' /></div>';
+               'value="'.$userfield.'"'.$disabled.' aria-label="'.$lt{'oth'}.'" /></div>';
     $output .= '<br />'.
                '<div class="LC_floatleft"><span class="LC_nobreak">'.
                &mt('Action when username is not for an enrolled student').': ';
@@ -7917,15 +8024,15 @@
     }
     $output .= '<div id="LC_extresreusediv" style="display:'.$reusesty.';">'.
                '<span class="LC_nobreak">'.
-               '<label><input type="checkbox" name="extwintabreuse" value="1"'.$checked.'>'.
+               '<label><input type="checkbox" name="extwintabreuse" value="1"'.$checked.' />'.
                &mt('Re-use tab/window').'</label>'.
                '</span></div>'.
                '<fieldset id="LC_extressize" style="display:'.$sizesty.';">'.
                '<legend>'.&mt('Window size (optional)').'</legend>'.
-               '<span class="LC_nobreak">'.
-               &mt('width').':<input type="text" name="extreswinwidth" value="'.$width.'" size="3" />px'.
-               (' ' x 3).
-               &mt('height').':<input type="text" name="extreswinheight" value="'.$height.'" size="3" />px'.
+               '<span class="LC_nobreak"><label>'.
+               &mt('width').':<input type="text" name="extreswinwidth" value="'.$width.'" size="3" /></label>px'.
+               (' ' x 3).'<label>'.
+               &mt('height').':<input type="text" name="extreswinheight" value="'.$height.'" size="3" /></label>px'.
                '</span></fieldset>';
     return $output;
 }
@@ -7938,19 +8045,23 @@
     my @ordered = &get_other_items($cdom,$settings,$allitems);
     my %items;
     foreach my $parameter (@ordered) {
+        my $id = $parameter;
+        $id =~ s{\s+}{_}g;
         $items{$parameter} = {
-                               text  => '<b>'.$parameter.'</b>',
+                               text  => $parameter,
                                input => 'textbox',
                                size  => '15',
+                               id    => $id,
                              },
     }
     push (@ordered,'newp_value');
     $items{'newp_value'} = {
-                            text  => '<b>'.&mt('Create New Environment Variable').'</b><br />'.
-                                     '<input type="textbox" name="newp_name"'.
-                                     ' value="" size="30" />',
+                            text  => &mt('Create New Environment Variable'),
+                            subtext => &mt('Name').':<input type="text" name="newp_name"'.
+                                       ' value="" size="30" id="newp_name"/>',
                             input => 'textbox',
                             size  => '30',
+                            id    => 'newp_name',
                            };
     return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'other',$noedit);
 }
@@ -7981,7 +8092,7 @@
 }
 
 sub item_table_row_start {
-    my ($text,$count,$add_class,$colspan,$leftclass,$rightclass) = @_;
+    my ($text,$link,$subtext,$label,$count,$add_class,$colspan,$leftclass,$rightclass) = @_;
     my $output;
     my $css_class = ($count % 2) ? 'LC_odd_row' : 'LC_even_row';
     $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
@@ -7992,8 +8103,23 @@
         $rightclass = 'LC_right_item';
     }
     $output .= '<tr class="'.$css_class.'">'."\n".
-               '<td class="'.$leftclass.'">'.$text.
-               '</td>';
+               '<th scope="row" class="'.$leftclass.'">';
+    if ($label) {
+        $output .= '<label for="'.$label.'">'.$text.'</label>';
+    } else {
+        $output .= $text;
+    }
+    if ($subtext || $link) {
+        $output .= '<span class="LC_subtext">';
+        if ($link) {
+            $output .= ' '.$link;
+        }
+        if ($subtext) {
+            $output .= '<br />'.$subtext;
+        }
+        $output .= '</span>';
+    }
+    $output .= '</th>';
     if ($colspan > 1) {
         $output .= '<td class="'.$rightclass.'" colspan="'.$colspan.'">';
     } else {
@@ -8007,7 +8133,7 @@
 }
 
 sub yesno_radio {
-    my ($item,$settings,$unsetdefault,$valueyes,$valueno,$noedit,$onclick,$reverse) = @_;
+    my ($item,$legend,$settings,$unsetdefault,$valueyes,$valueno,$noedit,$onclick,$reverse) = @_;
     my $itemon = ' ';
     my $itemoff = ' checked="checked" ';
     if (($valueyes eq '') && ($valueno eq '')) {
@@ -8032,18 +8158,28 @@
     } elsif ($onclick) {
         $onclick = ' onclick="'.$onclick.'"';
     }
+    my ($start_fieldset,$end_fieldset);
+    if ($legend) {
+        $start_fieldset = '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'.
+                          $legend.'</legend>'."\n";
+        $end_fieldset = '</fieldset>'."\n";
+    }
     if ($reverse) {
-        return '<span class="LC_nobreak"><label>'.
+        return $start_fieldset.
+               '<span class="LC_nobreak"><label>'.
                '<input type="radio" name="'.$item.'"'.
                $itemoff.' value="'.$valueno.'"'.$disabled.$onclick.' />'.&mt('No').'</label> '.
                '<label><input type="radio" name="'.$item.'"'.
-               $itemon.' value="'.$valueyes.'"'.$disabled.$onclick.' />'.&mt('Yes').'</label></span>';
+               $itemon.' value="'.$valueyes.'"'.$disabled.$onclick.' />'.&mt('Yes').'</label></span>'.
+               $end_fieldset;
     } else {
-        return '<span class="LC_nobreak"><label>'.
+        return $start_fieldset.
+               '<span class="LC_nobreak"><label>'.
                '<input type="radio" name="'.$item.'"'.
                $itemon.' value="'.$valueyes.'"'.$disabled.$onclick.' />'.&mt('Yes').'</label> '.
                '<label><input type="radio" name="'.$item.'"'.
-               $itemoff.' value="'.$valueno.'"'.$disabled.$onclick.' />'.&mt('No').'</label></span>';
+               $itemoff.' value="'.$valueno.'"'.$disabled.$onclick.' />'.&mt('No').'</label></span>'.
+               $end_fieldset;
     }
 }
 
@@ -8111,18 +8247,28 @@
                 (($caller eq 'printouts') && ($item ne 'print_header_format'))) {
                 $colspan = 2;
             }
-            my $rowdesc;
+            my ($rowdesc,$rightclass);
             if ($caller eq 'appearance') {
-                $rowdesc = '<span class="LC_nobreak">'.$items->{$item}{text}.'</span>';
+                if ($items->{$item}{id} ne '') {
+                    $rowdesc = '<span class="LC_nobreak">'.
+                               '<label for="'.$items->{$item}{id}.'">'.
+                               $items->{$item}{text}.'</label></span>'; 
+                } else {
+                    $rowdesc = '<span class="LC_nobreak">'.$items->{$item}{text}.'</span>';
+                }
             } elsif ($items->{$item}{id} ne '') {
+                my $id = $items->{$item}{id};
                 $rowdesc = '<label for="'.$items->{$item}{id}.'">'.$items->{$item}{text}.'</label>';
             } else {
                 $rowdesc = $items->{$item}{text};
             }
+            if ($item eq 'lti.lcmenu') {
+                $rightclass = 'LC_left_item';
+            }
             if (exists $items->{$item}{advanced} && $items->{$item}{advanced} == 1) {
-                $datatable .= &item_table_row_start($rowdesc,$count,"advanced",$colspan);
+                $datatable .= &item_table_row_start($rowdesc,$items->{$item}{link},$items->{$item}{subtext},$items->{$item}{label},$count,"advanced",$colspan,'',$rightclass);
             } else {
-                $datatable .= &item_table_row_start($rowdesc,$count,undef,$colspan);
+                $datatable .= &item_table_row_start($rowdesc,$items->{$item}{link},$items->{$item}{subtext},$items->{$item}{label},$count,undef,$colspan,'',$rightclass);
             }
             if ($item eq 'defaultcredits') {
                 my $defaultcredits = $env{'course.'.$env{'request.course.id'}.'.internal.defaultcredits'};
@@ -8140,7 +8286,7 @@
             } elsif ($item eq 'print_header_format') {
                 $datatable .= &print_hdrfmt_row($item,$settings,$noedit);
             } elsif ($item eq 'lti.lcmenu') {
-                $datatable .= &lcmenu_checkboxes($cdom,$item,$settings,$crstype,$noedit);
+                $datatable .= &lcmenu_checkboxes($cdom,$item,$settings,$crstype,$noedit,$items->{$item}{legend});
             } elsif ($item eq 'extresource') {
                 $datatable .= &print_extresource_row($item,$items->{$item},$settings->{$item},$noedit);
             } elsif ($items->{$item}{input} eq 'dates') {
@@ -8163,10 +8309,8 @@
                 } elsif (($item eq 'lti.topmenu') || ($item eq 'lti.inlinemenu')) {
                     $valueyes = '1';
                 }
-                $datatable .= '<fieldset class="LC_borderless"><legend class="LC_visually_hidden">'
-                             .$items->{$item}{text}.'</legend>'
-                             .&yesno_radio($item,$settings,$unsetdefault,$valueyes,$valueno,$noedit)
-                             .'</fieldset>';
+                $datatable .= &yesno_radio($item,$items->{$item}{legend},$settings,
+                                           $unsetdefault,$valueyes,$valueno,$noedit);
             } elsif ($items->{$item}{input} eq 'selectbox') {
                 my ($id,$onchange);
                 if ($caller eq 'menuitems') {
@@ -8214,9 +8358,11 @@
                     my $sectionbox = '<div id="sectotalsdiv" style="display:'.$gradingsecsty.'; float:right">';
                     my $reverse = 1;
                     if (@sections) {
-                        $sectionbox .= ' ... '.&mt('hidden in sections').': '.
+                        $sectionbox .= ' ... '.'<label for="hidetotals_sections">'.
+                                       &mt('hidden in sections').'</label>: '.
                                        '<div style="position: relative; top: 0%;">'.
-                                       &select_sections('hidetotals','',\@sections,\@selsec,$noedit,'all').
+                                       &select_sections('hidetotals','',\@sections,
+                                                        \@selsec,$noedit,'all','hidetotals_sections').
                                        '</div>';
                     }
                     $sectionbox .= '</div>';
@@ -8224,20 +8370,26 @@
                                   '<legend style="font-weight: normal;">'.
                                   &mt('Hide Course Points Totals').'</legend>'.
                                   '<div style="position: relative; top: 0%; float:left">'.
-                                  &yesno_radio('hidetotals',\%current,$unsetdefault,$valueyes,$valueno,$noedit,
+                                  &yesno_radio('hidetotals','',\%current,$unsetdefault,$valueyes,$valueno,$noedit,
                                                $onclick,$reverse).'</div>'.
                                   $sectionbox.
                                   '</fieldset><div style="padding:0;clear:both;margin:0;border:0"></div>';
                 }
             } elsif ($items->{$item}{input} eq 'textbox') {
-                my $disabled;
+                my ($disabled,$id);
                 if ($noedit) {
-                    $disabled = ' disabled=disabled"';
+                    $disabled = ' disabled="disabled"';
+                }
+                if (($caller eq 'other') && ($item eq 'newp_value')) {
+                    $id = ' id="'.$item.'"';
+                    $datatable .= '<label for="newp_value">'.&mt('Value').'</label>:';
+                } else {
+                    $id = ' id="'.$items->{$item}{'id'}.'"';
                 }
                 $datatable .= 
                     &Apache::lonhtmlcommon::textbox($item,$settings->{$item},
                                                     $items->{$item}{size},
-                                                    $disabled);
+                                                    $disabled.$id);
             }
             $datatable .= &item_table_row_end();
         }
@@ -8473,7 +8625,7 @@
 
 ENDJS
     $output .= '</td><td align="right"><br />'.
-               $currstr.'<table class="LC_data_table">';
+               $currstr.'<div role="grid" class="LC_grid">';
     my $disabled;
     if ($noedit) {
         $disabled = ' disabled="disabled"';
@@ -8481,59 +8633,66 @@
     if (@curr > 0) {
         for (my $i=0; $i<@curr; $i++) {
             my $pos = $i+1;
-            $output .= '<tr>'.
-                       '<td align="left"><span class="LC_nobreak">'.
+            $output .= '<div role="row" class="LC_grid_row">'.
+                       '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">'. 
+		       '<span class="LC_nobreak">'.
                        &position_selector($pos,$i,$maxnum,$disabled).&mt('Delete:').
                        '<input type="checkbox" name="printfmthdr_del_'.$i.
-                       '"'.$disabled.' /></span></td>';
+                       '"'.$disabled.' /></span></div>';
             if ($curr[$i] =~ /^%\d*[nca]$/) {
                 my ($limit,$subst) = ($curr[$i] =~ /^%(\d*)([nca])$/);
-                $output .= '<td align="left">'.
-                           &substitution_selector($i,$subst,$limit,$disabled).'</td>';
+                $output .= '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">'.
+                           &substitution_selector($i,$subst,$limit,$disabled).'</div>';
             } else {
-                $output .= '<td colspan="2" align="left">'.&mt('Text').'<br />'.
-                           '<input type="textbox" name="printfmthdr_text_'.$i.'"'.
-                           ' value="'.$curr[$i].'" size="25"'.$disabled.' /></td>';
+                $output .= '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">'.
+                           '<label>'.&mt('Text').'<br />'.
+                           '<input type="text" name="printfmthdr_text_'.$i.'"'.
+                           ' value="'.$curr[$i].'" size="25"'.$disabled.' /></label></div>';
             }
-            $output .= '</tr>';
+            $output .= '</div>';
         }
     }
     my $pos = $currnum+1;
     unless ($noedit) {
         $output .= 
-               '<tr>'.
-               '<td align="left"><span class="LC_nobreak">'.
+               '<div role="row" class="LC_grid_row">'.
+               '<div role="gridcell" class="LC_grid_cell" style="vertical-align: middle; text-align: left;">'.
+	       '<span class="LC_nobreak">'.
                &position_selector($pos,$currnum,$maxnum).
-               '<b>'.&mt('New').'</b></span></td><td align="left">'.
-               &substitution_selector($currnum).'</td>'.
-               '</tr>'; 
+               '<b>'.&mt('New').'</b></span></div>'.
+	       '<div role="gridcell" class="LC_grid_cell" style="text-align: left">'.
+               &substitution_selector($currnum).'</div>'.
+               '</div>';
         $pos ++;
         $currnum ++;
         $output .= 
-               '<tr>'.
-               '<td align="left"><span class="LC_nobreak">'.
+               '<div role="row" class="LC_grid_row">'.
+               '<div role="gridcell" class="LC_grid_cell" style="vertical-align: middle; text-align: left;">'.
+	       '<span class="LC_nobreak">'.
                &position_selector($pos,$currnum,$maxnum).
-               '<b>'.&mt('New').'</b></span></td>'.
-               '<td colspan="2" align="left">'.&mt('Text').'<br />'.
-               '<input type="textbox" name="printfmthdr_text_'.$currnum.
+               '<b>'.&mt('New').'</b></span></div>'.
+               '<div role="gridcell" class="LC_grid_cell" style="text-align: left;">'.
+               '<label>'.&mt('Text').'<br />'.
+               '<input type="text" name="printfmthdr_text_'.$currnum.
                '" value="" size ="25" />'.
                '<input type="hidden" name="printfmthdr_maxnum" value="'.
-                $maxnum.'" /></td>'.
-               '</tr>';
+                $maxnum.'" /></label></div>'.
+               '</div>';
     }
-    $output .= '</table><br />';
+    $output .= '</div><br />';
     return $output;
 }
 
 sub position_selector {
     my ($pos,$num,$maxnum,$disabled) = @_;
-    my $output = '<select name="printfmthdr_pos_'.$num.'" onchange="reOrder('."'$num'".');"'.$disabled.'>';
+    my $output = '<select name="printfmthdr_pos_'.$num.'" onchange="reOrder('."'$num'".');"'.$disabled.
+                 ' aria-label="'.&mt('Order of print header item [_1].',$num).'">';
     for (my $j=1; $j<=$maxnum; $j++) {
         my $sel = '';
         if ($pos == $j) {
             $sel = ' selected="selected"';
         }
-        $output .= '<option value="'.$j.'"'.$sel.'">'.$j.'</option>';
+        $output .= '<option value="'.$j.'"'.$sel.'>'.$j.'</option>';
     }
     $output .= '</select><input type="hidden" name="printfmthdr_oldpos_'.$num.
                '" value="'.$pos.'" />';
@@ -8555,7 +8714,7 @@
                     c => $crsidtxt,
                     a => 'assignment note',
              );
-    my $output .= &mt('Substitution').'<br />'.
+    my $output .= '<label>'.&mt('Substitution').'<br />'.
                   '<select name="printfmthdr_sub_'.$num.'"'.$disabled.'>';
     if ($subst eq '') {
         $output .= '<option value="" selected="selected"> </option>';
@@ -8568,9 +8727,11 @@
         $output .= '<option value="'.$field.'"'.$sel.'>'.
                    $lt{$field}.'</option>';
     }
-    $output .= '</select></td><td align="left">'.&mt('Size limit').'<br />'.
-               '<input type="textbox" name="printfmthdr_limit_'.$num.
-               '" value="'.$limit.'" size="5"'.$disabled.' /></span>';
+    $output .= '</select></label></div>'.
+               '<div role="gridcell" class="LC_grid_cell" style="text-align: left">'.
+               '<label>'.&mt('Size limit').'<br />'.
+               '<input type="text" name="printfmthdr_limit_'.$num.
+               '" value="'.$limit.'" size="5"'.$disabled.' /></label>';
     return $output;
 }
 


More information about the LON-CAPA-cvs mailing list