--- loncom/homework/grades.pm	2003/07/19 15:11:27	1.120
+++ loncom/homework/grades.pm	2003/07/23 17:33:59	1.123
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.120 2003/07/19 15:11:27 ng Exp $
+# $Id: grades.pm,v 1.123 2003/07/23 17:33:59 ng Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -123,23 +123,25 @@ sub showResourceInfo {
     my $result ='<table border="0">'.
 	'<tr><td colspan=3><font size=+1><b>Current Resource: </b>'.$probTitle.'</font></td></tr>'."\n";
     my ($partlist,$handgrade) = &response_type($url);
-    my ($resptype,$hdgrade)=('','no');
+    my %resptype = (); #,$hdgrade)=('','no');
+    my $hdgrade='no';
     for (sort keys(%$handgrade)) {
 	my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
-	$resptype = $responsetype;
+	my $partID = (split(/_/))[0];
+	$resptype{$partID} = $responsetype;
 	$hdgrade = $handgrade if ($handgrade eq 'yes');
-	$result.='<tr><td><b>Part </b>'.(split(/_/))[0].'</td>'.
+	$result.='<tr><td><b>Part </b>'.$partID.'</td>'.
 	    '<td><b>Type: </b>'.$responsetype.'</td></tr>';
 #	    '<td><b>Handgrade: </b>'.$handgrade.'</td></tr>';
     }
     $result.='</table>'."\n";
