[LON-CAPA-cvs] cvs: loncom /homework grades.pm

ng lon-capa-cvs@mail.lon-capa.org
Mon, 08 Jul 2002 21:18:54 -0000


This is a MIME encoded message

--ng1026163134
Content-Type: text/plain

ng		Mon Jul  8 17:18:54 2002 EDT

  Modified files:              
    /loncom/homework	grades.pm 
  Log:
  implement storing keywords, attributes etc to handgrade.db
  display last submission only - no history etc.
  pretty much working now but slow for 280 students
  needs to find a way to speed up the process
  
  
  
--ng1026163134
Content-Type: text/plain
Content-Disposition: attachment; filename="ng-20020708171854.txt"

Index: loncom/homework/grades.pm
diff -u loncom/homework/grades.pm:1.36 loncom/homework/grades.pm:1.37
--- loncom/homework/grades.pm:1.36	Sun Jul  7 16:08:45 2002
+++ loncom/homework/grades.pm	Mon Jul  8 17:18:54 2002
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.36 2002/07/07 20:08:45 ng Exp $
+# $Id: grades.pm,v 1.37 2002/07/08 21:18:54 ng Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -136,9 +136,11 @@
 &nbsp;<font size=+1><b>Resource:</b> $ENV{'form.url'}<br /><br />
 <form action="/adm/grades" method="post">&nbsp;<b>View Options</b></font><br />
 &nbsp;<b>View Problem: </b><input type="radio" name="vProb" value="no" checked> no 
-<input type="radio" name="vProb" value="yes"> yes 
-&nbsp;&nbsp;&nbsp;<b>Submissions: </b><input type="radio" name="lastSub" value="last" checked> last 
-<input type="radio" name="lastSub" value="all"> all 
+<input type="radio" name="vProb" value="yes"> yes <br />
+&nbsp;<b>Submissions: </b>
+<input type="radio" name="lastSub" value="lastonly" checked> last sub only
+<input type="radio" name="lastSub" value="last"> last sub & parts info
+<input type="radio" name="lastSub" value="all"> all details
 <input type="hidden" name="section" value="$getsec">
 <input type="hidden" name="submitonly" value="$submitonly">
 <input type="hidden" name="response" value="$ENV{'form.response'}">
@@ -428,13 +430,26 @@
     var Nmsg  = msgform.savemsgN.value;
     savedMsgHeader(Nmsg,usrctr,fullname);
     var subject = msgform.msgsub.value;
-    displaySubject(subject);
+    var rtrchk  = eval("document.SCORE.includemsg"+usrctr);
+    var msgchk = rtrchk.value;
+//    alert("checked=>"+msgchk);
+    re = /msgsub/;
+    var shwsel = "";
+    if (re.test(msgchk)) { shwsel = "checked" }
+    displaySubject(subject,shwsel);
     for (var i=1; i<=Nmsg; i++) {
+	var testpt = "savemsg"+i+",";
+	re = /testpt/;
+	shwsel = "";
+	if (re.test(msgchk)) { shwsel = "checked" }
 	var message = eval("document.SCORE.savemsg"+i+".value");
-	displaySavedMsg(i,message);
+	displaySavedMsg(i,message,shwsel);
     }
     newmsg = eval("document.SCORE.newmsg"+usrctr+".value");
-    newMsg(newmsg);
+    shwsel = "";
+    re = /newmsg/;
+    if (re.test(msgchk)) { shwsel = "checked" }
+    newMsg(newmsg,shwsel);
     msgTail(); 
     return;
   }
@@ -446,6 +461,8 @@
 	height = 600;
 	scrollbar = "yes";
     }
+/*    if (window.pWin)
+	window.pWin.close(); */
     pWin = window.open('', 'MessageCenter', 'toolbar=no,location=no,scrollbars='+scrollbar+',width=600,height='+height);
     pWin.document.write("<html><head>");
     pWin.document.write("<title>Message Central</title>");
@@ -460,7 +477,7 @@
 
     pWin.document.write("  var msgchk = \\"\\";");
     pWin.document.write("  if (document.msgcenter.subchk.checked) {");
