--- loncom/homework/grades.pm 2007/08/10 20:12:31 1.427 +++ loncom/homework/grades.pm 2007/10/08 21:05:54 1.445 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.427 2007/08/10 20:12:31 albertel Exp $ +# $Id: grades.pm,v 1.445 2007/10/08 21:05:54 banghart Exp $ # # Copyright Michigan State University Board of Trustees # @@ -45,35 +45,26 @@ use LONCAPA; use POSIX qw(floor); + my %perm=(); +my %bubble_lines_per_response; # no. bubble lines for each response. + # index is "symb.part_id" + # ----- These first few routines are general use routines.---- # # --- Retrieve the parts from the metadata file.--- sub getpartlist { my ($symb) = @_; - my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb); - my $partorder = &Apache::lonnet::metadata($url, 'partorder'); - my @parts; - if ($partorder) { - for my $part (split (/,/,$partorder)) { - if (!&Apache::loncommon::check_if_partid_hidden($part,$symb)) { - push(@parts, $part); - } - } - } else { - my $metadata = &Apache::lonnet::metadata($url, 'packages'); - foreach (split(/\,/,$metadata)) { - if ($_ =~ /^part_(.*)$/) { - if (!&Apache::loncommon::check_if_partid_hidden($1,$symb)) { - push(@parts, $1); - } - } - } - } + + my $navmap = Apache::lonnavmaps::navmap->new(); + my $res = $navmap->getBySymb($symb); + my $partlist = $res->parts(); + my $url = $res->src(); + my @metakeys = split(/,/,&Apache::lonnet::metadata($url,'keys')); + my @stores; - foreach my $part (@parts) { - my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys')); + foreach my $part (@{ $partlist }) { foreach my $key (@metakeys) { if ($key =~ m/^stores_\Q$part\E_/) { push(@stores,$key); } } @@ -194,22 +185,54 @@ sub showResourceInfo { return $result,$responseType,$hdgrade,$partlist,$handgrade; } +sub reset_caches { + &reset_analyze_cache(); + &reset_perm(); +} + +{ + my %analyze_cache; -sub get_order { - my ($partid,$respid,$symb,$uname,$udom)=@_; - my (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); - $url=&Apache::lonnet::clutter($url); - my $subresult=&Apache::lonnet::ssi($url, - ('grade_target' => 'analyze'), - ('grade_domain' => $udom), - ('grade_symb' => $symb), - ('grade_courseid' => - $env{'request.course.id'}), - ('grade_username' => $uname)); - (undef,$subresult)=split(/_HASH_REF__/,$subresult,2); - my %analyze=&Apache::lonnet::str2hash($subresult); - return ($analyze{"$partid.$respid.shown"}); + sub reset_analyze_cache { + undef(%analyze_cache); + } + + sub get_analyze { + my ($symb,$uname,$udom)=@_; + my $key = "$symb\0$uname\0$udom"; + return $analyze_cache{$key} if (exists($analyze_cache{$key})); + + my (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); + $url=&Apache::lonnet::clutter($url); + my $subresult=&Apache::lonnet::ssi($url, + ('grade_target' => 'analyze'), + ('grade_domain' => $udom), + ('grade_symb' => $symb), + ('grade_courseid' => + $env{'request.course.id'}), + ('grade_username' => $uname)); + (undef,$subresult)=split(/_HASH_REF__/,$subresult,2); + my %analyze=&Apache::lonnet::str2hash($subresult); + return $analyze_cache{$key} = \%analyze; + } + + sub get_order { + my ($partid,$respid,$symb,$uname,$udom)=@_; + my $analyze = &get_analyze($symb,$uname,$udom); + return $analyze->{"$partid.$respid.shown"}; + } + + sub get_radiobutton_correct_foil { + my ($partid,$respid,$symb,$uname,$udom)=@_; + my $analyze = &get_analyze($symb,$uname,$udom); + foreach my $foil (@{&get_order($partid,$respid,$symb,$uname,$udom)}) { + if ($analyze->{"$partid.$respid.foil.value.$foil"} eq 'true') { + return $foil; + } + } + } } + #--- Clean response type for display #--- Currently filters option/rank/radiobutton/match/essay/Task # response types only. @@ -258,11 +281,11 @@ sub cleanRecord { } elsif ($response eq 'radiobutton') { my %answer=&Apache::lonnet::str2hash($answer); my ($toprow,$bottomrow); - my $correct=($order->[0])+1; - for (my $i=1;$i<=$#$order;$i++) { - my $foil=$order->[$i]; + my $correct = + &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom); + foreach my $foil (@$order) { if (exists($answer{$foil})) { - if ($i == $correct) { + if ($foil eq $correct) { $toprow.='<td><b>true</b></td>'; } else { $toprow.='<td><i>true</i></td>'; @@ -326,7 +349,10 @@ sub cleanRecord { $result.='</ul>'; return $result; } - + } elsif ( $response =~ m/(?:numerical|formula)/) { + $answer = + &Apache::loncommon::format_previous_attempt_value('submission', + $answer); } return $answer; } @@ -372,6 +398,7 @@ COMMONJSFUNCTIONS sub getclasslist { my ($getsec,$filterlist) = @_; my @getsec; + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); if (!ref($getsec)) { if ($getsec ne '' && $getsec ne 'all') { @getsec=($getsec); @@ -401,8 +428,8 @@ sub getclasslist { my $status = $classlist->{$student}->[&Apache::loncoursedata::CL_STATUS()]; # filter students according to status selected - if ($filterlist && $env{'form.Status'} ne 'Any') { - if ($env{'form.Status'} ne $status) { + if ($filterlist && (!($stu_status =~ /Any/))) { + if (!($stu_status =~ $status)) { delete ($classlist->{$student}); next; } @@ -484,6 +511,7 @@ sub student_gradeStatus { # Shows a student's view of problem and submission sub jscriptNform { my ($symb) = @_; + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); my $jscript='<script type="text/javascript" language="javascript">'."\n". ' function viewOneStudent(user,domain) {'."\n". ' document.onestudent.student.value = user;'."\n". @@ -495,7 +523,7 @@ sub jscriptNform { '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n". '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n". '<input type="hidden" name="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n". - '<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n". + '<input type="hidden" name="Status" value="'.$stu_status.'" />'."\n". '<input type="hidden" name="command" value="submission" />'."\n". '<input type="hidden" name="student" value="" />'."\n". '<input type="hidden" name="userdom" value="" />'."\n". @@ -720,10 +748,9 @@ LISTJAVASCRIPT if ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1) { $gradeTable.='<label><input type="radio" name="lastSub" value="hdgrade" '.$checkhdgrade.' /> essay part only </label>'."\n"; } - - my $saveStatus = $env{'form.Status'} eq '' ? 'Active' : $env{'form.Status'}; + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); + my $saveStatus = $stu_status eq '' ? 'Active' : $stu_status; $env{'form.Status'} = $saveStatus; - $gradeTable.='<label><input type="radio" name="lastSub" value="lastonly" '.$checklastsub.' /> last submission only </label>'."\n". '<label><input type="radio" name="lastSub" value="last" /> last submission & parts info </label>'."\n". '<label><input type="radio" name="lastSub" value="datesub" /> by dates and submissions </label>'."\n". @@ -734,8 +761,7 @@ LISTJAVASCRIPT '<option value=".25">Quarter Points</option>'. '<option value=".1">Tenths of a Point</option>'. '</select>'. - - '<input type="hidden" name="section" value="'.$getsec.'" />'."\n". + &build_section_inputs(). '<input type="hidden" name="submitonly" value="'.$submitonly.'" />'."\n". '<input type="hidden" name="handgrade" value="'.$env{'form.handgrade'}.'" /><br />'."\n". '<input type="hidden" name="showgrading" value="'.$env{'form.showgrading'}.'" /><br />'."\n". @@ -745,7 +771,7 @@ LISTJAVASCRIPT '<input type="hidden" name="saveStatusOld" value="'.$saveStatus.'" />'."\n"; if (exists($env{'form.gradingMenu'}) && exists($env{'form.Status'})) { - $gradeTable.='<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n"; + $gradeTable.='<input type="hidden" name="Status" value="'.$stu_status.'" />'."\n"; } else { $gradeTable.='<b>Student Status:</b> '. &Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,'javascript:reLoadList(this.form);').'<br />'; @@ -1661,6 +1687,19 @@ sub download_all_link { return } +sub build_section_inputs { + my $section_inputs; + if ($env{'form.section'} eq '') { + $section_inputs .= '<input type="hidden" name="section" value="all" />'."\n"; + } else { + my @sections = &Apache::loncommon::get_env_multiple('form.section'); + foreach my $section (@sections) { + $section_inputs .= '<input type="hidden" name="section" value="'.$section.'" />'."\n"; + } + } + return $section_inputs; +} + # --------------------------- show submissions of a student, option to grade sub submission { my ($request,$counter,$total) = @_; @@ -1669,7 +1708,6 @@ sub submission { $udom = ($udom eq '' ? $env{'user.domain'} : $udom); #has form.userdom changed for a student? my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'}); $env{'form.fullname'} = &Apache::loncommon::plainname($uname,$udom,'lastname') if $env{'form.fullname'} eq ''; - my $symb = &get_symb($request); if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; } @@ -1722,7 +1760,7 @@ sub submission { &Apache::lonxml::clear_problem_counter(); $request->print(&show_problem($request,$symb,$uname,$udom,0,1,$mode)); } - + # kwclr is the only variable that is guaranteed to be non blank # if this subroutine has been called once. my %keyhash = (); @@ -1741,11 +1779,11 @@ sub submission { $env{'form.savemsgN'} = $keyhash{$symb.'_savemsgN'} ne '' ? $keyhash{$symb.'_savemsgN'} : '0'; } my $overRideScore = $env{'form.overRideScore'} eq '' ? 'no' : $env{'form.overRideScore'}; - + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); $request->print('<form action="/adm/grades" method="post" name="SCORE" enctype="multipart/form-data">'."\n". '<input type="hidden" name="command" value="handgrade" />'."\n". '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n". - '<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n". + '<input type="hidden" name="Status" value="'.$stu_status.'" />'."\n". '<input type="hidden" name="overRideScore" value="'.$overRideScore.'" />'."\n". '<input type="hidden" name="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n". '<input type="hidden" name="refresh" value="off" />'."\n". @@ -1756,7 +1794,7 @@ sub submission { '<input type="hidden" name="vProb" value="'.$env{'form.vProb'}.'" />'."\n". '<input type="hidden" name="vAns" value="'.$env{'form.vAns'}.'" />'."\n". '<input type="hidden" name="lastSub" value="'.$env{'form.lastSub'}.'" />'."\n". - '<input type="hidden" name="section" value="'.$env{'form.section'}.'" />'."\n". + &build_section_inputs(). '<input type="hidden" name="submitonly" value="'.$env{'form.submitonly'}.'" />'."\n". '<input type="hidden" name="handgrade" value="'.$env{'form.handgrade'}.'" />'."\n". '<input type="hidden" name="NCT"'. @@ -1808,8 +1846,13 @@ KEYWORDS } } +# This is where output for one specific student would start + my $bgcolor='#DDEEDD'; + if (int($counter/2) eq $counter) { $bgcolor='#DDDDEE'; } + $request->print("\n\n". + '<p><table border="2"><tr><th bgcolor="'.$bgcolor.'">'.$env{'form.fullname'}.'</th></tr><tr><td bgcolor="'.$bgcolor.'">'); + if ($env{'form.vProb'} eq 'all' or $env{'form.vAns'} eq 'all') { - $request->print('<br /><br /><br />') if ($counter > 0); my $mode; if ($env{'form.vProb'} eq 'all' && $env{'form.vAns'} eq 'all') { $mode='both'; @@ -2079,6 +2122,11 @@ KEYWORDS } $request->print($result.'</td></tr></table></td></tr></table>'."\n"); +# Done with printing info for one student + + $request->print('</td></tr></table></p>'); + + # print end of form if ($counter == $total) { my $endform='<table border="0"><tr><td>'."\n"; @@ -2962,23 +3010,25 @@ sub viewgrades { $result.=&jscriptNform($symb); #beginning of class grading form + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); $result.= '<form action="/adm/grades" method="post" name="classgrade">'."\n". '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n". '<input type="hidden" name="command" value="editgrades" />'."\n". - '<input type="hidden" name="section" value="'.$env{'form.section'}.'" />'."\n". + &build_section_inputs(). '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."\n". - '<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n". + '<input type="hidden" name="Status" value="'.$env{'stu_status'}.'" />'."\n". '<input type="hidden" name="probTitle" value="'.$env{'form.probTitle'}.'" />'."\n"; my $sectionClass; + my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section')); if ($env{'form.section'} eq 'all') { $sectionClass='Class </h3>'; } elsif ($env{'form.section'} eq 'none') { - $sectionClass='Students in no Section </h3>'; + $sectionClass=&mt('Students in no Section').'</h3>'; } else { - $sectionClass='Students in Section '.$env{'form.section'}.'</h3>'; + $sectionClass=&mt('Students in Section(s) [_1]',$section_display).'</h3>'; } - $result.='<h3>Assign Common Grade To '.$sectionClass; + $result.='<h3>'.&mt('Assign Common Grade To [_1]',$sectionClass); $result.= '<table border=0><tr><td bgcolor="#777777">'."\n". '<table border=0><tr bgcolor="#ffffdd"><td>'; #radio buttons/text box for assigning points for a section or class. @@ -3084,8 +3134,12 @@ sub viewgrades { 'onClick="javascript:submit();" target="_self" /></form>'."\n"; if (scalar(%$fullname) eq 0) { my $colspan=3+scalar(@parts); - $result='<span class="LC_warning">There are no students in section "'.$env{'form.section'}. - '" with enrollment status "'.$env{'form.Status'}.'" to modify or grade.</span>'; + my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section')); + my $stu_status = join(' or ',&Apache::loncommon::get_env_multiple('form.Status')); + $result='<span class="LC_warning">'. + &mt('There are no students in section(s) [_1] with enrollment status [_2] to modify or grade', + $section_display, $stu_status). + '</span>'; } $result.=&show_grading_menu_form($symb); return $result; @@ -3162,9 +3216,10 @@ sub editgrades { my ($request) = @_; my $symb=&get_symb($request); - my $title='<h3><span class="LC_info">Current Grade Status</span></h3>'; - $title.='<h4><b>Current Resource: </b>'.$env{'form.probTitle'}.'</h4><br />'."\n"; - $title.='<h4><b>Section: </b>'.$env{'form.section'}.'</h4>'."\n"; + my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section')); + my $title='<h3><span class="LC_info">'.&mt('Current Grade Status').'</span></h3>'; + $title.='<h4>'.&mt('<b>Current Resource: </b>[_1]',$env{'form.probTitle'}).'</h4><br />'."\n"; + $title.='<h4>'.&mt('<b>Section: </b>[_1]',$section_display).'</h4>'."\n"; my $result= '<table border="0"><tr><td bgcolor="#777777">'."\n"; $result.= '<table border="0"><tr bgcolor="#deffff">'. @@ -3362,7 +3417,7 @@ sub split_part_type { my ($partstr) = @_; my ($temp,@allparts)=split(/_/,$partstr); my $type=pop(@allparts); - my $part=join('.',@allparts); + my $part=join('_',@allparts); return ($part,$type); } @@ -3865,9 +3920,10 @@ LISTJAVASCRIPT '<label><input type="radio" name="lastSub" value="none" /> none</label>'."\n". '<label><input type="radio" name="lastSub" value="datesub" checked="checked" /> by dates and submissions</label>'."\n". '<label><input type="radio" name="lastSub" value="all" /> all details</label>'."\n"; - - $result.='<input type="hidden" name="section" value="'.$getsec.'" />'."\n". - '<input type="hidden" name="Status" value="'.$env{'form.Status'}.'" />'."\n". + + $result.=&build_section_inputs(); + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); + $result.='<input type="hidden" name="Status" value="'.$stu_status.'" />'."\n". '<input type="hidden" name="command" value="displayPage" />'."\n". '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n". '<input type="hidden" name="saveState" value="'.$env{'form.saveState'}.'" />'."<br />\n"; @@ -4381,7 +4437,7 @@ one of the predefined configurations for like. Next each scanline is checked for any errors of either 'missing -bubbles' (it's an error because it may have been missed scanned +bubbles' (it's an error because it may have been mis-scanned because too light bubbling), 'double bubble' (each bubble line should have no more that one letter picked), invalid or duplicated CODE, invalid student ID @@ -4392,7 +4448,7 @@ username:domain. During the validation phase the instructor can choose to skip scanlines. -After the validation phase, there is now 3 bubble sheet files +After the validation phase, there are now 3 bubble sheet files scantron_original_filename (unmodified original file) scantron_corrected_filename (file where the corrected information has replaced the original information) @@ -6462,6 +6518,7 @@ sub scantron_validate_doublebubble { =cut sub scantron_get_maxbubble { + if (defined($env{'form.scantron_maxbubble'}) && $env{'form.scantron_maxbubble'}) { return $env{'form.scantron_maxbubble'}; @@ -6476,14 +6533,40 @@ sub scantron_get_maxbubble { &Apache::lonxml::clear_problem_counter(); + my $uname = $env{'form.student'}; + my $udom = $env{'form.userdom'}; + my $cid = $env{'request.course.id'}; + my $total_lines = 0; + %bubble_lines_per_response = (); + foreach my $resource (@resources) { + my $symb = $resource->symb(); my $result=&Apache::lonnet::ssi($resource->src(), - ('symb' => $resource->symb())); + ('symb' => $resource->symb()), + ('grade_target' => 'analyze'), + ('grade_courseid' => $cid), + ('grade_domain' => $udom), + ('grade_username' => $uname)); + my (undef, $an) = + split(/_HASH_REF__/,$result, 2); + + my %analysis = &Apache::lonnet::str2hash($an); + + + + foreach my $part_id (@{$analysis{'parts'}}) { + my $bubble_lines = $analysis{"$part_id.bubble_lines"}[0]; + if (!$bubble_lines) { + $bubble_lines = 1; + } + $bubble_lines_per_response{"$symb.$part_id"} = $bubble_lines; + $total_lines = $total_lines + $bubble_lines; + } + } &Apache::lonnet::delenv('scantron\.'); $env{'form.scantron_maxbubble'} = - &Apache::lonxml::get_problem_counter()-1; - + $total_lines; return $env{'form.scantron_maxbubble'}; } @@ -6862,8 +6945,198 @@ sub savedState { return \%savedState; } -#--- Displays the main menu page ------- -sub gradingmenu { +sub grading_menu { + my ($request) = @_; + my ($symb)=&get_symb($request); + if (!$symb) {return '';} + my $probTitle = &Apache::lonnet::gettitle($symb); + my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle); + + # + # Define menu data + $env{'form.probTitle'} = &Apache::lonnet::gettitle($symb); + my ($table) = &showResourceInfo($symb,$env{'form.probTitle'}); + $request->print($table); + my %fields = ('symb'=>&Apache::lonenc::check_encrypt($symb), + 'handgrade'=>$hdgrade, + 'probTitle'=>$probTitle, + 'command'=>'submit_options', + 'saveState'=>"", + 'gradingMenu'=>1, + 'showgrading'=>"yes"); + my $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + my @menu = ({ url => $url, + name => &mt('Manual Grading/View Submissions'), + short_description => + &mt('Start the process of hand grading submissions.'), + }); + $fields{'command'} = 'csvform'; + $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + push (@menu, { url => $url, + name => &mt('Upload Scores'), + short_description => + &mt('Specify a file containing the class scores for current resource.')}); + $fields{'command'} = 'processclicker'; + $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + push (@menu, { url => $url, + name => &mt('Process Clicker'), + short_description => + &mt('Specify a file containing the clicker information for this resource.')}); + $fields{'command'} = 'scantron_selectphase'; + $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + push (@menu, { url => $url, + name => &mt('Grade Scantron Forms'), + short_description => + &mt('')}); + $fields{'command'} = 'verify'; + $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + push (@menu, { url => "", + jscript => ' onClick="javascript:checkChoice2(document.forms.gradingMenu,\'5\',\'verify\')" ', + name => &mt('Verify Receipt'), + short_description => + &mt('')}); + $fields{'command'} = 'manage'; + $url = &Apache::lonhtmlcommon::build_url('/adm/helper/resettimes.helper',\%fields); + push (@menu, { url => $url, + name => &mt('Manage Access Times'), + short_description => + &mt('')}); + $fields{'command'} = 'view'; + $url = &Apache::lonhtmlcommon::build_url('/adm/pickcode',\%fields); + push (@menu, { url => $url, + name => &mt('View Saved CODEs'), + short_description => + &mt('')}); + + # + # Create the menu + my $Str; + # $Str .= '<h2>'.&mt('Please select a grading task').'</h2>'; + $Str .= '<form method="post" action="" name="gradingMenu">'; + $Str .= '<input type="hidden" name="command" value="" />'. + '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n". + '<input type="hidden" name="handgrade" value="'.$hdgrade.'" />'."\n". + '<input type="hidden" name="probTitle" value="'.$probTitle.'" ue="" />'."\n". + '<input type="hidden" name="saveState" value="" />'."\n". + '<input type="hidden" name="gradingMenu" value="1" />'."\n". + '<input type="hidden" name="showgrading" value="yes" />'."\n"; + + foreach my $menudata (@menu) { + if ($menudata->{'name'} ne &mt('Verify Receipt')) { + $Str .=' <h3><a '. + $menudata->{'jscript'}. + ' href="'. + $menudata->{'url'}.'" >'. + $menudata->{'name'}."</a></h3>\n"; + } else { + $Str .=' <h3><a '. + $menudata->{'jscript'}. + ' nohref="nohref" >'. + $menudata->{'name'}."</a></h3>\n"; + $Str .= ' receipt: '.&Apache::lonnet::recprefix($env{'request.course.id'}). + '-<input type="text" name="receipt" size="4" onChange="javascript:checkReceiptNo(this.form,\'OK\')" />'; + } + $Str .= ' '.(' 'x8).$menudata->{'short_description'}. + "\n"; + } + $Str .="</dl>\n"; + $Str .="</form>\n"; + $request->print(<<GRADINGMENUJS); +<script type="text/javascript" language="javascript"> + function checkChoice(formname,val,cmdx) { + if (val <= 2) { + var cmd = radioSelection(formname.radioChoice); + var cmdsave = cmd; + } else { + cmd = cmdx; + cmdsave = 'submission'; + } + formname.command.value = cmd; + formname.saveState.value = "saveCmd="+cmdsave+":saveSec="+pullDownSelection(formname.section)+ + ":saveSub="+pullDownSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.Status); + if (val < 5) formname.submit(); + if (val == 5) { + if (!checkReceiptNo(formname,'notOK')) { return false;} + formname.submit(); + } + if (val < 7) formname.submit(); + } + function checkChoice2(formname,val,cmdx) { + if (val <= 2) { + var cmd = radioSelection(formname.radioChoice); + var cmdsave = cmd; + } else { + cmd = cmdx; + cmdsave = 'submission'; + } + formname.command.value = cmd; + if (val < 5) formname.submit(); + if (val == 5) { + if (!checkReceiptNo(formname,'notOK')) { return false;} + formname.submit(); + } + if (val < 7) formname.submit(); + } + + function checkReceiptNo(formname,nospace) { + var receiptNo = formname.receipt.value; + var checkOpt = false; + if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;} + if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;} + if (checkOpt) { + alert("Please enter a receipt number given by a student in the receipt box."); + formname.receipt.value = ""; + formname.receipt.focus(); + return false; + } + return true; + } +</script> +GRADINGMENUJS + &commonJSfunctions($request); + my $result='<h3> <span class="LC_info">Manual Grading/View Submission</span></h3>'; + $result.=$table; + my (undef,$sections) = &getclasslist('all','0'); + my $savedState = &savedState(); + my $saveCmd = ($$savedState{'saveCmd'} eq '' ? 'submission' : $$savedState{'saveCmd'}); + my $saveSec = ($$savedState{'saveSec'} eq '' ? 'all' : $$savedState{'saveSec'}); + my $saveSub = ($$savedState{'saveSub'} eq '' ? 'all' : $$savedState{'saveSub'}); + my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'}); + + $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". + '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n". + '<input type="hidden" name="handgrade" value="'.$hdgrade.'" />'."\n". + '<input type="hidden" name="probTitle" value="'.$probTitle.'" ue="" />'."\n". + '<input type="hidden" name="saveState" value="" />'."\n". + '<input type="hidden" name="gradingMenu" value="1" />'."\n". + '<input type="hidden" name="showgrading" value="yes" />'."\n"; + + $result.='<table width="100%" border="0"><tr><td bgcolor=#777777>'."\n". + '<table width="100%" border="0"><tr bgcolor="#e6ffff"><td colspan="2">'."\n". + ' <b>Select a Grading/Viewing Option</b></td></tr>'."\n". + '<tr bgcolor="#ffffe6" valign="top"><td>'."\n"; + + $result.='<table width="100%" border="0">'; + $result.='<tr bgcolor="#ffffe6" valign="top">'."\n"; + $result.='<td><b>'.&mt('Sections').'</b></td>'; +# $result.='<td>Groups</td>'; + $result.='<td><b>'.&mt('Access Status').'</td>'."\n"; + $result.='</tr>'; + $result.='<tr bgcolor="#ffffe6" valign="top"><td>'."\n". + ' <select name="section" multiple="multiple" size="3">'."\n"; + if (ref($sections)) { + foreach (sort (@$sections)) { + $result.='<option value="'.$_.'" '. + ($saveSec eq $_ ? 'selected="selected"':'').'>'.$_.'</option>'."\n"; + } + } + $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="selected"' : ''). '>all</option></select> '; + return $Str; +} + + +#--- Displays the submissions first page ------- +sub submit_options { my ($request) = @_; my ($symb)=&get_symb($request); if (!$symb) {return '';} @@ -6931,8 +7204,13 @@ GRADINGMENUJS '<tr bgcolor="#ffffe6" valign="top"><td>'."\n"; $result.='<table width="100%" border="0">'; + $result.='<tr bgcolor="#ffffe6" valign="top">'."\n"; + $result.='<td><b>'.&mt('Sections').'</b></td>'; +# $result.='<td>Groups</td>'; + $result.='<td><b>'.&mt('Access Status').'</td>'."\n"; + $result.='</tr>'; $result.='<tr bgcolor="#ffffe6" valign="top"><td>'."\n". - ' '.&mt('Select Section').': <select name="section">'."\n"; + ' <select name="section" multiple="multiple" size="3">'."\n"; if (ref($sections)) { foreach (sort (@$sections)) { $result.='<option value="'.$_.'" '. @@ -6940,12 +7218,14 @@ GRADINGMENUJS } } $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="selected"' : ''). '>all</option></select> '; - - $result.=&mt('Student Status').':'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef); +# $result.= '</td><td>'."\n"; +# $result.='Put group select here'."\n"; + $result.='</td><td>'."\n"; + $result.=&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,3,undef,'mult'); $result.='</td></tr>'; - $result.='<tr bgcolor="#ffffe6"valign="top"><td><label>'. + $result.='<tr bgcolor="#ffffe6"valign="top"><td colspan="3"><label>'. '<input type="radio" name="radioChoice" value="submission" '. ($saveCmd eq 'submission' ? 'checked="checked"' : '').' /> '.'<b>'.&mt('Current Resource').':</b> '.&mt('For one or more students'). '</label> <select name="submitonly">'. @@ -6960,17 +7240,17 @@ GRADINGMENUJS '<option value="all" '. ($saveSub eq 'all' ? 'selected="selected"' : '').'>'.&mt('with any status').'</option></select></td></tr>'."\n"; - $result.='<tr bgcolor="#ffffe6"valign="top"><td>'. + $result.='<tr bgcolor="#ffffe6"valign="top"><td colspan="2">'. '<label><input type="radio" name="radioChoice" value="viewgrades" '. ($saveCmd eq 'viewgrades' ? 'checked="checked"' : '').' /> '. '<b>Current Resource:</b> For all students in selected section or course</label></td></tr>'."\n"; - $result.='<tr bgcolor="#ffffe6" valign="top"><td>'. + $result.='<tr bgcolor="#ffffe6" valign="top"><td colspan="2">'. '<label><input type="radio" name="radioChoice" value="pickStudentPage" '. ($saveCmd eq 'pickStudentPage' ? 'checked="checked"' : '').' /> '. 'The <b>complete</b> set/page/sequence: For one student</label></td></tr>'."\n"; - $result.='<tr bgcolor="#ffffe6"><td><br />'. + $result.='<tr bgcolor="#ffffe6"><td colspan="2"><br />'. '<input type="button" onClick="javascript:checkChoice(this.form,\'2\');" value="Next->" />'. '</td></tr></table>'."\n"; @@ -7040,9 +7320,10 @@ sub gather_clicker_ids { # Set up a couple variables. my $username_idx = &Apache::loncoursedata::CL_SNAME(); my $domain_idx = &Apache::loncoursedata::CL_SDOM(); + my $status_idx = &Apache::loncoursedata::CL_STATUS(); foreach my $student (keys(%$classlist)) { - + if ($classlist->{$student}->[$status_idx] ne 'Active') { next; } my $username = $classlist->{$student}->[$username_idx]; my $domain = $classlist->{$student}->[$domain_idx]; my $clickers = @@ -7284,6 +7565,8 @@ ENDHEADER } $result.='<br />'.&mt('Found [_1] question(s)',$number).'<br />'. '<input type="hidden" name="number" value="'.$number.'" />'. + &mt('Awarding [_1] percent for corrion(s)',$number).'<br />'. + '<input type="hidden" name="number" value="'.$number.'" />'. &mt('Awarding [_1] percent for correct and [_2] percent for incorrect responses', $env{'form.pcorrect'},$env{'form.pincorrect'}). '<br />'; @@ -7303,8 +7586,21 @@ ENDHEADER $result.="\n".'<input type="hidden" name="correct:'.$correct_count.':'.$correct_ids{$id}.'" value="'.$responses{$id}.'" />'; $correct_count++; } elsif ($clicker_ids{$id}) { - $result.="\n".'<input type="hidden" name="student:'.$clicker_ids{$id}.'" value="'.$responses{$id}.'" />'; - $student_count++; + if ($clicker_ids{$id}=~/\,/) { +# More than one user with the same clicker! + $result.="\n<hr />".&mt('Clicker registered more than once').": <tt>".$id."</tt><br />"; + $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'. + "<select name='multi".$id."'>"; + foreach my $reguser (sort(split(/\,/,$clicker_ids{$id}))) { + $result.="<option value='".$reguser."'>".&Apache::loncommon::plainname(split(/\:/,$reguser)).' ('.$reguser.')</option>'; + } + $result.='</select>'; + $unknown_count++; + } else { +# Good: found one and only one user with the right clicker + $result.="\n".'<input type="hidden" name="student:'.$clicker_ids{$id}.'" value="'.$responses{$id}.'" />'; + $student_count++; + } } else { $result.="\n<hr />".&mt('Unregistered Clicker')." <tt>".$id."</tt><br />"; $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'. @@ -7324,6 +7620,9 @@ ENDHEADER $result.='<br /><span class="LC_warning">'.&mt("Found [_1] entries for grading!",$correct_count).'</span>'; } } + if ($number<1) { + $errormsg.="Found no questions."; + } if ($errormsg) { $result.='<br /><span class="LC_error">'.&mt($errormsg).'</span>'; } else { @@ -7452,6 +7751,8 @@ ENDHEADER my $id=$1; if (($env{'form.uname'.$id}) && ($env{'form.udom'.$id})) { $user=$env{'form.uname'.$id}.':'.$env{'form.udom'.$id}; + } elsif ($env{'form.multi'.$id}) { + $user=$env{'form.multi'.$id}; } } if ($user) { @@ -7497,7 +7798,7 @@ ENDHEADER sub handler { my $request=$_[0]; - &reset_perm(); + &reset_caches(); if ($env{'browser.mathml'}) { &Apache::loncommon::content_type($request,'text/xml'); } else { @@ -7506,6 +7807,7 @@ sub handler { $request->send_http_header; return '' if $request->header_only; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); + &Apache::lonnet::logthis("receipt is ".$env{'form.receipt'}); my $symb=&get_symb($request,1); my @commands=&Apache::loncommon::get_env_multiple('form.command'); my $command=$commands[0]; @@ -7552,7 +7854,9 @@ sub handler { } elsif ($command eq 'processGroup' && $perm{'vgr'}) { &processGroup($request); } elsif ($command eq 'gradingmenu' && $perm{'vgr'}) { - $request->print(&gradingmenu($request)); + $request->print(&grading_menu($request)); + } elsif ($command eq 'submit_options' && $perm{'vgr'}) { + $request->print(&submit_options($request)); } elsif ($command eq 'viewgrades' && $perm{'vgr'}) { $request->print(&viewgrades($request)); } elsif ($command eq 'handgrade' && $perm{'mgr'}) { @@ -7610,6 +7914,7 @@ sub handler { } } $request->print(&Apache::loncommon::end_page()); + &reset_caches(); return ''; }