-    return $result,$resptype,$hdgrade,$partlist,$handgrade;
+    return $result,\%resptype,$hdgrade,$partlist,$handgrade;
 }
 
 #--- Clean response type for display
 #--- Currently filters option response type only.
 sub cleanRecord {
-    my ($answer,$response) = @_;
+    my ($answer,$response,$symb) = @_;
     if ($response eq 'option') {
 	my (@IDs,@ans);
 	foreach (split(/\&/,&Apache::lonnet::unescape($answer))) {
@@ -155,6 +157,21 @@ sub cleanRecord {
 	    (join '</td><td>'.$grayFont,@IDs).'</font></td></tr>'.
 	    '</table>';
     }
+    if ($response eq 'essay') {
+	if (! exists ($ENV{'form.'.$symb})) {
+	    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'};
+	    $ENV{'form.keywords'} = $keyhash{$symb.'_keywords'} ne '' ? $keyhash{$symb.'_keywords'} : '';
+	    $ENV{'form.kwclr'}    = $keyhash{$loginuser.'_kwclr'} ne '' ? $keyhash{$loginuser.'_kwclr'} : 'red';
+	    $ENV{'form.kwsize'}   = $keyhash{$loginuser.'_kwsize'} ne '' ? $keyhash{$loginuser.'_kwsize'} : '0';
+	    $ENV{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';
+	    $ENV{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob.
+	}
+	return &keywords_highlight($answer);
+    }
     return $answer;
 }
 
@@ -197,6 +214,7 @@ COMMONJSFUNCTIONS
 #--- section, ids and fullnames for each user.
 sub getclasslist {
     my ($getsec,$filterlist) = @_;
+    $getsec = $getsec eq '' ? 'all' : $getsec;
     my $classlist=&Apache::loncoursedata::get_classlist();
     # Bail out if we were unable to get the classlist
     return if (! defined($classlist));
@@ -430,7 +448,7 @@ sub listStudents {
     my $result='<h3><font color="#339933">&nbsp;'.$viewgrade.
 	' Submissions for a Student or a Group of Students</font></h3>';
 
-    my ($table,$resptype,$hdgrade,$partlist,$handgrade) = &showResourceInfo($url,$ENV{'form.probTitle'});
+    my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($url,$ENV{'form.probTitle'});
     $result.=$table;
 
     $request->print(<<LISTJAVASCRIPT);
@@ -485,10 +503,10 @@ LISTJAVASCRIPT
 
     $gradeTable.='<input type="radio" name="lastSub" value="lastonly" '.$checklastsub.' /> last sub only'."\n".
 	'<input type="radio" name="lastSub" value="last" /> last sub & parts info'."\n".
+	'<input type="radio" name="lastSub" value="datesub" /> by dates and submissions'."\n".
 	'<input type="radio" name="lastSub" value="all" /> all details'."\n".
 	'<input type="hidden" name="section"     value="'.$getsec.'" />'."\n".
 	'<input type="hidden" name="submitonly"  value="'.$submitonly.'" />'."\n".
-	'<input type="hidden" name="response"    value="'.$ENV{'form.response'}.'" />'."\n".
 	'<input type="hidden" name="handgrade"   value="'.$ENV{'form.handgrade'}.'" /><br />'."\n".
 	'<input type="hidden" name="showgrading" value="'.$ENV{'form.showgrading'}.'" /><br />'."\n".
 	'<input type="hidden" name="saveState"   value="'.$ENV{'form.saveState'}.'" />'."\n".
@@ -721,9 +739,9 @@ sub sub_page_js {
 	return;
     }
 
-//=========== Check that a point is assigned for all the parts (essay grading only) ============
+//=========== Check that a point is assigned for all the parts  ============
     function checksubmit(formname,val,total,parttot) {
-	document.SCORE.gradeOpt.value = val;
+	formname.gradeOpt.value = val;
 	if (val == "Save & Next") {
 	    for (i=0;i<=total;i++) {
 		for (j=0;j<parttot;j++) {
@@ -745,14 +763,13 @@ sub sub_page_js {
 	    }
 	    
 	}
-	formname.submit();
-    }
-
-//======= Process request to show the grading page from SUBM, CHART buttons
-    function gradeStudent(formname,ptr) {
-	formname.gradeOpt.value = 'Grade Student';
-	formname.showgrading.value = "yes";
-	formname.studentNo.value = ptr;
+	if (val == "Grade Student") {
+	    formname.showgrading.value = "yes";
+	    if (formname.Status.value == "") {
+		formname.Status.value = "Active";
+	    }
+	    formname.studentNo.value = total;
+	}
 	formname.submit();
     }
 
@@ -806,14 +823,14 @@ sub sub_page_kw_js {
 <script type="text/javascript" language="javascript">
 
 //===================== Show list of keywords ====================
-  function keywords(keyform) {
-    var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",keyform.value);
+  function keywords(formname) {
+    var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",formname.keywords.value);
     if (nret==null) return;
-    keyform.value = nret;
+    formname.keywords.value = nret;
 
-    document.SCORE.refresh.value = "on";
-    if (document.SCORE.keywords.value != "") {
-	document.SCORE.submit();
+    formname.refresh.value = "on";
+    if (formname.keywords.value != "") {
+	formname.submit();
     }
     return;
   }
@@ -864,14 +881,18 @@ sub sub_page_kw_js {
     re = /msgsub/;
     var shwsel = "";
     if (re.test(msgchk)) { shwsel = "checked" }
-    displaySubject(subject,shwsel);
+    subject = (document.SCORE.shownSub.value == 0 ? checkEntities(subject) : subject);
+    displaySubject(checkEntities(subject),shwsel);
     for (var i=1; i<=Nmsg; i++) {
-	var testpt = "savemsg"+i+",";
-	re = /testpt/;
+	var testmsg = "savemsg"+i+",";
+	re = new RegExp(testmsg,"g");
 	shwsel = "";
 	if (re.test(msgchk)) { shwsel = "checked" }
 	var message = eval("document.SCORE.savemsg"+i+".value");
-	displaySavedMsg(i,message,shwsel);
+	var shownOnce = eval("document.SCORE.shownOnce"+i+".value");
+	message = (shownOnce == 0 ? checkEntities(message) : message);
+	displaySavedMsg(i,message,shwsel); //I do not get it. w/o checkEntities on saved messages,
+	                                   //any &lt; is already converted to <, etc. However, only once!!
     }
     newmsg = eval("document.SCORE.newmsg"+usrctr+".value");
     shwsel = "";
@@ -882,6 +903,22 @@ sub sub_page_kw_js {
     return;
   }
 
+  function checkEntities(strx) {
+    if (strx.length == 0) return strx;
+    var orgStr = ["&", "<", ">", '"']; 
+    var newStr = ["&amp;", "&lt;", "&gt;", "&quot;"];
+    var counter = 0;
+    while (counter < 4) {
+	strx = strReplace(strx,orgStr[counter],newStr[counter]);
+	counter++;
+    }
+    return strx;
+  }
+
+  function strReplace(strx, orgStr, newStr) {
+    return strx.split(orgStr).join(newStr);
+  }
+
   function savedMsgHeader(Nmsg,usrctr,fullname) {
     var height = 70*Nmsg+250;
     var scrollbar = "no";
@@ -903,11 +940,11 @@ sub sub_page_kw_js {
 
     pDoc.write("<script language=javascript>");
     pDoc.write("function checkInput() {");
-    pDoc.write("  opener.document.SCORE.msgsub.value = document.msgcenter.msgsub.value;");
+    pDoc.write("  opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value);");
     pDoc.write("  var nmsg   = opener.document.SCORE.savemsgN.value;");
     pDoc.write("  var usrctr = document.msgcenter.usrctr.value;");
     pDoc.write("  var newval = eval(\\"opener.document.SCORE.newmsg\\"+usrctr);");
-    pDoc.write("  newval.value = document.msgcenter.newmsg.value;");
+    pDoc.write("  newval.value = opener.checkEntities(document.msgcenter.newmsg.value);");
 
     pDoc.write("  var msgchk = \\"\\";");
     pDoc.write("  if (document.msgcenter.subchk.checked) {");
@@ -917,7 +954,9 @@ sub sub_page_kw_js {
     pDoc.write("  for (var i=1; i<=nmsg; i++) {");
     pDoc.write("      var opnmsg = eval(\\"opener.document.SCORE.savemsg\\"+i);");
     pDoc.write("      var frmmsg = eval(\\"document.msgcenter.msg\\"+i);");
-    pDoc.write("      opnmsg.value = frmmsg.value;");
+    pDoc.write("      opnmsg.value = opener.checkEntities(frmmsg.value);");
+    pDoc.write("      var showflg = eval(\\"opener.document.SCORE.shownOnce\\"+i);");
+    pDoc.write("      showflg.value = \\"1\\";");
     pDoc.write("      var chkbox = eval(\\"document.msgcenter.msgn\\"+i);");
     pDoc.write("      if (chkbox.checked) {");
     pDoc.write("         msgchk += \\"savemsg\\"+i+\\",\\";");
@@ -1183,8 +1222,10 @@ sub submission {
 	return;
     }
 
-    $ENV{'form.lastSub'} = ($ENV{'form.lastSub'} eq '' ? 'all' : $ENV{'form.lastSub'});
+    $ENV{'form.lastSub'} = ($ENV{'form.lastSub'} eq '' ? 'datesub' : $ENV{'form.lastSub'});
     my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');
+    my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL').
+	'/check.gif" height="16" border="0" />';
 
     # header info
     if ($counter == 0) {
@@ -1197,8 +1238,6 @@ sub submission {
 			'<font size=+1>&nbsp;<b>Resource: </b>'.$ENV{'form.probTitle'}.'</font>'."\n");
 
 	if ($ENV{'form.handgrade'} eq 'no') {
-	    my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL').
-		'/check.gif" height="16" border="0" />';
 	    my $checkMark='<br /><br />&nbsp;<b>Note:</b> Part(s) graded correct by the computer is marked with a '.
 		$checkIcon.' symbol.'."\n";
 	    $request->print($checkMark);
@@ -1226,7 +1265,6 @@ sub submission {
 	    $ENV{'form.msgsub'}   = $keyhash{$symb.'_subject'} ne '' ? 
 		$keyhash{$symb.'_subject'} : $ENV{'form.probTitle'};
 	    $ENV{'form.savemsgN'} = $keyhash{$symb.'_savemsgN'} ne '' ? $keyhash{$symb.'_savemsgN'} : '0';
-
 	}
 	my $overRideScore = $ENV{'form.overRideScore'} eq '' ? 'no' : $ENV{'form.overRideScore'};
 
@@ -1246,24 +1284,27 @@ sub submission {
 			'<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="keywords"   value="'.$ENV{'form.keywords'}.'" />'."\n".
-			'<input type="hidden" name="kwclr"      value="'.$ENV{'form.kwclr'}.'" />'."\n".
-			'<input type="hidden" name="kwsize"     value="'.$ENV{'form.kwsize'}.'" />'."\n".
-			'<input type="hidden" name="kwstyle"    value="'.$ENV{'form.kwstyle'}.'" />'."\n".
-			'<input type="hidden" name="msgsub"     value="'.$ENV{'form.msgsub'}.'" />'."\n".
-			'<input type="hidden" name="savemsgN"   value="'.$ENV{'form.savemsgN'}.'" />'."\n".
 			'<input type="hidden" name="NCT"'.
 			' value="'.($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : $total+1).'" />'."\n");
+	if ($ENV{'form.handgrade'} eq 'yes') {
+	    $request->print('<input type="hidden" name="keywords" value="'.$ENV{'form.keywords'}.'" />'."\n".
+			    '<input type="hidden" name="kwclr"    value="'.$ENV{'form.kwclr'}.'" />'."\n".
+			    '<input type="hidden" name="kwsize"   value="'.$ENV{'form.kwsize'}.'" />'."\n".
+			    '<input type="hidden" name="kwstyle"  value="'.$ENV{'form.kwstyle'}.'" />'."\n".
+			    '<input type="hidden" name="msgsub"   value="'.$ENV{'form.msgsub'}.'" />'."\n".
+			    '<input type="hidden" name="shownSub" value="0" />'."\n".
+			    '<input type="hidden" name="savemsgN" value="'.$ENV{'form.savemsgN'}.'" />'."\n");
+	}
 	
 	my ($cts,$prnmsg) = (1,'');
 	while ($cts <= $ENV{'form.savemsgN'}) {
 	    $prnmsg.='<input type="hidden" name="savemsg'.$cts.'" value="'.
-		($keyhash{$symb.'_savemsg'.$cts} eq '' ? 
+		(!exists($keyhash{$symb.'_savemsg'.$cts}) ? 
 		 &Apache::lonfeedback::clear_out_html($ENV{'form.savemsg'.$cts}) :
 		 &Apache::lonfeedback::clear_out_html($keyhash{$symb.'_savemsg'.$cts})).
-		'" />'."\n";
+		'" />'."\n".
+		'<input type="hidden" name="shownOnce'.$cts.'" value="0" />'."\n";
 	    $cts++;
 	}
 	$request->print($prnmsg);
@@ -1274,7 +1315,7 @@ sub submission {
 #
 	    $request->print(<<KEYWORDS);
 &nbsp;<b>Keyword Options:</b>&nbsp;
-<a href="javascript:keywords(document.SCORE.keywords)"; TARGET=_self>List</a>&nbsp; &nbsp;
+<a href="javascript:keywords(document.SCORE)"; TARGET=_self>List</a>&nbsp; &nbsp;
 <a href="#" onMouseDown="javascript:getSel(); return false"
  CLASS="page">Paste Selection to List</a>&nbsp; &nbsp;
 <a href="javascript:kwhighlight()"; TARGET=_self>Highlight Attribute</a><br /><br />
@@ -1393,7 +1434,7 @@ KEYWORDS
 		    if (!exists($record{'resource.'.$partid.'.'.$respid.'.submission'})) {
 			$lastsubonly.='<tr><td bgcolor="#ffffe6"><b>Part '.
 			    $partid.'</b> <font color="#999999">( ID '.$respid.
-			    ' )</font>&nbsp; &nbsp;Nothing submitted<br /><br />';
+			    ' )</font>&nbsp; &nbsp;Nothing submitted - no attempts<br /><br />';
  		    } else {
 			foreach (@$string) {
 			    my ($partid,$respid) = /^resource\.(\w+)\.(\w+)\.submission/;
@@ -1420,7 +1461,8 @@ KEYWORDS
 				     'this file may contain virusses</font><br />':'').
 				     '<b>Submitted Answer: </b>'.($responsetype =~ /^(essay|option)$/ ? 
 								  '<blockquote>' : '').
-				     &cleanRecord(&keywords_highlight($subval),$responsetype).
+#				     &cleanRecord(&keywords_highlight($subval),$responsetype).
+				     &cleanRecord($subval,$responsetype,$symb).
 				     ($responsetype =~ /^(essay|option)$/ ? '</blockquote><br />' : 
 				      '<br /><br />').$similar."\n"
 				     if ($ENV{'form.lastSub'} eq 'lastonly' || 
@@ -1434,23 +1476,24 @@ KEYWORDS
 	    $lastsubonly.='</td></tr><tr bgcolor="#ffffff"><td>'."\n";
 	    $request->print($lastsubonly);
 	}
-    } else {
+    } elsif ($ENV{'form.lastSub'} eq 'datesub') {
+	my (undef,$responseType,undef,$parts) = &showResourceInfo($url);
+	$request->print(&displaySubByDates(\$symb,\%record,$parts,$responseType,$checkIcon));
+    } elsif ($ENV{'form.lastSub'} =~ /^(last|all)$/) {
 	$request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
 								 $ENV{'request.course.id'},
 								 $last,'.submission',
 								 'Apache::grades::keywords_highlight'));
     }
 
-    $result='<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n".
-	'<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".
-	'<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'
-	.$udom.'" />'."\n";
-    $request->print($result);
+    $request->print('<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'
+	.$udom.'" />'."\n");
     
     # return if view submission with no grading option
     if ($ENV{'form.showgrading'} eq '' || (!&canmodify($usec))) {
 	my $toGrade.='<input type="button" value="Grade Student" '.
-	    'onClick="javascript:gradeStudent(this.form,\''.$counter.'\');" TARGET=_self> &nbsp;'."\n";
+	    'onClick="javascript:checksubmit(this.form,\'Grade Student\',\''
+	    .$counter.'\');" TARGET=_self> &nbsp;'."\n" if (&canmodify($usec));
 	$toGrade.='</td></tr></table></td></tr></table></form>'."\n";
 	$toGrade.=&show_grading_menu_form($symb,$url) 
 	    if (($ENV{'form.command'} eq 'submission') || 
@@ -1459,7 +1502,7 @@ KEYWORDS
 	return;
     }
 
-    # essay grading options
+    # essay grading message center
     if ($ENV{'form.handgrade'} eq 'yes') {
 	my ($lastname,$givenn) = split(/,/,$ENV{'form.fullname'});
 	my $msgfor = $givenn.' '.$lastname;
@@ -1469,15 +1512,17 @@ KEYWORDS
 	}
 	$msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript
 #	$result.='<tr><td bgcolor="#ffffff">'."\n".
-	$result='&nbsp;<a href="javascript:msgCenter(document.SCORE,'.$counter.
+	$result='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".
+	    '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n";
+	$result.='&nbsp;<a href="javascript:msgCenter(document.SCORE,'.$counter.
 	    ',\''.$msgfor.'\')"; TARGET=_self>'.
 	    'Compose Message to student'.(scalar(@col_fullnames) >= 1 ? 's' : '').'</a> &nbsp;'.
 	    '<img src="'.$request->dir_config('lonIconsURL').
 	    '/mailbkgrd.gif" width="14" height="10" name="mailicon'.$counter.'" />'."\n".
 	    '<br />&nbsp;(Message will be sent when you click on Save & Next below.)'."\n" 
 	    if ($ENV{'form.handgrade'} eq 'yes');
+	$request->print($result);
     }
-    $request->print($result);
 
     my %seen = ();
     my @partlist;
@@ -1503,7 +1548,6 @@ KEYWORDS
     # print end of form
     if ($counter == $total) {
 	my $endform='<table border="0"><tr><td>'."\n";
-#	    '<input type="hidden" name="gradeOpt" value="" />'."\n";
 	$endform.='<input type="button" value="Save & Next" '.
 	    'onClick="javascript:checksubmit(this.form,\'Save & Next\','.
 	    $total.','.scalar(@partlist).');" TARGET=_self> &nbsp;'."\n";
@@ -1666,7 +1710,6 @@ sub processHandGrade {
 	     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
     }
     # Called by Save & Refresh from Highlight Attribute Window
-#    my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'0');
     my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'1');
     if ($ENV{'form.refresh'} eq 'on') {
 	my ($ctr,$total) = (0,0);
@@ -1686,8 +1729,9 @@ sub processHandGrade {
 	return '';
     }
 
-# Go directly to grade student - from submission page
+# Go directly to grade student - from submission or link from chart page
     if ($button eq 'Grade Student') {
+	(undef,undef,$ENV{'form.handgrade'},undef,undef) = &showResourceInfo($url);
 	my $processUser = $ENV{'form.unamedom'.$ENV{'form.studentNo'}};
 	($ENV{'form.student'},$ENV{'form.userdom'}) = split(/:/,$processUser);
 	$ENV{'form.fullname'} = $$fullname{$processUser};
@@ -1795,7 +1839,7 @@ sub saveHandGrade {
 	    }
 	    $newrecord{'resource.'.$_.'.submitted_by'} = $submitter 
 		if ($submitter && ($record{'resource.'.$_.'.submitted_by'} ne $submitter));
-	    $newrecord{'resource.'.$_.'regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
+	    $newrecord{'resource.'.$_.'.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
 	}
     }
 
@@ -2074,7 +2118,7 @@ sub viewgrades {
     my (@parts) = sort(&getpartlist($url));
     foreach my $part (@parts) {
 	my $display=&Apache::lonnet::metadata($url,$part.'.display');
-	next if ($display =~ /Number of Attempts/);
+	$display =~ s/^Number of Attempts/Tries/; # makes the column narrower
 	if  (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
 	if ($display =~ /^Partial Credit Factor/) {
 	    my ($partid) = &split_part_type($part);
@@ -2146,13 +2190,13 @@ sub viewstudentgrade {
 		if ($status eq 'excused');
 	    $result.=$optsel;
 	    $result.="</select></td>\n";
-#	} else {
-#	    $result.='<input type="hidden" name="'.
-#		'GD_'.$student.'_'.$part.'_'.$type.'_s" value="'.$score.'" />'.
-#		    "\n";
-#	    $result.='<td align="middle"><input type="text" name="'.
-#		'GD_'.$student.'_'.$part.'_'.$type.'" '.
-#		'value="'.$score.'" size="4" /></td>'."\n";
+	} else {
+	    $result.='<input type="hidden" name="'.
+		'GD_'.$student.'_'.$part.'_'.$type.'_s" value="'.$score.'" />'.
+		    "\n";
+	    $result.='<td align="middle"><input type="text" name="'.
+		'GD_'.$student.'_'.$part.'_'.$type.'" '.
+		'value="'.$score.'" size="4" /></td>'."\n";
 	}
     }
     $result.='</tr>';
@@ -2276,7 +2320,7 @@ sub editgrades {
 		my $awarded   = $ENV{'form.GD_'.$user.'_'.$part.'_'.$type};
 		if ($awarded ne '' && $awarded ne $old_aw) {
 		    $newrecord{'resource.'.$part.'.'.$type}= $awarded;
-		    $newrecord{'resource.'.$part.'regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
+		    $newrecord{'resource.'.$part.'.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
 		    $updateflag=1;
 		}
 		$line .= '<td align="center">'.$old_aw.'&nbsp;</td>'.
@@ -2405,7 +2449,7 @@ sub csvuploadmap_header {
 	$javascript=&csvupload_javascript_forward_associate();
     }
 
-    my ($result,$resptype,$hdgrade,$partlist,$handgrade) = &showResourceInfo($url,$ENV{'form.probTitle'});
+    my ($result) = &showResourceInfo($url,$ENV{'form.probTitle'});
 
     $request->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
@@ -2617,7 +2661,7 @@ sub csvuploadassign {
 #
 #-------------------------------------------------------------------
 #
-#-------------- Next few routines handles grading by page/sequence
+#-------------- Next few routines handle grading by page/sequence
 #
 #--- Select a page/sequence and a student to grade
 sub pickStudentPage {
@@ -2676,7 +2720,7 @@ LISTJAVASCRIPT
 
     $result.='&nbsp;<b>Submission Details: </b>'.
 	'<input type="radio" name="lastSub" value="none" /> none'."\n".
-	'<input type="radio" name="lastSub" value="datesub" checked /> dates and submissions'."\n".
+	'<input type="radio" name="lastSub" value="datesub" checked /> by dates and submissions'."\n".
 	'<input type="radio" name="lastSub" value="all" /> all details'."\n";
 
     $result.='<input type="hidden" name="section"     value="'.$getsec.'" />'."\n".
@@ -2837,7 +2881,7 @@ sub displayPage {
 		    foreach my $partid (@{$parts}) {
 			$responseType{$partid} = $curRes->responseType($partid);
 		    }
-		    $studentTable.= &displaySubByDates(\%record,$parts,\%responseType,$checkIcon);
+		    $studentTable.= &displaySubByDates(\$symbx,\%record,$parts,\%responseType,$checkIcon);
 		}
 	    } elsif ($ENV{'form.lastSub'} eq 'all') {
 		my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');
@@ -2872,7 +2916,7 @@ sub displayPage {
 }
 
 sub displaySubByDates {
-    my ($record,$parts,$responseType,$checkIcon) = @_;
+    my ($symbx,$record,$parts,$responseType,$checkIcon) = @_;
     my $studentTable='<table border="0" width="100%"><tr><td bgcolor="#777777">'.
 	'<table border="0" width="100%"><tr bgcolor="#e6ffff">'.
 	'<td><b>Date/Time</b></td>'.
@@ -2881,6 +2925,8 @@ sub displaySubByDates {
     my ($version);
     my %mark;
     $mark{'correct_by_student'} = $checkIcon;
+    return '<br />&nbsp;<font color="red">Nothing submitted - no attempts</font><br />' 
+	if (!exists($$record{'1:timestamp'}));
     for ($version=1;$version<=$$record{'version'};$version++) {
 	my $timestamp = scalar(localtime($$record{$version.':timestamp'}));
 	$studentTable.='<tr bgcolor="#ffffff" valign="top"><td>'.$timestamp.'</td>';
@@ -2888,17 +2934,16 @@ sub displaySubByDates {
 	my @displaySub = ();
 	foreach my $partid (@{$parts}) {
 	    my @matchKey = grep /^resource\.$partid\..*?\.submission$/,@versionKeys;
-	    next if ($$record{"$version:resource.$partid.solved"} eq '');
+#	    next if ($$record{"$version:resource.$partid.solved"} eq '');
 	    $displaySub[0].=(exists $$record{$version.':'.$matchKey[0]}) ? 
 		'<b>Part&nbsp;'.$partid.'&nbsp;'.
 		($$record{"$version:resource.$partid.tries"} eq '' ? 'Trial&nbsp;not&nbsp;counted' :
 		 'Trial&nbsp;'.$$record{"$version:resource.$partid.tries"}).'</b>&nbsp; '.
-		 &cleanRecord($$record{$version.':'.$matchKey[0]},$$responseType{$partid}).'<br />' : '';
+		 &cleanRecord($$record{$version.':'.$matchKey[0]},$$responseType{$partid},$$symbx).'<br />' : '';
 	    $displaySub[1].=(exists $$record{"$version:resource.$partid.award"}) ?
 		'<b>Part&nbsp;'.$partid.'</b> &nbsp;'.
 		lc($$record{"$version:resource.$partid.award"}).' '.
 		$mark{$$record{"$version:resource.$partid.solved"}}.'<br />' : '';
-#	    $$record{"$version:resource.$partid.solved"}.'<br />' : '';
 	    $displaySub[2].=(exists $$record{"$version:resource.$partid.regrader"}) ?
 		$$record{"$version:resource.$partid.regrader"}.' (<b>Part:</b> '.$partid.')' : '';
 	}
@@ -3413,7 +3458,7 @@ sub gradingmenu {
 GRADINGMENUJS
     &commonJSfunctions($request);
     my $result='<h3>&nbsp;<font color="#339933">Manual Grading/View Submission</font></h3>';
-    my ($table,$resptype,$hdgrade) = &showResourceInfo($url,$probTitle);
+    my ($table,undef,$hdgrade) = &showResourceInfo($url,$probTitle);
     $result.=$table;
     my (undef,$sections) = &getclasslist('all','0');
     my $savedState = &savedState();
@@ -3425,7 +3470,6 @@ GRADINGMENUJS
     $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n".
 	'<input type="hidden" name="symb"        value="'.$symb.'" />'."\n".
 	'<input type="hidden" name="url"         value="'.$url.'" />'."\n".
-	'<input type="hidden" name="response"    value="'.$resptype.'" />'."\n".
 	'<input type="hidden" name="handgrade"   value="'.$hdgrade.'" />'."\n".
 	'<input type="hidden" name="probTitle"   value="'.$probTitle.'" />'."\n".
 	'<input type="hidden" name="command"     value="" />'."\n".