-    pWin.document.write("     msgchk = \\"subject,\\";");
+    pWin.document.write("     msgchk = \\"msgsub,\\";");
     pWin.document.write("  }");
     pWin.document.write(   "for (var i=1; i<=nmsg; i++) {");
     pWin.document.write("      var opnmsg = eval(\\"opener.document.SCORE.savemsg\\"+i);");
@@ -468,15 +485,16 @@
     pWin.document.write("      opnmsg.value = frmmsg.value;");
     pWin.document.write("      var chkbox = eval(\\"document.msgcenter.msgn\\"+i);");
     pWin.document.write("      if (chkbox.checked) {");
-    pWin.document.write("         msgchk += i+\\",\\";");
+    pWin.document.write("         msgchk += \\"savemsg\\"+i+\\",\\";");
     pWin.document.write("      }");
     pWin.document.write("  }");
     pWin.document.write("  if (document.msgcenter.newmsgchk.checked) {");
-    pWin.document.write("     msgchk += \\"new\\";");
+    pWin.document.write("     msgchk += \\"newmsg\\"+usrctr;");
     pWin.document.write("  }");
     pWin.document.write("  var includemsg = eval(\\"opener.document.SCORE.includemsg\\"+usrctr);");
     pWin.document.write("  includemsg.value = msgchk;");
 
+//    pWin.document.write("  alert(\\"slected=\\"+msgchk)");
     pWin.document.write("  self.close()");
 
     pWin.document.write("}");
@@ -494,24 +512,24 @@
     pWin.document.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">");
     pWin.document.write("<td><b>Type</b></td><td><b>Include</b></td><td><b>Message</td></tr>");
 }
-    function displaySubject(msg) {
+    function displaySubject(msg,shwsel) {
     pWin.document.write("<tr bgcolor=\\"#ffffdd\\">");
     pWin.document.write("<td>Subject</td>");
-    pWin.document.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\" checked></td>");
+    pWin.document.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\"" +shwsel+"></td>");
     pWin.document.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+" \\"size=\\"60\\" maxlength=\\"80\\"></td></tr>");
 }
 
