--- loncom/homework/grades.pm 2010/04/20 23:29:22 1.628 +++ loncom/homework/grades.pm 2010/06/06 02:40:35 1.635 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.628 2010/04/20 23:29:22 www Exp $ +# $Id: grades.pm,v 1.635 2010/06/06 02:40:35 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -820,9 +820,7 @@ sub listStudents { $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'}; } - my $result='<h3><span class="LC_info"> ' - .&mt("View/Grade/Regrade Submissions for a Student or a Group of Students") - .'</span></h3>'; + my $result=''; my $res_error; my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error); @@ -1269,12 +1267,6 @@ sub sub_page_js { } } - if (val == "Grade Student") { - if (formname.Status.value == "") { - formname.Status.value = "Active"; - } - formname.studentNo.value = total; - } formname.submit(); } @@ -1323,7 +1315,8 @@ sub sub_page_kw_js { my $iconpath = $request->dir_config('lonIconsURL'); &commonJSfunctions($request); - my $inner_js_msg_central= &Apache::lonhtmlcommon::scripttag(<<INNERJS); + my $inner_js_msg_central= (<<INNERJS); +<script type="text/javascript"> function checkInput() { opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value); var nmsg = opener.document.SCORE.savemsgN.value; @@ -1360,9 +1353,11 @@ sub sub_page_kw_js { self.close() } +</script> INNERJS - my $inner_js_highlight_central= &Apache::lonhtmlcommon::scripttag(<<INNERJS); + my $inner_js_highlight_central= (<<INNERJS); +<script type="text/javascript"> function updateChoice(flag) { opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr); opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize); @@ -1373,6 +1368,7 @@ INNERJS } self.close() } +</script> INNERJS my $start_page_msg_central = @@ -1909,7 +1905,6 @@ sub submission { if ($counter == 0) { &sub_page_js($request); &sub_page_kw_js($request); - $request->print('<h3> <span class="LC_info">'.&mt('Submission Record').'</span></h3>'); # option to display problem, only once else it cause problems # with the form later since the problem has a form. @@ -2213,13 +2208,8 @@ KEYWORDS $request->print('<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':' .$udom.'" />'."\n"); # return if view submission with no grading option -# FIXME: the logic seems off here. Why show the grade button if you cannot grade? if (!&canmodify($usec)) { - my $toGrade.='<input type="button" value="Grade Student" '. - 'onclick="javascript:checksubmit(this.form,\'Grade Student\',\'' - .$counter.'\');" target="_self" /> '."\n" if (&canmodify($usec)); - $toGrade.='</div>'."\n"; - $request->print($toGrade); + $request->print('<p><span class="LC_warning">'.&mt('No grading privileges').'</span></p></div>'); return; } else { $request->print('</div>'."\n"); @@ -2337,10 +2327,10 @@ sub check_collaborators { next if ($record->{'resource.'.$part.'.collaborators'} eq ''); my (@good_collaborators, @bad_collaborators); foreach my $possible_collaborator - (split(/,?\s+/,$record->{'resource.'.$part.'.collaborators'})) { + (split(/[,;\s]+/,$record->{'resource.'.$part.'.collaborators'})) { $possible_collaborator =~ s/[\$\^\(\)]//g; next if ($possible_collaborator eq ''); - my ($co_name,$co_dom) = split(/\@|:/,$possible_collaborator); + my ($co_name,$co_dom) = split(/:/,$possible_collaborator); $co_dom = $udom if (! defined($co_dom) || $co_dom =~ /^domain$/i); next if ($co_name eq $uname && $co_dom eq $udom); # Doing this grep allows 'fuzzy' specification @@ -2353,13 +2343,13 @@ sub check_collaborators { } } if (scalar(@good_collaborators) != 0) { - $result.='<br />'.&mt('Collaborators: '); + $result.='<br />'.&mt('Collaborators:').'<ol>'; foreach my $name (@good_collaborators) { my ($lastname,$givenn) = split(/,/,$$fullname{$name}); push(@col_fullnames, $givenn.' '.$lastname); - $result.=$fullname->{$name}.' '; + $result.='<li>'.$fullname->{$name}.'</li>'; } - $result.='<br />'."\n"; + $result.='</ol><br />'."\n"; my ($part)=split(/\./,$part); $result.='<input type="hidden" name="collaborator'.$counter. '" value="'.$part.':'.(join ':',@good_collaborators).'" />'. @@ -2592,16 +2582,6 @@ sub processHandGrade { return ''; } -# Go directly to grade student - from submission or link from chart page -# FIXME: looks like reading off the button label! - if ($button eq 'Grade Student') { - my $processUser = $env{'form.unamedom'.$env{'form.studentNo'}}; - ($env{'form.student'},$env{'form.userdom'}) = split(/:/,$processUser); - $env{'form.fullname'} = $$fullname{$processUser}; - &submission($request,0,0,$symb); - return ''; - } - # Get the next/previous one or group of students my $firststu = $env{'form.unamedom0'}; my $laststu = $env{'form.unamedom'.($ngrade-1)}; @@ -2689,9 +2669,7 @@ sub processHandGrade { $ctr++; } if ($total < 0) { - my $the_end = '<h3><span class="LC_info">'.&mt('LON-CAPA User Message').'</span></h3><br />'."\n"; - $the_end.=&mt('<b>Message: </b> No more students for this section or class.').'<br /><br />'."\n"; - $the_end.=&mt('Click on the button below to return to the grading menu.').'<br /><br />'."\n"; + my $the_end.=&mt('<b>Message: </b> No more students for this section or class.').'<br /><br />'."\n"; $request->print($the_end); } return ''; @@ -3820,18 +3798,14 @@ sub csvuploadmap_header { $javascript=&csvupload_javascript_forward_associate(); } - my $result=''; $symb = &Apache::lonenc::check_encrypt($symb); + $request->print('<form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">'. + &mt('Total number of records found in file: [_1]',$distotal).'<hr />'. + &mt('Associate entries from the uploaded file with as many fields as you can.')); + my $reverse=&mt("Reverse Association"); $request->print(<<ENDPICK); -<form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload"> -<h3><span class="LC_info">Uploading Class Grades</span></h3> -$result -<hr /> -<h3>Identify fields</h3> -Total number of records found in file: $distotal <hr /> -Enter as many fields as you can. The system will inform you and bring you back -to this page if the data selected is insufficient to run your class.<hr /> -<input type="button" value="Reverse Association" onclick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" /> +<br /> +<input type="button" value="$reverse" onclick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" /> <input type="hidden" name="associate" value="" /> <input type="hidden" name="phase" value="three" /> <input type="hidden" name="datatoken" value="$datatoken" /> @@ -3887,7 +3861,7 @@ ENDPICK } sub checkforfile_js { - my $alertmsg = &mt('Please use the browse button to select a file from your local directory.'); + my $alertmsg = &mt('Please use the "Choose File" button to select a file from your local directory.'); my $result = &Apache::lonhtmlcommon::scripttag(<<CSVFORMJS); function checkUpload(formname) { if (formname.upfile.value == "") { @@ -3904,11 +3878,11 @@ sub upcsvScores_form { my ($request,$symb) = @_; if (!$symb) {return '';} my $result=&checkforfile_js(); - $result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n"; - $result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n"; - $result.=' <b>'.&mt('Specify a file containing the class scores for current resource.'). - '</b></td></tr>'."\n"; - $result.='<tr bgcolor=#ffffe6><td>'."\n"; + $result.=&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + '<th>'.&mt('Specify a file containing the class scores for current resource.').'</th>'. + &Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row().'<td>'; my $upload=&mt("Upload Scores"); my $upfile_select=&Apache::loncommon::upfile_select_html(); my $ignore=&mt('Ignore First Line'); @@ -3922,9 +3896,10 @@ $upfile_select </form> ENDUPFORM $result.=&Apache::loncommon::help_open_topic("Course_Convert_To_CSV", - &mt("How do I create a CSV file from a spreadsheet")) - .'</td></tr></table>'."\n"; - $result.='</td></tr></table><br /><br />'."\n"; + &mt("How do I create a CSV file from a spreadsheet")). + '</td>'. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); return $result; } @@ -3976,29 +3951,21 @@ sub csvuploadmap { sub csvuploadoptions { my ($request,$symb)= @_; + my $overwrite=&mt('Overwrite any existing score'); $request->print(<<ENDPICK); <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload"> -<h3><span class="LC_info">Uploading Class Grade Options</span></h3> <input type="hidden" name="command" value="csvuploadassign" /> -<!-- -<p> -<label> - <input type="checkbox" name="show_full_results" /> - Show a table of all changes -</label> -</p> ---> <p> <label> <input type="checkbox" name="overwite_scores" checked="checked" /> - Overwrite any existing score + $overwrite </label> </p> ENDPICK my %fields=&get_fields(); if (!defined($fields{'domain'})) { my $domform = &Apache::loncommon::select_dom_form($env{'request.role.domain'},'default_domain'); - $request->print("\n<p> Users are in domain: ".$domform."</p>\n"); + $request->print("\n<p>".&mt('Users are in domain: [_1]',$domform)."</p>\n"); } foreach my $key (sort(keys(%env))) { if ($key !~ /^form\.(.*)$/) { next; } @@ -4038,7 +4005,6 @@ sub csvuploadassign { &Apache::loncommon::load_tmp_file($request); my @gradedata = &Apache::loncommon::upfile_record_sep(); my %fields=&get_fields(); - $request->print('<h3>Assigning Grades</h3>'); my $courseid=$env{'request.course.id'}; my ($classlist) = &getclasslist('all',0); my @notallowed; @@ -8497,11 +8463,7 @@ sub submit_options_sequence { $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n"; - $result.=' -<h2> - '.&mt('Grade page/folder for one student').' -</h2>'. - &selectfield(0). + $result.=&selectfield(0). '<input type="hidden" name="command" value="pickStudentPage" /> <div> <input type="submit" value="'.&mt('Next').' →" /> @@ -8520,11 +8482,7 @@ sub submit_options_table { $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n"; - $result.=' -<h2> - '.&mt('Grading table').' -</h2>'. - &selectfield(0). + $result.=&selectfield(0). '<input type="hidden" name="command" value="viewgrades" /> <div> <input type="submit" value="'.&mt('Next').' →" /> @@ -8566,10 +8524,7 @@ sub submit_options { $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n"; - $result.=' -<h2> - '.&mt('Select individual students to grade').' -</h2>'.&selectfield(1).' + $result.=&selectfield(1).' <input type="hidden" name="command" value="submission" /> <input type="submit" value="'.&mt('Next').' →" /> </div> @@ -8582,6 +8537,14 @@ sub submit_options { sub selectfield { my ($full)=@_; + my %options = + (&Apache::lonlocal::texthash( + 'yes' => 'with submissions', + 'queued' => 'in grading queue', + 'graded' => 'with ungraded submissions', + 'incorrect' => 'with incorrect submissions', + 'all' => 'with any status'), + 'select_form_order' => ['yes','queued','graded','incorrect','all']); my $result='<div class="LC_columnSection"> <fieldset> @@ -8610,14 +8573,7 @@ sub selectfield { <legend> '.&mt('Submission Status').' </legend>'. - &Apache::loncommon::select_form('all','submitonly', - (&Apache::lonlocal::texthash( - 'yes' => 'with submissions', - 'queued' => 'in grading queue', - 'graded' => 'with ungraded submissions', - 'incorrect' => 'with incorrect submissions', - 'all' => 'with any status'), - 'select_form_order' => ['yes','queued','graded','incorrect','all'])). + &Apache::loncommon::select_form('all','submitonly',\%options). '</fieldset>'; } $result.='</div><br />'; @@ -8711,11 +8667,11 @@ sub process_clicker { my ($r,$symb)=@_; if (!$symb) {return '';} my $result=&checkforfile_js(); - $result.='<br /><table width="100%" border="0"><tr><td bgcolor="#777777">'."\n"; - $result.='<table width="100%" border="0"><tr bgcolor="#e6ffff"><td>'."\n"; - $result.=' <b>'.&mt('Specify a file containing the clicker information for this resource.'). - '</b></td></tr>'."\n"; - $result.='<tr bgcolor="#ffffe6"><td>'."\n"; + $result.=&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + '<th>'.&mt('Specify a file containing clicker information and set grading options.').'</th>'. + &Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row()."<td>\n"; # Attempt to restore parameters from last session, set defaults if not present my %Saveable_Parameters=&clicker_grading_parameters(); &Apache::loncommon::restore_course_settings('grades_clicker', @@ -8732,7 +8688,7 @@ sub process_clicker { } } - my $upload=&mt("Upload File"); + my $upload=&mt("Evaluate File"); my $type=&mt("Type"); my $attendance=&mt("Award points just for participation"); my $personnel=&mt("Correctness determined from response by course personnel"); @@ -8742,8 +8698,8 @@ sub process_clicker { my $pcorrect=&mt("Percentage points for correct solution"); my $pincorrect=&mt("Percentage points for incorrect solution"); my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype', - ('iclicker' => 'i>clicker', - 'interwrite' => 'interwrite PRS')); + {'iclicker' => 'i>clicker', + 'interwrite' => 'interwrite PRS'}); $symb = &Apache::lonenc::check_encrypt($symb); $result.= &Apache::lonhtmlcommon::scripttag(<<ENDUPFORM); function sanitycheck() { @@ -8790,7 +8746,10 @@ ENDUPFORM <input type="hidden" name="command" value="processclickerfile" /> <input type="file" name="upfile" size="50" /> <br /><label>$type: $selectform</label> -<br /><label><input type="radio" name="gradingmechanism" value="attendance"$checked{'attendance'} onclick="sanitycheck()" />$attendance </label> +ENDUPFORM + $result.='</td>'.&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::start_data_table_row().'<td>'.(<<ENDGRADINGFORM); + <label><input type="radio" name="gradingmechanism" value="attendance"$checked{'attendance'} onclick="sanitycheck()" />$attendance </label> <br /><label><input type="radio" name="gradingmechanism" value="personnel"$checked{'personnel'} onclick="sanitycheck()" />$personnel</label> <br /><label><input type="radio" name="gradingmechanism" value="specific"$checked{'specific'} onclick="sanitycheck()" />$specific </label> <input type="text" name="specificid" value="$env{'form.specificid'}" size="20" /> @@ -8798,13 +8757,17 @@ ENDUPFORM <br /> <input type="text" name="givenanswer" size="50" /> <input type="hidden" name="waschecked" value="$env{'form.gradingmechanism'}" /> -<br /><label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onchange="sanitycheck()" /></label> +ENDGRADINGFORM + $result.='</td>'.&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::start_data_table_row().'<td>'.(<<ENDPERCFORM); + <label>$pcorrect: <input type="text" name="pcorrect" size="4" value="$env{'form.pcorrect'}" onchange="sanitycheck()" /></label> <br /><label>$pincorrect: <input type="text" name="pincorrect" size="4" value="$env{'form.pincorrect'}" onchange="sanitycheck()" /></label> <br /><input type="button" onclick="javascript:checkUpload(this.form);" value="$upload" /> </form>' -ENDUPFORM - $result.='</td></tr></table>'."\n". - '</td></tr></table><br /><br />'."\n"; +ENDPERCFORM + $result.='</td>'. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); return $result; } @@ -8884,11 +8847,12 @@ sub process_clicker_file { $result.=&Apache::loncommon::studentbrowser_javascript(); $symb = &Apache::lonenc::check_encrypt($symb); - my $heading=&mt('Scanning clicker file'); - $result.=(<<ENDHEADER); -<br /><table width="100%" border="0"><tr><td bgcolor="#777777"> -<table width="100%" border="0"><tr bgcolor="#e6ffff"><td> -<b>$heading</b></td></tr><tr bgcolor=#ffffe6><td> + $result.=&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + '<th>'.&mt('Evaluate clicker file').'</th>'. + &Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row().(<<ENDHEADER); +<td> <form method="post" action="/adm/grades" name="clickeranalysis"> <input type="hidden" name="symb" value="$symb" /> <input type="hidden" name="command" value="assignclickergrades" /> @@ -8936,7 +8900,9 @@ ENDHEADER } elsif ($clicker_ids{$id}) { 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.="</td>".&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::start_data_table_row()."<td>". + &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}))) { @@ -8950,7 +8916,9 @@ ENDHEADER $student_count++; } } else { - $result.="\n<hr />".&mt('Unregistered Clicker')." <tt>".$id."</tt><br />"; + $result.="</td>".&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::start_data_table_row()."<td>". + &mt('Unregistered Clicker')." <tt>".$id."</tt><br />"; $result.="\n".'<input type="hidden" name="unknown:'.$id.'" value="'.$responses{$id}.'" />'. "\n".&mt("Username").": <input type='text' name='uname".$id."' /> ". "\n".&mt("Domain").": ". @@ -8976,8 +8944,9 @@ ENDHEADER } else { $result.='<br /><input type="submit" name="finalize" value="'.&mt('Finalize Grading').'" />'; } - $result.='</form></td></tr></table>'."\n". - '</td></tr></table><br /><br />'."\n"; + $result.='</form></td>'. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); return $result; } @@ -9051,14 +9020,11 @@ sub assign_clicker_grades { # FIXME: This should probably look for the first handgradeable part my $part=$$partlist[0]; # Start screen output - my $result=''; - - my $heading=&mt('Assigning grades based on clicker file'); - $result.=(<<ENDHEADER); -<br /><table width="100%" border="0"><tr><td bgcolor="#777777"> -<table width="100%" border="0"><tr bgcolor="#e6ffff"><td> -<b>$heading</b></td></tr><tr bgcolor=#ffffe6><td> -ENDHEADER + my $result=&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + '<th>'.&mt('Assigning grades based on clicker file').'</th>'. + &Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row().'<td>'; # Get correct result # FIXME: Possibly need delimiter other than ":" my @correct=(); @@ -9093,6 +9059,7 @@ ENDHEADER my $pcorrect=$env{'form.pcorrect'}; my $pincorrect=$env{'form.pincorrect'}; my $storecount=0; + my %users=(); foreach my $key (keys(%env)) { my $user=''; if ($key=~/^form\.student\:(.*)$/) { @@ -9106,7 +9073,13 @@ ENDHEADER $user=$env{'form.multi'.$id}; } } - if ($user) { + if ($user) { + if ($users{$user}) { + $result.='<br /><span class="LC_warning">'. + &mt("More than one entry found for <tt>[_1]</tt>!",$user). + '</span><br />'; + } + $users{$user}=1; my @answer=split(/\,/,$env{$key}); my $sum=0; my $realnumber=$number; @@ -9146,8 +9119,9 @@ ENDHEADER } # We are done $result.='<br />'.&mt('Successfully stored grades for [quant,_1,student].',$storecount). - '</td></tr></table>'."\n". - '</td></tr></table><br /><br />'."\n"; + '</td>'. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); return $result; } @@ -9163,6 +9137,7 @@ sub startpage { unshift(@$crumbs,{href=>&href_symb_cmd($symb,'gradingmenu'),text=>"Grading"}); $r->print(&Apache::loncommon::start_page('Grading',undef, {'bread_crumbs' => $crumbs})); + $r->print('<h3>'.$$crumbs[-1]{'text'}.'</h3>'); unless ($nodisplayflag) { $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag)); } @@ -9170,7 +9145,7 @@ sub startpage { sub select_problem { my ($r)=@_; - $r->print('<h2>'.&mt('Select the problem or one of the problems you want to grade').'</h2><form action="/adm/grades">'); + $r->print('<h3>'.&mt('Select the problem or one of the problems you want to grade').'</h3><form action="/adm/grades">'); $r->print(&Apache::lonstathelpers::problem_selector('.',undef,1)); $r->print('<input type="hidden" name="command" value="gradingmenu" />'); $r->print('<input type="submit" value="'.&mt('Next').' →" /></form>');