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

raeburn raeburn at source.lon-capa.org
Tue May 5 07:18:49 EDT 2026


raeburn		Tue May  5 11:18:49 2026 EDT

  Modified files:              
    /loncom/interface	lonmanagekeys.pm 
  Log:
  - WCAG 2.2 compliance
    - Include landmark for page's main content to support "Skip to main content". 
    - Include labels for form elements.
    - Satisfy minimum spacing between touch targets.
    - Group form elements in fieldset with legend for screenreaders.
    - Use <th> tags for column headings and row headings in data table
      with scope="row" attribute for latter.
    - For form elements in data table cells use aria-labelledby to reference 
      appropriate column and row headers.
    - Sequential headings.
  - Coding style: push(), eliminate use of $_
  - Localization
  - Use standard LON-CAPA data table styling.
  
  
-------------- next part --------------
Index: loncom/interface/lonmanagekeys.pm
diff -u loncom/interface/lonmanagekeys.pm:1.27 loncom/interface/lonmanagekeys.pm:1.28
--- loncom/interface/lonmanagekeys.pm:1.27	Thu Dec 11 01:48:54 2014
+++ loncom/interface/lonmanagekeys.pm	Tue May  5 11:18:49 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to manage course access keys 
 #
-# $Id: lonmanagekeys.pm,v 1.27 2014/12/11 01:48:54 raeburn Exp $
+# $Id: lonmanagekeys.pm,v 1.28 2026/05/05 11:18:49 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -50,6 +50,7 @@
                                                   {'bread_crumbs' => $brcrum,});
     return(<<ENDHEAD);
 $start_page
+<div class="LC_landmark" role="main" id="LC_main_content">
 <form method="post" enctype="multipart/form-data"  
       action="/adm/managekeys" name="keyform">
 ENDHEAD
@@ -61,8 +62,18 @@
     $comment=~s/\W/\./g;
     my %accesskeys=&Apache::lonnet::dump
 	('accesskeys',$cenv{'domain'},$cenv{'num'});