-function displaySavedMsg(ctr,msg) {
+function displaySavedMsg(ctr,msg,shwsel) {
     pWin.document.write("<tr bgcolor=\\"#ffffdd\\">");
     pWin.document.write("<td align=\\"center\\">"+ctr+"</td>");
-    pWin.document.write("<td align=\\"center\\"><input name=\\"msgn"+ctr+"\\" type=\\"checkbox\\"></td>");
+    pWin.document.write("<td align=\\"center\\"><input name=\\"msgn"+ctr+"\\" type=\\"checkbox\\"" +shwsel+"></td>");
     pWin.document.write("<td><input name=\\"msg"+ctr+"\\" type=\\"text\\" value=\\""+msg+" \\" size=\\"60\\" maxlength=\\"80\\"></td></tr>");
 }
 
-function newMsg(newmsg) {
+function newMsg(newmsg,shwsel) {
     pWin.document.write("<tr bgcolor=\\"#ffffdd\\">");
     pWin.document.write("<td align=\\"center\\">New</td>");
-    pWin.document.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"></td>");
+    pWin.document.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"></td>");
     pWin.document.write("<td><input name=\\"newmsg\\" type=\\"text\\" value=\\""+newmsg+" \\" size=\\"60\\" maxlength=\\"80\\"></td></tr>");
 }
 
@@ -623,15 +641,14 @@
   my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
   if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
   my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');
-#
-# header info
+
+  # header info
   if ($counter == 0) {
       $request->print('<h2>&nbsp;<font color="#339933">Submission Record</font></h2>'.
 		      '<font size=+1>&nbsp;<b>Resource: </b>'.$url.'</font>');
   }
 
-#
-# option to display problem, only once else it cause problems with the form later since the problem has a form.
+  # option to display problem, only once else it cause problems with the form later since the problem has a form.
   if ($ENV{'form.vProb'} eq 'yes' && $counter == 0) {
       my $rendered=&Apache::loncommon::get_student_view($symb,$uname,$udom,
 						   $ENV{'request.course.id'});
@@ -645,65 +662,75 @@
       $result.='</td></tr></table><br />';
       $request->print($result);
   }
-#
-# beginning of form
+
+  # beginning of form
   if ($counter == 0) {
-      my %keyhash = &Apache::lonnet::get
-                ('nohist_handgrade',[$symb.'_keywords'],
+      my %keyhash = &Apache::lonnet::dump('nohist_handgrade',
                  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
 		 $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
 
+      my $loginuser = $ENV{'user.name'}.':'.$ENV{'user.domain'};
+      # if the handgrade db has never being initialized then set some default values
+      if ($keyhash{$symb.'_handgrade'} eq '') {
+	  $keyhash{$symb.'_keywords'}     = '';
+	  $keyhash{$symb.'_subject'}      = &Apache::lonnet::metadata($url,'title');
+	  $keyhash{$loginuser.'_kwclr'}   = $keyhash{$loginuser.'_kwclr'}   eq '' ? 'red' : $keyhash{$loginuser.'_kwclr'};
+	  $keyhash{$loginuser.'_kwsize'}  = $keyhash{$loginuser.'_kwsize'}  eq '' ? '0' : $keyhash{$loginuser.'_kwsize'};
+	  $keyhash{$loginuser.'_kwstyle'} = $keyhash{$loginuser.'_kwstyle'} eq '' ? ''  : $keyhash{$loginuser.'_kwstyle'};
+ 	  $keyhash{$symb.'_savemsgN'}     = '0';
+      }
       $request->print('<form action="/adm/grades" method="post" name="SCORE">'."\n".
 		      '<input type="hidden" name="symb"       value="'.$symb.'" />'."\n".
 		      '<input type="hidden" name="url"        value="'.$url.'" />'."\n".
 		      '<input type="hidden" name="vProb"      value="'.$ENV{'form.vProb'}.'" />'."\n".
-		      '<input type="hidden" name="lastSub"    value="'.$last.'" />'."\n".
+		      '<input type="hidden" name="lastSub"    value="'.$ENV{'form.lastSub'}.'" />'."\n".
 		      '<input type="hidden" name="section"    value="'.$ENV{'form.section'}.'">'."\n".
 		      '<input type="hidden" name="submitonly" value="'.$ENV{'form.submitonly'}.'">'."\n".
 		      '<input type="hidden" name="response"   value="'.$ENV{'form.response'}.'">'."\n".
 		      '<input type="hidden" name="handgrade"  value="'.$ENV{'form.handgrade'}.'">'."\n".
 		      '<input type="hidden" name="command"    value="handgrade" />'."\n".
 		      '<input type="hidden" name="keywords"   value="'.$keyhash{$symb.'_keywords'}.'" />'."\n".
-		      '<input type="hidden" name="kwclr"      value="blue" />'."\n".
-		      '<input type="hidden" name="kwsize"     value="0" />'."\n".
-		      '<input type="hidden" name="kwstyle"    value="" />'."\n".
-		      '<input type="hidden" name="msgsub"     value="Problem title" />'."\n".
-		      '<input type="hidden" name="savemsgN"   value="4" />'."\n".
-		      '<input type="hidden" name="savemsg1"   value="Good Job!" />'."\n".
-		      '<input type="hidden" name="savemsg2"   value="Needs a better explanation." />'."\n".
-		      '<input type="hidden" name="savemsg3"   value="Read the book before submitting such garbagge!" />'."\n".
-		      '<input type="hidden" name="savemsg4"   value="You are nowhere close." />'."\n".
+		      '<input type="hidden" name="kwclr"      value="'.$keyhash{$loginuser.'_kwclr'}.'" />'."\n".
+		      '<input type="hidden" name="kwsize"     value="'.$keyhash{$loginuser.'_kwsize'}.'" />'."\n".
+		      '<input type="hidden" name="kwstyle"    value="'.$keyhash{$loginuser.'_kwstyle'}.'" />'."\n".
+		      '<input type="hidden" name="msgsub"     value="'.$keyhash{$symb.'_subject'}.'" />'."\n".
+		      '<input type="hidden" name="savemsgN"   value="'.$keyhash{$symb.'_savemsgN'}.'" />'."\n".
 		      '<input type="hidden" name="NCT"'.
-		      ' value="'.($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : '1').'" />'."\n");
+		      ' value="'.($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : $total+1).'" />'."\n");
+
+      my ($cts,$prnmsg) = (1,'');
+      while ($cts <= $keyhash{$symb.'_savemsgN'}) {
+	  $prnmsg.='<input type="hidden" name="savemsg'.$cts.'" value="'.$keyhash{$symb.'_savemsg'.$cts}.'" />'."\n";
+	  $cts++;
+      }
+      $request->print($prnmsg);
 
       if ($ENV{'form.handgrade'} eq 'yes') {
 	  $request->print(<<KEYWORDS);
 &nbsp;<b>Keyword Options</b>&nbsp;
 <a href="javascript:keywords(document.SCORE.keywords)"; TARGET=_self>Keyword List</a>&nbsp; &nbsp;
 <a href="#" onMouseDown="javascript:getSel(); return false"
- CLASS="page">Paste Selection to Keyword list</a> (requires N4+ and IE5+)&nbsp; &nbsp;
+ CLASS="page">Paste Selection to Keyword list</a>&nbsp; &nbsp;
 <a href="javascript:kwhighlight()"; TARGET=_self>Keyword Highlight Attribute</a><br /><br />
 KEYWORDS
       }
   }
 
-#
-# Student info
+  # Student info
   $request->print(($counter == 0 ? '' : '<br /><hr><br />'));
   my $fullname = ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom));
   my $result.='<table border="0"><tr><td><b>Username: </b>'.$uname.
       '</td><td><b>Fullname: </b>'.$fullname.
-#	  ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom)).
 	      '</td><td><b>Domain: </b>'.$udom.'</td></tr>';
   if ($ENV{'form.handgrade'} eq 'yes') {
-      my $subonly = &get_last_submission($symb,$uname,$udom,$ENV{'request.course.id'});
+#      my $subonly = &get_last_submission($symb,$uname,$udom,$ENV{'request.course.id'});
       my ($classlist) = &getclasslist('all','0');
       my @collaborators;
-      foreach ( sort(@{ $$classlist{'all'} }) ) {
-	  my ($sname,$sdom) = split(/:/);
-	  push @collaborators,$sname if (grep /\b$sname(\b|\.)/i,$subonly);
-      }
-      push @collaborators,'leede','carlandmm','freyniks'; # as a test to display collaborators.
+#      foreach ( sort(@{ $$classlist{'all'} }) ) {
+#	  my ($sname,$sdom) = split(/:/);
+#	  push @collaborators,$sname if (grep /\b$sname(\b|\.)/i,$subonly);
+#      }
+#      push @collaborators,'leede','carlandmm','freyniks'; # as a test to display collaborators.
       if (scalar(@collaborators) != 0) {
 	  $result.='<tr><td colspan=3><b>Collaborators: </b>';
 	  foreach (@collaborators) {
@@ -716,28 +743,39 @@
   }
   $result.='</table>'."\n";
   $request->print($result);
-#
-# print student answer
-  $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
-							   $ENV{'request.course.id'},$last,
-							   '.submission','Apache::grades::keywords_highlight'));
-#
-#
+
+  # print student answer
+  if ($ENV{'form.lastSub'} eq 'lastonly') {
+      my ($string,$timestamp)=&get_last_submission ($symb,$uname,$udom,$ENV{'request.course.id'});
+      $string=&keywords_highlight($string);
+      my $lastsubonly='<table border="0" width=100%><tr><td bgcolor="#777777">';
+      $lastsubonly.='<table border="0" width=100%><tr bgcolor="#e6ffff">';
+      $lastsubonly.='<td><b>Last Submission Only</b>'.
+	  ($timestamp eq '' ? '' : '&nbsp; &nbsp; <b>Date Submitted:</b> '.$timestamp).'</td></tr>';
+      $lastsubonly.='<tr><td bgcolor="#ffffe6">';
+      $lastsubonly.=$string;
+      $lastsubonly.='</td></tr></table></td></tr></table>'."\n";
+      $request->print($lastsubonly);
+  } else {
+      $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
+							       $ENV{'request.course.id'},$last,
+							       '.submission','Apache::grades::keywords_highlight'));
+  }
+
   my $wgt    = &Apache::lonnet::EXT('resource.partid.weight',$symb,$udom,$uname);
   my $wgtmsg = ($wgt > 0 ? '(problem weight)' : '<font color="red">problem weight assigned by computer</font>');
   $wgt       = ($wgt > 0 ? $wgt : '1');
   my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);
   my $score  = ($record{'resource.0.awarded'} eq '' ? '' : $record{'resource.0.awarded'}*$wgt);
 
