--- loncom/homework/grades.pm 2003/06/21 00:39:46 1.106 +++ loncom/homework/grades.pm 2003/07/14 14:29:07 1.113 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.106 2003/06/21 00:39:46 albertel Exp $ +# $Id: grades.pm,v 1.113 2003/07/14 14:29:07 ng Exp $ # # Copyright Michigan State University Board of Trustees # @@ -41,6 +41,7 @@ use Apache::style; use Apache::lonxml; use Apache::lonnet; use Apache::loncommon; +use Apache::lonhtmlcommon; use Apache::lonnavmaps; use Apache::lonhomework; use Apache::loncoursedata; @@ -129,8 +130,8 @@ sub getclasslist { my (undef,undef,$end,$start,$id,$section,$fullname,$status)= @{$classlist->{$_}}; # filter students according to status selected - if ($filterlist && $ENV{'form.status'} ne 'Any') { - if ($ENV{'form.status'} ne $status) { + if ($filterlist && $ENV{'form.Status'} ne 'Any') { + if ($ENV{'form.Status'} ne $status) { delete ($classlist->{$_}); next; } @@ -367,28 +368,47 @@ sub listStudents { $request->print(<<LISTJAVASCRIPT); <script type="text/javascript" language="javascript"> - function checkSelect(checkBox) { - var ctr=0; - var sense=""; - if (checkBox.length > 1) { - for (var i=0; i<checkBox.length; i++) { - if (checkBox[i].checked) { - ctr++; - } - } - sense = "a student or group of students"; - } else { - if (checkBox.checked) { - ctr = 1; - } - sense = "the student"; + function checkSelect(checkBox) { + var ctr=0; + var sense=""; + if (checkBox.length > 1) { + for (var i=0; i<checkBox.length; i++) { + if (checkBox[i].checked) { + ctr++; + } + } + sense = "a student or group of students"; + } else { + if (checkBox.checked) { + ctr = 1; + } + sense = "the student"; + } + if (ctr == 0) { + alert("Please select "+sense+" before clicking on the $viewgrade button."); + return false; + } + document.gradesub.submit(); } - if (ctr == 0) { - alert("Please select "+sense+" before clicking on the $viewgrade button."); - return false; + + function reLoadList(formname) { + if (formname.saveStatusOld.value == pullDownSelection(formname.Status)) {return;} + formname.command.value = 'submission'; + formname.submit(); + } + + function pullDownSelection(selectOne) { + var selection=""; + if (selectOne.length > 1) { + for (var i=0; i<selectOne.length; i++) { + if (selectOne[i].selected) { + return selectOne[i].value; + } + } + } else { + if (selectOne.selected) return selectOne.value; + } } - document.gradesub.submit(); - } </script> LISTJAVASCRIPT @@ -405,6 +425,10 @@ LISTJAVASCRIPT if ($ENV{'form.handgrade'} eq 'yes') { $gradeTable.='<input type="radio" name="lastSub" value="hdgrade" '.$checkhdgrade.' /> handgrade only'."\n"; } + + my $saveStatus = $ENV{'form.Status'} eq '' ? 'Active' : $ENV{'form.Status'}; + $ENV{'form.Status'} = $saveStatus; + $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="all" /> all details'."\n". @@ -417,58 +441,82 @@ LISTJAVASCRIPT '<input type="hidden" name="probTitle" value="'.$ENV{'form.probTitle'}.'" />'."\n". '<input type="hidden" name="url" value="'.$url.'" />'."\n". '<input type="hidden" name="symb" value="'.$symb.'" />'."\n". - 'To '.lc($viewgrade).' a submission, click on the check box next to the student\'s name. Then '."\n". + '<input type="hidden" name="saveStatusOld" value="'.$saveStatus.'" />'."\n"; + + $gradeTable.='<b>Student Status:</b> '. + &Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,'javascript:reLoadList(this.form);').'<br />'; + + $gradeTable.='To '.lc($viewgrade).' a submission, click on the check box next to the student\'s name. Then '."\n". 'click on the '.$viewgrade.' button. To view the submissions for a group of students, click'."\n". ' on the check boxes for the group of students.<br />'."\n". - '<input type="hidden" name="command" value="processGroup" />'."\n". - '<input type="button" '."\n". + '<input type="hidden" name="command" value="processGroup" />'."\n"; + $gradeTable.='<input type="button" '."\n". 'onClick="javascript:checkSelect(this.form.stuinfo);" '."\n". 'value="'.$viewgrade.'" />'."\n"; - - my (undef,undef,$fullname) = &getclasslist($getsec,$ENV{'form.showgrading'} eq 'yes' ? '1' : '0'); - + + my (undef, undef, $fullname) = &getclasslist($getsec,'1'); $gradeTable.='<table border="0"><tr><td bgcolor="#777777">'. - '<table border="0"><tr bgcolor="#e6ffff">'. - '<td><b> Select </b></td><td><b> Fullname </b></td>'. - '<td><b> Username </b></td><td><b> Domain </b></td>'; - foreach (sort(@$partlist)) { - $gradeTable.='<td><b> Part '.(split(/_/))[0].' Status </b></td>'; + '<table border="0"><tr bgcolor="#e6ffff">'; + my $loop = 0; + while ($loop < 2) { + $gradeTable.='<td><b> Select </b></td><td><b> Fullname </b>'. + '<font color="#999999">(Username)</font> </td>'; + if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { + foreach (sort(@$partlist)) { + $gradeTable.='<td><b> Part '.(split(/_/))[0].' Status </b></td>'; + } + } + $loop++; } $gradeTable.='</tr>'."\n"; my $ctr = 0; foreach my $student (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) { my ($uname,$udom) = split(/:/,$student); - my (%status) =&student_gradeStatus($url,$symb,$udom,$uname,$partlist); - my $statusflg = ''; - foreach (keys(%status)) { - $statusflg = 1 if ($status{$_} ne 'nothing'); - my ($foo,$partid,$foo1) = split(/\./,$_); - if ($status{'resource.'.$partid.'.submitted_by'} ne '') { - $statusflg = ''; - $gradeTable.='<input type="hidden" name="'. - $student.':submitted_by" value="'. - $status{'resource.'.$partid.'.submitted_by'}.'" />'; + my %status = (); + if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { + (%status) =&student_gradeStatus($url,$symb,$udom,$uname,$partlist); + my $statusflg = ''; + foreach (keys(%status)) { + $statusflg = 1 if ($status{$_} ne 'nothing'); + my ($foo,$partid,$foo1) = split(/\./,$_); + if ($status{'resource.'.$partid.'.submitted_by'} ne '') { + $statusflg = ''; + $gradeTable.='<input type="hidden" name="'. + $student.':submitted_by" value="'. + $status{'resource.'.$partid.'.submitted_by'}.'" />'; + } } + next if ($statusflg eq '' && $submitonly eq 'yes'); } - next if ($statusflg eq '' && $submitonly eq 'yes'); $ctr++; if ( $perm{'vgr'} eq 'F' ) { - $gradeTable.='<tr bgcolor="#ffffe6">'. - '<td align="center"><input type=checkbox name="stuinfo" value="'. - $student.':'.$$fullname{$student}.'"></td>'."\n". - '<td> '.$$fullname{$student}.' </td>'."\n". - '<td> '.$uname.' </td>'."\n". - '<td align="middle"> '.$udom.' </td>'."\n"; - - foreach (sort keys(%status)) { - next if (/^resource.*?submitted_by$/); - $gradeTable.='<td align="middle"> '.$status{$_}.' </td>'."\n"; + $gradeTable.='<tr bgcolor="#ffffe6">' if ($ctr%2 ==1); + $gradeTable.='<td align="center"><input type=checkbox name="stuinfo" value="'. + $student.':'.$$fullname{$student}.' "></td>'."\n". + '<td> '.$$fullname{$student}.' '."\n". + '<font color="#999999">('.$uname.')</font></td>'."\n"; + + if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { + foreach (sort keys(%status)) { + next if (/^resource.*?submitted_by$/); + $gradeTable.='<td align="middle"> '.$status{$_}.' </td>'."\n"; + } } - $gradeTable.='</tr>'."\n"; + $gradeTable.='</tr>'."\n" if ($ctr%2 ==0); } } + if ($ctr%2 ==1) { + $gradeTable.='<td> </td><td> </td>'; + if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { + foreach (@$partlist) { + $gradeTable.='<td> </td>'; + } + } + $gradeTable.='</tr>'; + } + $gradeTable.='</table></td></tr></table>'. '<input type="button" '. 'onClick="javascript:checkSelect(this.form.stuinfo);" '. @@ -479,7 +527,8 @@ LISTJAVASCRIPT $gradeTable='<br /> <font color="red">There are no students currently enrolled.</font>'; } else { $gradeTable='<br /> <font color="red">'. - 'No submissions found for this resource for any students. ('.$num_students.' checked for submissions</font><br />'; + 'No submissions found for this resource for any students. ('.$num_students. + ' checked for submissions</font><br />'; } } elsif ($ctr == 1) { $gradeTable =~ s/type=checkbox/type=checkbox checked/; @@ -1264,7 +1313,7 @@ KEYWORDS } else { for my $part (sort keys(%$handgrade)) { foreach (@$string) { - my ($partid,$respid) = /^resource\.(\d+)\.(\d+)\.submission/; + my ($partid,$respid) = /^resource\.(\w+)\.(\w+)\.submission/; if ($part eq ($partid.'_'.$respid)) { my ($ressub,$subval) = split(/:/,$_,2); # Similarity check @@ -1322,7 +1371,7 @@ KEYWORDS my $lastone = pop @col_fullnames; $msgfor .= ', '.(join ', ',@col_fullnames).' and '.$lastone.'.'; } - $msgfor =~ s/\'/\\'/g; #' stupid emacs + $msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript $result.='<tr><td bgcolor="#ffffff">'."\n". ' <a href="javascript:msgCenter(document.SCORE,'.$counter. ',\''.$msgfor.'\')"; TARGET=_self>'. @@ -1673,8 +1722,8 @@ sub viewgrades_js { var textbox = eval("document.classgrade.TEXTVAL_"+partid); if (point == "textval") { var point = eval("document.classgrade.TEXTVAL_"+partid+".value"); - if (isNaN(point) || point < 0) { - alert("A number equal or greater than 0 is expected. Entered value = "+point); + if (isNaN(point) || parseFloat(point) < 0) { + alert("A number equal or greater than 0 is expected. Entered value = "+parseFloat(point)); var resetbox = false; for (var i=0; i<radioButton.length; i++) { if (radioButton[i].checked) { @@ -1687,8 +1736,8 @@ sub viewgrades_js { } return; } - if (point > weight) { - var resp = confirm("You entered a value ("+point+ + if (parseFloat(point) > parseFloat(weight)) { + var resp = confirm("You entered a value ("+parseFloat(point)+ ") greater than the weight for the part. Accept?"); if (resp == false) { textbox.value = ""; @@ -1697,7 +1746,7 @@ sub viewgrades_js { } for (var i=0; i<radioButton.length; i++) { radioButton[i].checked=false; - if (point == i) { + if (parseFloat(point) == i) { radioButton[i].checked=true; } } @@ -1771,13 +1820,13 @@ sub viewgrades_js { var point = textbox.value; var weight = eval("document.classgrade.weight_"+partid+".value"); - if (isNaN(point) || point < 0) { - alert("A number equal or greater than 0 is expected. Entered value = "+point); + if (isNaN(point) || parseFloat(point) < 0) { + alert("A number equal or greater than 0 is expected. Entered value = "+parseFloat(point)); textbox.value = ""; return; } - if (point > weight) { - var resp = confirm("You entered a value ("+point+ + if (parseFloat(point) > parseFloat(weight)) { + var resp = confirm("You entered a value ("+parseFloat(point)+ ") greater than the weight of the part. Accept?"); if (resp == false) { textbox.value = ""; @@ -1908,9 +1957,9 @@ sub viewgrades { $result.='</table>'.'</td></tr></table>'.'</td></tr></table>'."\n". '<input type="hidden" name="totalparts" value="'.$ctsparts.'" />'; $result.='<input type="button" value="Reset" '. - 'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self> '; - $result.='<input type="button" value="Submit Changes" '. - 'onClick="javascript:submit();" TARGET=_self />'."\n"; + 'onClick="javascript:resetEntry('.$ctsparts.');" TARGET=_self>'; +# $result.=' <input type="button" value="Submit Changes" name="subButton1'. +# 'onClick="javascript:submit();" TARGET=_self />'."\n"; #table listing all the students in a section/class #header of table @@ -1924,7 +1973,7 @@ sub viewgrades { } $result.= '<table border=0><tr><td bgcolor="#777777">'."\n". '<table border=0><tr bgcolor="#deffff">'. - '<td><b>Fullname</b></td><td><b>Username</b></td><td><b>Domain</b></td>'."\n"; + '<td><b>Fullname</b> <font color="#999999">(Username)</font></td>'."\n"; my (@parts) = sort(&getpartlist($url)); foreach my $part (@parts) { my $display=&Apache::lonnet::metadata($url,$part.'.display'); @@ -1958,7 +2007,7 @@ sub viewgrades { 'onClick="javascript:submit();" TARGET=_self /></form>'."\n"; if (scalar(%$fullname) eq 0) { my $colspan=3+scalar(@parts); - $result='<font color="red">There are no students in section "'.$ENV{'form.section'}.'" with enrollment status "'.$ENV{'form.status'}.'" to modify or grade.</font>'; + $result='<font color="red">There are no students in section "'.$ENV{'form.section'}.'" with enrollment status "'.$ENV{'form.Status'}.'" to modify or grade.</font>'; } $result.=&show_grading_menu_form($symb,$url); return $result; @@ -1972,8 +2021,8 @@ sub viewstudentgrade { my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname); my $result='<tr bgcolor="#ffffdd"><td>'. '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom. - '\')"; TARGET=_self>'.$fullname.'</a>'. - '</td><td>'.$uname.'</td><td align="middle">'.$udom.'</td>'."\n"; + '\')"; TARGET=_self>'.$fullname.'</a> '. + '<font color="#999999">('.$uname.($ENV{'user.domain'} eq $udom ? '' : ':'.$udom).')</font></td>'."\n"; foreach my $apart (@$parts) { my ($part,$type) = &split_part_type($apart); my $score=$record{"resource.$part.$type"}; @@ -2083,7 +2132,7 @@ sub editgrades { $line .= '<tr bgcolor="#ffffde"><td>'.$uname.' </td><td>'. $udom.' </td><td>'. $$fullname{$usercolon}.' </td>'; - my $usec=%$classlist->{"$uname:$udom"}[5]; + my $usec=$classlist->{"$uname:$udom"}[5]; if (!&canmodify($usec)) { my $numcols=scalar(@partid)*(scalar(@parts)-1)*2; $noupdate.=$line."<td colspan=\"$numcols\"><font color=\"red\">Not allowed to modify student</font></td></tr>"; @@ -2440,7 +2489,7 @@ sub csvuploadassign { push(@skipped,"$username:$domain"); next; } - my $usec=%$classlist->{"$username:$domain"}[5]; + my $usec=$classlist->{"$username:$domain"}[5]; if (!&canmodify($usec)) { push(@notallowed,"$username:$domain"); next; @@ -2567,7 +2616,7 @@ LISTJAVASCRIPT '<input type="radio" name="lastSub" value="all" /> all details'."\n"; $result.='<input type="hidden" name="section" value="'.$getsec.'" />'."\n". - '<input type="hidden" name="status" value="'.$ENV{'form.status'}.'" />'."\n". + '<input type="hidden" name="Status" value="'.$ENV{'form.Status'}.'" />'."\n". '<input type="hidden" name="command" value="displayPage" />'."\n". '<input type="hidden" name="url" value="'.$url.'" />'."\n". '<input type="hidden" name="symb" value="'.$symb.'" />'."\n". @@ -2614,21 +2663,21 @@ sub getSymbMap { my $navmap = Apache::lonnavmaps::navmap-> new($ENV{'request.course.fn'}.'.db', $ENV{'request.course.fn'}.'_parms.db',1, 1); - my $res = $navmap->firstResource(); # temp resource to access constants + #my $res = $navmap->firstResource(); # temp resource to access constants $navmap->init(); # End navmap using boilerplate - my $iterator = $navmap->getIterator(undef, undef, undef, 1); + my $iterator = Apache::lonnavmaps::iterator->new($navmap, undef, undef, undef, 1, undef, 1); my $depth = 1; - $iterator->next(); # ignore first BEGIN_MAP my $curRes = $iterator->next(); my %symbx = (); my @titles = (); my $minder=0; - while ($depth > 0) { - if ($curRes == $iterator->BEGIN_MAP()) {$depth++;} + my $seenBeginMap = 0; + while ($depth > 0 && !$seenBeginMap) { + if ($curRes == $iterator->BEGIN_MAP()) {$depth++; $seenBeginMap = 1; } if ($curRes == $iterator->END_MAP()) { $depth--; } if (ref($curRes) && $curRes->is_map()) { @@ -3290,7 +3339,7 @@ sub gradingmenu { function checkChoice(formname) { var cmd = formname.command; formname.saveState.value = "saveCmd="+radioSelection(cmd)+":saveSec="+pullDownSelection(formname.section)+ - ":saveSub="+radioSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.status); + ":saveSub="+radioSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.Status); if (cmd[0].checked || cmd[1].checked || cmd[2].checked || cmd[3].checked || cmd[4].checked) formname.submit(); if (cmd[5].checked) { if (!checkReceiptNo(formname,'notOK')) { return false;} @@ -3428,12 +3477,7 @@ GRADINGMENUJS } $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="on"' : ''). '>all</select> '; - $result.='Student Status:</b><select name="status">'. - '<option value="Active" '.($saveStatus eq 'Active' ? 'selected' : '').'>Active</option>'. - '<option value="Expired" '.($saveStatus eq 'Expired' ? 'selected' : '').'>Expired</option>'. - '<option value="Any" '.($saveStatus eq 'Any' ? 'selected' : '').'>Any</option>'. - '</select>'; - + $result.='Student Status:</b>'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef); $result.=' <font color="red">(Applies to the first three options only.)</font>'."\n"; if (ref($sections)) {