+    my %lt;
     unless ($csvlist) {
-	$r->print(<<ENDTABLEHEADER);
+        %lt = &Apache::lonlocal::texthash(
+                  list => 'List of Keys/Enter New Comments',
+                  key  => 'Key',
+                  chec => 'Checked Out',
+                  comm => 'Comments/Remarks/Notes',
+                  ente => 'Enter Additional Comments/Remarks/Notes',
+                  copy => 'Copy to All',
+                  adda => 'Add Above Comments to Key',
+        );
+	$r->print(<<ENDJS);
 <script>
     function copyallcom(tf) {
 	for (i=0; i<tf.elements.length; i++) {
@@ -73,37 +84,57 @@
 
     }
 </script>
-<h3>List of Keys/Enter New Comments</h3>
-<table border="2"><tr><th>Key</th><th>Checked Out</th>
-<th>Comments/Remarks/Notes</th>
-<th>Enter Additional Comments/Remarks/Notes<br />
-<input type="text" size="40" name="copyall" />
-<input type="button" value="Copy to All" onclick="copyallcom(this.form);" />
-</th></tr>
-ENDTABLEHEADER
-    }
-    foreach (keys(%accesskeys)) {
-        if ($_=~/^error\:/) {
-	    $r->print('<tr><td>No keys have been generated yet.</td></tr>');
-        } elsif ($accesskeys{$_}=~/$comment/) {
-	    my ($checkout,$com)=split(/\s*\#\s*/,$accesskeys{$_});
+ENDJS
+        $r->print('<h2 class="LC_heading_2">'.$lt{'list'}.'</h2>'
+                 .&Apache::loncommon::start_data_table('LC_paramDefault')
+                 .&Apache::loncommon::start_data_table_header_row()
+                 .'<th>'.$lt{'key'}.'</th>'."\n"
+                 .'<th>'.$lt{'chec'}.'</th>'."\n"
+                 .'<th>'.$lt{'comm'}.'</th>'."\n"
+                 .'<th id="commentscol">'.$lt{'ente'}.'</th>'."\n"
+                 .&Apache::loncommon::end_data_table_header_row()
+                 .&Apache::loncommon::start_data_table_row()
+                 .'<td colspan="3"> </td>'
+                 .'<td><input type="text" size="40" name="copyall" aria-label="'.$lt{'copy'}.'" />'
+                 .'<input type="button" value="'.$lt{'copy'}.'" onclick="copyallcom(this.form);" />'
+                 .'</td>'
+                 .&Apache::loncommon::end_data_table_row());
+    }
+    foreach my $key (keys(%accesskeys)) {
+        if ($key =~ /^error\:/) {
+            my $msg = &mt('No keys have been generated yet.');
+            if ($csvlist) {
+                $r->print($msg);
+            } else {
+                $r->print(&Apache::loncommon::start_data_table_row()
+                         .'<td colspan="4">'
+                         .$msg
+                         .'</td>'
+                         .&Apache::loncommon::end_data_table_row());
+            }
+        } elsif ($accesskeys{$key}=~/$comment/) {
+	    my ($checkout,$com)=split(/\s*\#\s*/,$accesskeys{$key});
             unless ($checkout) {
 		if ($checkonly) { next; }
             } else {
 		if ($newonly) { next; }
             }
             unless ($csvlist) {
-		$r->print("\n<tr><td><tt>".$_.'</tt></td><td>'.($checkout?
-                     $checkout:'-').'</td><td>'.
-                     join('<br />',split(/\s*\;\s*/,$com)).
-		     '</td><td><input type="text" size="40" name="com_'.$_.
-		     '" value="" /></td></tr>');
+                $r->print("\n".&Apache::loncommon::start_data_table_row()
+                         .'<th scope="row" id="'.$key.'_row" class="LC_rowheader">'
+                         .'<tt>'.$key.'</tt></th><td>'.($checkout?
+                                                        $checkout:'-').'</td>'
+                         .'<td>'
+                         .join('<br />',split(/\s*\;\s*/,$com))
+                         .'</td><td><input type="text" size="40" name="com_'.$key
+                         .'" value="" aria-labelledby="commentscol '.$key.'_row" /></td>'
+                         .&Apache::loncommon::end_data_table_row());
 	    } else {
 		my @line = ();
-		push @line,&Apache::loncommon::csv_translate($_);
-		push @line,&Apache::loncommon::csv_translate($checkout);
-		foreach (split(/\s*\;\s*/,$com)) {
- 		   push @line,&Apache::loncommon::csv_translate($_);
+		push(@line,&Apache::loncommon::csv_translate($key));
+		push(@line,&Apache::loncommon::csv_translate($checkout));
+		foreach my $item (split(/\s*\;\s*/,$com)) {
+ 		   push(@line,&Apache::loncommon::csv_translate($item));
 		}
 		my $tmp = $";
 		$" = '","';
@@ -113,8 +144,8 @@
        }
     }
     unless ($csvlist) {
-	$r->print('</table>');
-	$r->print('<input type="submit" name="addcom" value="Add Above Comments to Keys" /><hr />');
+        $r->print(&Apache::loncommon::end_data_table()
+                 .'<input type="submit" name="addcom" value="'.$lt{'adda'}.'" /><hr />');
     }
     return '';
 }
@@ -159,10 +190,10 @@
     my %cenv=@_;
     my %newcomment=();
     undef %newcomment;
-    foreach (keys(%env)) {
-	if ($_=~/^form\.com\_(.+)$/) {
+    foreach my $envkey (keys(%env)) {
+	if ($envkey =~ /^form\.com\_(.+)$/) {
             my $key=$1;
-	    my $comment=$env{$_};
+	    my $comment=$env{$envkey};
             $comment=~s/^\s+//gs;
             if ($comment) {
                &Apache::lonnet::comment_access_key
@@ -246,8 +277,22 @@
 		&addcom(%cenv);
             }
 # --- Menu
+            my %lt = &Apache::lonlocal::texthash(
+                         genk => 'Generate New Keys',
+                         numk => 'Number of keys to be generated',
+                         comm => 'Comments/Remarks/Notes',
+                         gene => 'Generate Keys',
+                         sett => 'Settings for new keys',
+                         list => 'List Keys',
+                         filt => 'Filters to apply to listing of keys',
+                         core => 'Comments/Remarks/Notes/User/Batch Number Filter',
+                         unsd => 'Unused keys only',
+                         used => 'Used keys only',
+                         liad => 'List Keys/Add Comments',
+                         csvl => 'CSV List of Keys',
+            );
 	    if ($keytype eq 'course') {
-		$r->print('<h3>'.&mt('Key Access').'</h3>');
+		$r->print('<h2 class="LC_heading_2">'.&mt('Key Access').'</h2>');
 		if ($cenv{'keyaccess'} eq 'yes') {
 		    $r->print(&mt('Access to this course is key controlled.').
 '<br /><input type="submit" name="toggle" value="'.&mt('Open Access').'" />')
@@ -255,23 +300,29 @@
 		    $r->print(&mt('Access to this course is open, no access keys').'<br /><input type="submit" name="toggle" value="'.&mt('Control Access').'" />');
 		}
 	    } else {
-		$r->print('<h3>'.&mt('Key Authority').
-			  ' <tt>'.$cenv{'num'}.'@'.$cenv{'domain'}.'</tt></h3>');
+		$r->print('<h2 class="LC_heading_2">'.&mt('Key Authority').
+			  ' <tt>'.$cenv{'num'}.':'.$cenv{'domain'}.'</tt></h2>');
 	    }
 	    $r->print(<<ENDKEYMENU);
-<hr /><h3>Generate New Keys</h3>
-Number of keys to be generated: <input type="text" name="num" size="6" /><br />
-Comments/Remarks/Notes: <input type="text" name="comments" size="30" /><br />
-<input type="submit" name="genkeys" value="Generate Keys" />
-<hr /><h3>List Keys</h3>
-Comments/Remarks/Notes/User/Batch Number Filter:
-<input type="text" name="listcom" size="30" value="$batchnumber" /><br />
-<label><input type="checkbox" name="newonly" /> Unused keys only</label><br />
-<label><input type="checkbox" name="checkonly" /> Used keys only</label><br />
-<input type="submit" name="listkeys" value="List Keys/Add Comments" />
-<input type="submit" name="listkeyscsv" value="CSV List of Keys" />
+<hr /><h2 class="LC_heading_2">$lt{'genk'}</h2>
+<fieldset class="LC_borderless" style="line-height: 180%;">
+<legend class="LC_visually_hidden">$lt{'sett'}</legend>
+<label>$lt{'numk'}: <input type="text" name="num" size="6" /></label><br />
+<label>$lt{'comm'}: <input type="text" name="comments" size="30" /></label>
+</fieldset><br />
+<input type="submit" name="genkeys" value="$lt{'gene'}" />
+<hr /><h2 class="LC_heading_2">$lt{'list'}</h2>
+<fieldset class="LC_borderless" style="line-height: 185%;">
+<legend class="LC_visually_hidden">$lt{'filt'}</legend>
+<label>$lt{'core'}:
+<input type="text" name="listcom" size="30" value="$batchnumber" /></label><br />
+<label><input type="checkbox" name="newonly" /> $lt{'unsd'}</label><br />
+<label><input type="checkbox" name="checkonly" /> $lt{'used'}</label>
+</fieldset><br />
+<input type="submit" name="listkeys" value="$lt{'liad'}" />
+<input type="submit" name="listkeyscsv" value="$lt{'csvl'}" />
 ENDKEYMENU
-	    $r->print('</form>'.&Apache::loncommon::end_page());
+	    $r->print('</form></div>'.&Apache::loncommon::end_page());
 	}
     } else {
 	# Start page no course id
@@ -279,20 +330,26 @@
 	$r->send_http_header;
 	$r->print(&header().&Apache::loncommon::coursebrowser_javascript());
         $r->print('<br />');
+        my %lt = &Apache::lonlocal::texthash(
+                     idka => 'Course ID of Key Authority',
+                     doma => 'Domain',
+                     next => 'Next',
+        );
         $r->print(&Apache::lonhtmlcommon::start_pick_box()
-                 .&Apache::lonhtmlcommon::row_title(&mt('Course ID of Key Authority'))
-                 .'<input input type="text" size="25" name="course" value="" />'
+                 .&Apache::lonhtmlcommon::row_title('<label for="course">'.$lt{'idka'}.'</label>')
+                 .'<input input type="text" size="25" name="course" id="course" value="" />'
                  .' '.&Apache::loncommon::selectcourse_link(
                           'keyform','course','domain',
                           undef,undef,undef,'Course')
                  .&Apache::lonhtmlcommon::row_closure()
-                 .&Apache::lonhtmlcommon::row_title(&mt('Domain'))
-                 .&Apache::loncommon::select_dom_form($env{'request.role.domain'},'domain')
+                 .&Apache::lonhtmlcommon::row_title('<label for="domain">'.$lt{'doma'}.'</label>')
+                 .&Apache::loncommon::select_dom_form($env{'request.role.domain'},'domain',
+                                                      '','','','','','','domain')
                  .&Apache::lonhtmlcommon::row_closure(1)
                  .&Apache::lonhtmlcommon::end_pick_box()
         );
-        $r->print('<input type="submit" value="'.&mt('Next').'" />'
-                .'</form>'
+        $r->print('<input type="submit" value="'.$lt{'next'}.'" />'
+                .'</form></div>'
                 .&Apache::loncommon::end_page()
         );
     }


More information about the LON-CAPA-cvs mailing list