-#
-# display grading options
+  # display grading options
   $result='<input type="hidden" name="WGT'.$counter.'" value="'.$wgt.'" />'.
       '<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'.$udom.'" />'."\n";
-  $result.='<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n".
-  $result.='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".
+  $result.='<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n";
+  $result.='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n";
   $result.='<table border="0"><tr><td><b>Points</b></td><td>';
-  my $ctr = 0;
 
+  my $ctr = 0;
   $result.='<table border="0"><tr>';  # display radio buttons in a nice table with 10 across
   while ($ctr<=$wgt) {
       $result.= '<td><input type="radio" name="RADVAL'.$counter.'" '.
@@ -776,8 +814,8 @@
   }
   $result.='</table>';
   $request->print($result);
-#
-# print end of form
+
+  # print end of form
   if ($counter == $total) {
       my $endform.='<table border="0"><tr><td><input type="submit" name="gradeOpt" value="Save & Next" />';
       my $ntstu ='<select name="NTSTU">'.
@@ -799,20 +837,23 @@
 sub get_last_submission {
   my ($symb,$username,$domain,$course)=@_;
   if ($symb) {
+      my ($string,$timestamp);
      my (%returnhash)=&Apache::lonnet::restore($symb,$course,$domain,$username);
      if ($returnhash{'version'}) {
 	my %lasthash=();
-	my $version;
+	my ($version);
 	for ($version=1;$version<=$returnhash{'version'};$version++) {
 	  foreach (sort(split(/\:/,$returnhash{$version.':keys'}))) {
 	      $lasthash{$_}=$returnhash{$version.':'.$_};
 	  }
         }
 	foreach ((keys %lasthash)) {
-	    if ($_ =~ /\.submission$/) {return $lasthash{$_}}
+	    if ($_ =~ /\.submission$/) {$string = $lasthash{$_}}
+	    if ($_ =~ /timestamp/) {$timestamp=scalar(localtime($lasthash{$_}))};
 	}
-	return '';
     }
+     $string = $string eq '' ? 'Nothing submitted - no attempts.' : $string;
+     return $string,$timestamp;
   }
 }
 
@@ -820,14 +861,25 @@
   my $string  = shift;
   (my $url=$ENV{'form.url'})=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
   my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
+  my $loginuser = $ENV{'user.name'}.':'.$ENV{'user.domain'};
+
+  my @kwkeys = ($symb.'_keywords',
+		$loginuser.'_kwclr',
+		$loginuser.'_kwsize',
+		$loginuser.'_kwstyle'
+		);
+
   my %keyhash = &Apache::lonnet::get
-      ('nohist_handgrade',[$symb.'_keywords'],
+      ('nohist_handgrade',\@kwkeys,
        $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
        $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   my @keylist = split(/[,\s+]/,$keyhash{$symb.'_keywords'});
+  my $size    = $keyhash{$kwkeys[2]} eq '0' ? '' : 'size='.$keyhash{$kwkeys[2]};
+  my $styleon = $keyhash{$kwkeys[3]} eq ''  ? '' : $keyhash{$kwkeys[3]};
+  (my $styleoff = $styleon) =~ s/\</\<\//;
   foreach my $word (@keylist) {
       next if ($word eq '');
-      $string =~ s/\b$word(\b|\.)/\<font color\=red\>$word\<\/font\>/gi;
+      $string =~ s/\b$word(\b|\.)/\<font color\=$keyhash{$kwkeys[1]} $size\>$styleon$word$styleoff\<\/font\>/gi;
   }
   return $string;
 }
@@ -839,33 +891,44 @@
   my $button = $ENV{'form.gradeOpt'};
   my $ngrade = $ENV{'form.NCT'};
   my $ntstu  = $ENV{'form.NTSTU'};
-  my $keywords= $ENV{'form.keywords'};
-  my $newmsg0  = $ENV{'form.newmsg0'};
-  print "newmsg0=$newmsg0<br>";
-  my $newmsg1  = $ENV{'form.newmsg1'};
-  print "newmsg1=$newmsg1<br>";
-  my $oldmsg1  = $ENV{'form.savemsg1'};
-  print "oldmsg1=$oldmsg1<br>";
-  my $oldmsg2  = $ENV{'form.savemsg2'};
-  print "oldmsg1=$oldmsg2<br>";
-  my $oldmsg3  = $ENV{'form.savemsg3'};
-  print "oldmsg1=$oldmsg3<br>";
-  my $oldmsg4  = $ENV{'form.savemsg4'};
-  print "oldmsg1=$oldmsg4<br>";
-  my $messages  = $ENV{'form.includemsg0'};
-  print "messages=$messages<br>";
- if ($keywords ne '') {
-      my $crsname = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
-      my $crsdom  = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
-#      my $putresult = &Apache::lonnet::put
-#                ('nohist_handgrade',{$symb.'_keywords' => $keywords},
-#                 $crsdom,$crsname);
+
+  my $loginuser = $ENV{'user.name'}.':'.$ENV{'user.domain'};
+  my %keyhash = ();
+  $keyhash{$symb.'_handgrade'} = 'activated';
+  $keyhash{$symb.'_keywords'} = $ENV{'form.keywords'};
+  $keyhash{$symb.'_subject'} = $ENV{'form.msgsub'};
+  $keyhash{$loginuser.'_kwclr'} = $ENV{'form.kwclr'};
+  $keyhash{$loginuser.'_kwsize'} = $ENV{'form.kwsize'};
+  $keyhash{$loginuser.'_kwstyle'} = $ENV{'form.kwstyle'};
+
+  my ($ctr,$idx) = (1,1);
+  while ($ctr <= $ENV{'form.savemsgN'}) {
+      if ($ENV{'form.savemsg'.$ctr} ne '') {
+	  $keyhash{$symb.'_savemsg'.$idx} = $ENV{'form.savemsg'.$ctr};
+	  $idx++;
+      }
+      $ctr++;
   }
+  $ctr = 0;
+  while ($ctr < $ngrade) {
+      if ($ENV{'form.newmsg'.$ctr} ne '') {
+	  $keyhash{$symb.'_savemsg'.$idx} = $ENV{'form.newmsg'.$ctr};
+	  $idx++;
+      }
+      $ctr++;
+  }
+
+  $keyhash{$symb.'_savemsgN'} = --$idx;
+  my $putresult = &Apache::lonnet::put
+      ('nohist_handgrade',\%keyhash,
+       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
+       $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+
   my (@parts) = sort(&getpartlist($url));
 
   if ($button eq 'Save & Next') {
       my $ctr = 0;
-      while ($ctr < $ENV{'form.NCT'}) {
+      while ($ctr < $ngrade) {
 	  my ($uname,$udom) = split(/:/,$ENV{'form.unamedom'.$ctr});
 	  &saveHandGrade($url,$symb,$uname,$udom,$ctr,@parts);
 	  if ($ENV{'form.collaborator'.$ctr}) {
@@ -881,11 +944,14 @@
   my $laststu  = $ENV{'form.unamedom'.($ngrade-1)};
 
   my ($classlist) = &getclasslist($ENV{'form.section'},'0');
-
+#  print "first=$firststu,last=$laststu<br>";
   my (@nextlist,@prevlist);
   my ($nextflg,$prevflg,$ctr,$ctprev) = (0,0,0,0);
   foreach my $student ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) {
       my ($uname,$udom) = split(/:/,$student);
+      my ($type,$status) = &student_gradeStatus($ENV{'form.url'},$udom,$uname);
+      next if ($status eq 'nothing' && $ENV{'form.submitonly'} eq 'yes');
+
       if ($nextflg == 1 && $button =~ /Next$/) {
 	  push @nextlist,$uname if ($ctr < $ntstu);
 	  $ctr++;
@@ -897,6 +963,7 @@
 	  $ctprev++;
       }
   }
+#  print "next student=@nextlist<br>";
   if ($button eq 'Previous') {
       if ($ctprev <= $ntstu) {
 	  @nextlist = @prevlist;

--ng1026163134--