--- loncom/homework/grades.pm 2015/03/18 12:53:24 1.735 +++ loncom/homework/grades.pm 2017/07/02 16:50:30 1.741 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.735 2015/03/18 12:53:24 raeburn Exp $ +# $Id: grades.pm,v 1.741 2017/07/02 16:50:30 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -293,7 +293,7 @@ sub reset_caches { } sub scantron_partids_tograde { - my ($resource,$cid,$uname,$udom,$check_for_randomlist,$bubbles_per_row) = @_; + my ($resource,$cid,$uname,$udom,$check_for_randomlist,$bubbles_per_row,$scancode) = @_; my (%analysis,@parts); if (ref($resource)) { my $symb = $resource->symb(); @@ -301,6 +301,13 @@ sub reset_caches { if ($check_for_randomlist) { $add_to_form = { 'check_parts_withrandomlist' => 1,}; } + if ($scancode) { + if (ref($add_to_form) eq 'HASH') { + $add_to_form->{'code_for_randomlist'} = $scancode; + } else { + $add_to_form = { 'code_for_randomlist' => $scancode,}; + } + } my $analyze = &get_analyze($symb,$uname,$udom,undef,$add_to_form, undef,undef,undef,$bubbles_per_row); @@ -857,10 +864,11 @@ sub listStudents { my $res_error; my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error); - my %lt = &Apache::lonlocal::texthash ( + my %js_lt = &Apache::lonlocal::texthash ( 'multiple' => 'Please select a student or group of students before clicking on the Next button.', 'single' => 'Please select the student before clicking on the Next button.', ); + &js_escape(\%js_lt); $request->print(&Apache::lonhtmlcommon::scripttag(<<LISTJAVASCRIPT)); function checkSelect(checkBox) { var ctr=0; @@ -871,12 +879,12 @@ sub listStudents { ctr++; } } - sense = '$lt{'multiple'}'; + sense = '$js_lt{'multiple'}'; } else { if (checkBox.checked) { ctr = 1; } - sense = '$lt{'single'}'; + sense = '$js_lt{'single'}'; } if (ctr == 0) { alert(sense); @@ -1177,7 +1185,8 @@ sub processGroup { #--- Javascript to handle the submission page functionality --- sub sub_page_js { my $request = shift; - my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = '); + my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = '); + &js_escape(\$alertmsg); $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT)); function updateRadio(formname,id,weight) { var gradeBox = formname["GD_BOX"+id]; @@ -1422,10 +1431,21 @@ INNERJS my $docopen=&Apache::lonhtmlcommon::javascript_docopen(); $docopen=~s/^document\.//; - my %lt = &Apache::lonlocal::texthash( + my %js_lt = &Apache::lonlocal::texthash( keyw => 'Keywords list, separated by a space. Add/delete to list if desired.', plse => 'Please select a word or group of words from document and then click this link.', adds => 'Add selection to keyword list? Edit if desired.', + col1 => 'red', + col2 => 'green', + col3 => 'blue', + siz1 => 'normal', + siz2 => '+1', + siz3 => '+2', + sty1 => 'normal', + sty2 => 'italic', + sty3 => 'bold', + ); + my %html_js_lt = &Apache::lonlocal::texthash( comp => 'Compose Message for: ', incl => 'Include', type => 'Type', @@ -1438,21 +1458,15 @@ INNERJS txtc => 'Text Color', font => 'Font Size', fnst => 'Font Style', - col1 => 'red', - col2 => 'green', - col3 => 'blue', - siz1 => 'normal', - siz2 => '+1', - siz3 => '+2', - sty1 => 'normal', - sty2 => 'italic', - sty3 => 'bold', ); + &js_escape(\%js_lt); + &html_escape(\%html_js_lt); + &js_escape(\%html_js_lt); $request->print(&Apache::lonhtmlcommon::scripttag(<<SUBJAVASCRIPT)); //===================== Show list of keywords ==================== function keywords(formname) { - var nret = prompt("$lt{'keyw'}",formname.keywords.value); + var nret = prompt("$js_lt{'keyw'}",formname.keywords.value); if (nret==null) return; formname.keywords.value = nret; @@ -1479,10 +1493,10 @@ INNERJS else return; var cleantxt = txt.replace(new RegExp('([\\f\\n\\r\\t\\v ])+', 'g')," "); if (cleantxt=="") { - alert("$lt{'plse'}"); + alert("$js_lt{'plse'}"); return; } - var nret = prompt("$lt{'adds'}",cleantxt); + var nret = prompt("$js_lt{'adds'}",cleantxt); if (nret==null) return; document.SCORE.keywords.value = document.SCORE.keywords.value+" "+nret; if (document.SCORE.keywords.value != "") { @@ -1562,16 +1576,16 @@ INNERJS pDoc.write("<form action=\\"inactive\\" name=\\"msgcenter\\">"); pDoc.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">"); - pDoc.write("<h1> $lt{'comp'}\"+fullname+\"<\\/h1>"); + pDoc.write("<h1> $html_js_lt{'comp'}\"+fullname+\"<\\/h1>"); pDoc.write('<table style="border:1px solid black;"><tr>'); - pDoc.write("<td><b>$lt{'incl'}<\\/b><\\/td><td><b>$lt{'type'}<\\/b><\\/td><td><b>$lt{'mesa'}<\\/td><\\/tr>"); + pDoc.write("<td><b>$html_js_lt{'incl'}<\\/b><\\/td><td><b>$html_js_lt{'type'}<\\/b><\\/td><td><b>$html_js_lt{'mesa'}<\\/td><\\/tr>"); } function displaySubject(msg,shwsel) { pDoc = pWin.document; pDoc.write("<tr>"); pDoc.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>"); - pDoc.write("<td>$lt{'subj'}<\\/td>"); + pDoc.write("<td>$html_js_lt{'subj'}<\\/td>"); pDoc.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+"\\"size=\\"40\\" maxlength=\\"80\\"><\\/td><\\/tr>"); } @@ -1587,7 +1601,7 @@ INNERJS pDoc = pWin.document; pDoc.write("<tr>"); pDoc.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>"); - pDoc.write("<td align=\\"center\\">$lt{'new'}<\\/td>"); + pDoc.write("<td align=\\"center\\">$html_js_lt{'new'}<\\/td>"); pDoc.write("<td><textarea name=\\"newmsg\\" cols=\\"60\\" rows=\\"3\\" onchange=\\"javascript:this.form.newmsgchk.checked=true\\" >"+newmsg+"<\\/textarea><\\/td><\\/tr>"); } @@ -1595,8 +1609,8 @@ INNERJS pDoc = pWin.document; //pDoc.write("<\\/table>"); pDoc.write("<\\/td><\\/tr><\\/table> "); - pDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:checkInput()\\"> "); - pDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />"); + pDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'save'}\\" onclick=\\"javascript:checkInput()\\"> "); + pDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'canc'}\\" onclick=\\"self.close()\\"><br /><br />"); pDoc.write("<\\/form>"); pDoc.write('$end_page_msg_central'); pDoc.close(); @@ -1610,15 +1624,15 @@ INNERJS var redsel = ""; var grnsel = ""; var blusel = ""; - var txtcol1 = "$lt{'col1'}"; - var txtcol2 = "$lt{'col2'}"; - var txtcol3 = "$lt{'col3'}"; - var txtsiz1 = "$lt{'siz1'}"; - var txtsiz2 = "$lt{'siz2'}"; - var txtsiz3 = "$lt{'siz3'}"; - var txtsty1 = "$lt{'sty1'}"; - var txtsty2 = "$lt{'sty2'}"; - var txtsty3 = "$lt{'sty3'}"; + var txtcol1 = "$js_lt{'col1'}"; + var txtcol2 = "$js_lt{'col2'}"; + var txtcol3 = "$js_lt{'col3'}"; + var txtsiz1 = "$js_lt{'siz1'}"; + var txtsiz2 = "$js_lt{'siz2'}"; + var txtsiz3 = "$js_lt{'siz3'}"; + var txtsty1 = "$js_lt{'sty1'}"; + var txtsty2 = "$js_lt{'sty2'}"; + var txtsty3 = "$js_lt{'sty3'}"; if (kwclr=="red") {var redsel="checked='checked'"}; if (kwclr=="green") {var grnsel="checked='checked'"}; if (kwclr=="blue") {var blusel="checked='checked'"}; @@ -1655,10 +1669,10 @@ INNERJS hDoc.$docopen; hDoc.write('$start_page_highlight_central'); hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">"); - hDoc.write("<h1>$lt{'kehi'}<\\/h1>"); + hDoc.write("<h1>$html_js_lt{'kehi'}<\\/h1>"); hDoc.write('<table border="0" width="100%"><tr style="background-color:#A1D676">'); - hDoc.write("<th>$lt{'txtc'}<\\/th><th>$lt{'font'}<\\/th><th>$lt{'fnst'}<\\/th><\\/tr>"); + hDoc.write("<th>$html_js_lt{'txtc'}<\\/th><th>$html_js_lt{'font'}<\\/th><th>$html_js_lt{'fnst'}<\\/th><\\/tr>"); } function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) { @@ -1676,8 +1690,8 @@ INNERJS function highlightend() { var hDoc = hwdWin.document; hDoc.write("<\\/table><br \\/>"); - hDoc.write("<input type=\\"button\\" value=\\"$lt{'save'}\\" onclick=\\"javascript:updateChoice(1)\\" \\/> "); - hDoc.write("<input type=\\"button\\" value=\\"$lt{'canc'}\\" onclick=\\"self.close()\\" \\/><br /><br />"); + hDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'save'}\\" onclick=\\"javascript:updateChoice(1)\\" \\/> "); + hDoc.write("<input type=\\"button\\" value=\\"$html_js_lt{'canc'}\\" onclick=\\"self.close()\\" \\/><br /><br />"); hDoc.write("<\\/form>"); hDoc.write('$end_page_highlight_central'); hDoc.close(); @@ -3379,6 +3393,7 @@ sub viewgrades_js { my ($request) = shift; my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = '); + &js_escape(\$alertmsg); $request->print(&Apache::lonhtmlcommon::scripttag(<<VIEWJAVASCRIPT)); function writePoint(partid,weight,point) { var radioButton = document.classgrade["RADVAL_"+partid]; @@ -3568,19 +3583,67 @@ sub viewgrades { &build_section_inputs(). '<input type="hidden" name="Status" value="'.$env{'stu_status'}.'" />'."\n". - my ($common_header,$specific_header); - if ($env{'form.section'} eq 'all') { - $common_header = &mt('Assign Common Grade to Class'); - $specific_header = &mt('Assign Grade to Specific Students in Class'); - } elsif ($env{'form.section'} eq 'none') { - $common_header = &mt('Assign Common Grade to Students in no Section'); - $specific_header = &mt('Assign Grade to Specific Students in no Section'); - } else { - my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section')); - $common_header = &mt('Assign Common Grade to Students in Section(s) [_1]',$section_display); - $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1]',$section_display); + #retrieve selected groups + my (@groups,$group_display); + @groups = &Apache::loncommon::get_env_multiple('form.group'); + if (grep(/^all$/,@groups)) { + @groups = ('all'); + } elsif (grep(/^none$/,@groups)) { + @groups = ('none'); + } elsif (@groups > 0) { + $group_display = join(', ',@groups); + } + + my ($common_header,$specific_header,@sections,$section_display); + @sections = &Apache::loncommon::get_env_multiple('form.section'); + if (grep(/^all$/,@sections)) { + @sections = ('all'); + if ($group_display) { + $common_header = &mt('Assign Common Grade to Students in Group(s) [_1]',$group_display); + $specific_header = &mt('Assign Grade to Specific Students in Group(s) [_1]',$group_display); + } elsif (grep(/^none$/,@groups)) { + $common_header = &mt('Assign Common Grade to Students not assigned to any groups'); + $specific_header = &mt('Assign Grade to Specific Students not assigned to any groups'); + } else { + $common_header = &mt('Assign Common Grade to Class'); + $specific_header = &mt('Assign Grade to Specific Students in Class'); + } + } elsif (grep(/^none$/,@sections)) { + @sections = ('none'); + if ($group_display) { + $common_header = &mt('Assign Common Grade to Students in no Section and in Group(s) [_1]',$group_display); + $specific_header = &mt('Assign Grade to Specific Students in no Section and in Group(s)',$group_display); + } elsif (grep(/^none$/,@groups)) { + $common_header = &mt('Assign Common Grade to Students in no Section and in no Group'); + $specific_header = &mt('Assign Grade to Specific Students in no Section and in no Group'); + } else { + $common_header = &mt('Assign Common Grade to Students in no Section'); + $specific_header = &mt('Assign Grade to Specific Students in no Section'); + } + } else { + $section_display = join (", ",@sections); + if ($group_display) { + $common_header = &mt('Assign Common Grade to Students in Section(s) [_1], and in Group(s) [_2]', + $section_display,$group_display); + $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1], and in Group(s) [_2]', + $section_display,$group_display); + } elsif (grep(/^none$/,@groups)) { + $common_header = &mt('Assign Common Grade to Students in Section(s) [_1] and no Group',$section_display); + $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1] and no Group',$section_display); + } else { + $common_header = &mt('Assign Common Grade to Students in Section(s) [_1]',$section_display); + $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1]',$section_display); + } + } + my %submit_types = &substatus_options(); + my $submission_status = $submit_types{$env{'form.submitonly'}}; + + if ($env{'form.submitonly'} eq 'all') { + $result.= '<h3>'.$common_header.'</h3>'; + } else { + $result.= '<h3>'.$common_header.' '.&mt('(submission status: "[_1]")',$submission_status).'</h3>'; } - $result.= '<h3>'.$common_header.'</h3>'.&Apache::loncommon::start_data_table(); + $result .= &Apache::loncommon::start_data_table(); #radio buttons/text box for assigning points for a section or class. #handles different parts of a problem my $res_error; @@ -3643,8 +3706,12 @@ sub viewgrades { #table listing all the students in a section/class #header of table - $result.= '<h3>'.$specific_header.'</h3>'. - &Apache::loncommon::start_data_table(). + if ($env{'form.submitonly'} eq 'all') { + $result.= '<h3>'.$specific_header.'</h3>'; + } else { + $result.= '<h3>'.$specific_header.' '.&mt('(submission status: "[_1]")',$submission_status).'</h3>'; + } + $result.= &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). '<th>'.&mt('No.').'</th>'. '<th>'.&nameUserString('header')."</th>\n"; @@ -3690,7 +3757,7 @@ sub viewgrades { #get info for each student #list all the students - with points and grade status - my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1'); + my (undef,undef,$fullname) = &getclasslist(\@sections,'1',\@groups); my $ctr = 0; foreach (sort { @@ -3699,35 +3766,142 @@ sub viewgrades { } return $a cmp $b; } (keys(%$fullname))) { - $ctr++; $result.=&viewstudentgrade($symb,$env{'request.course.id'}, - $_,$$fullname{$_},\@parts,\%weight,$ctr,\%last_resets); + $_,$$fullname{$_},\@parts,\%weight,\$ctr,\%last_resets); } $result.=&Apache::loncommon::end_data_table(); $result.='<input type="hidden" name="total" value="'.$ctr.'" />'."\n"; $result.='<input type="button" value="'.&mt('Save').'" '. 'onclick="javascript:submit();" target="_self" /></form>'."\n"; - if (scalar(%$fullname) eq 0) { - my $colspan=3+scalar(@parts); - my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section')); + if ($ctr == 0) { 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='<h3><span class="LC_info">'.&mt('Manual Grading').'</span></h3>'. + '<span class="LC_warning">'; + if ($env{'form.submitonly'} eq 'all') { + if (grep(/^all$/,@sections)) { + if (grep(/^all$/,@groups)) { + $result .= &mt('There are no students with enrollment status [_1] to modify or grade.', + $stu_status); + } elsif (grep(/^none$/,@groups)) { + $result .= &mt('There are no students with no group assigned and with enrollment status [_1] to modify or grade.', + $stu_status); + } else { + $result .= &mt('There are no students in group(s) [_1] with enrollment status [_2] to modify or grade.', + $group_display,$stu_status); + } + } elsif (grep(/^none$/,@sections)) { + if (grep(/^all$/,@groups)) { + $result .= &mt('There are no students in no section with enrollment status [_1] to modify or grade.', + $stu_status); + } elsif (grep(/^none$/,@groups)) { + $result .= &mt('There are no students in no section and no group with enrollment status [_1] to modify or grade.', + $stu_status); + } else { + $result .= &mt('There are no students in no section in group(s) [_1] with enrollment status [_2] to modify or grade.', + $group_display,$stu_status); + } + } else { + if (grep(/^all$/,@groups)) { + $result .= &mt('There are no students in section(s) [_1] with enrollment status [_2] to modify or grade.', + $section_display,$stu_status); + } elsif (grep(/^none$/,@groups)) { + $result .= &mt('There are no students in section(s) [_1] and no group with enrollment status [_2] to modify or grade.', + $section_display,$stu_status); + } else { + $result .= &mt('There are no students in section(s) [_1] and group(s) [_2] with enrollment status [_3] to modify or grade.', + $section_display,$group_display,$stu_status); + } + } + } else { + if (grep(/^all$/,@sections)) { + if (grep(/^all$/,@groups)) { + $result .= &mt('There are no students with enrollment status [_1] and submission status "[_2]" to modify or grade.', + $stu_status,$submission_status); + } elsif (grep(/^none$/,@groups)) { + $result .= &mt('There are no students with no group assigned with enrollment status [_1] and submission status "[_2]" to modify or grade.', + $stu_status,$submission_status); + } else { + $result .= &mt('There are no students in group(s) [_1] with enrollment status [_2] and submission status "[_3]" to modify or grade.', + $group_display,$stu_status,$submission_status); + } + } elsif (grep(/^none$/,@sections)) { + if (grep(/^all$/,@groups)) { + $result .= &mt('There are no students in no section with enrollment status [_1] and submission status "[_2]" to modify or grade.', + $stu_status,$submission_status); + } elsif (grep(/^none$/,@groups)) { + $result .= &mt('There are no students in no section and no group with enrollment status [_1] and submission status "[_2]" to modify or grade.', + $stu_status,$submission_status); + } else { + $result .= &mt('There are no students in no section in group(s) [_1] with enrollment status [_2] and submission status "[_3]" to modify or grade.', + $group_display,$stu_status,$submission_status); + } + } else { + if (grep(/^all$/,@groups)) { + $result .= &mt('There are no students in section(s) [_1] with enrollment status [_2] and submission status "[_3]" to modify or grade.', + $section_display,$stu_status,$submission_status); + } elsif (grep(/^none$/,@groups)) { + $result .= &mt('There are no students in section(s) [_1] and no group with enrollment status [_2] and submission status "[_3]" to modify or grade.', + $section_display,$stu_status,$submission_status); + } else { + $result .= &mt('There are no students in section(s) [_1] and group(s) [_2] with enrollment status [_3] and submission status "[_4]" to modify or grade.', + $section_display,$group_display,$stu_status,$submission_status); + } + } + } + $result .= '</span><br />'; } return $result; } -#--- call by previous routine to display each student +#--- call by previous routine to display each student who satisfies submission filter. sub viewstudentgrade { my ($symb,$courseid,$student,$fullname,$parts,$weight,$ctr,$last_resets) = @_; my ($uname,$udom) = split(/:/,$student); my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname); - my %aggregates = (); + my $submitonly = $env{'form.submitonly'}; + unless (($submitonly eq 'all') || ($submitonly eq 'queued')) { + my %partstatus = (); + if (ref($parts) eq 'ARRAY') { + foreach my $apart (@{$parts}) { + my ($part,$type) = &split_part_type($apart); + my ($status,undef) = split(/_/,$record{"resource.$part.solved"},2); + $status = 'nothing' if ($status eq ''); + $partstatus{$part} = $status; + my $subkey = "resource.$part.submitted_by"; + $partstatus{$subkey} = $record{$subkey} if ($record{$subkey} ne ''); + } + my $submitted = 0; + my $graded = 0; + my $incorrect = 0; + foreach my $key (keys(%partstatus)) { + $submitted = 1 if ($partstatus{$key} ne 'nothing'); + $graded = 1 if ($partstatus{$key} =~ /^ungraded/); + $incorrect = 1 if ($partstatus{$key} =~ /^incorrect/); + + my $partid = (split(/\./,$key))[1]; + if ($partstatus{'resource.'.$partid.'.'.$key.'.submitted_by'} ne '') { + $submitted = 0; + } + } + return if (!$submitted && ($submitonly eq 'yes' || + $submitonly eq 'incorrect' || + $submitonly eq 'graded')); + return if (!$graded && ($submitonly eq 'graded')); + return if (!$incorrect && $submitonly eq 'incorrect'); + } + } + if ($submitonly eq 'queued') { + my ($cdom,$cnum) = split(/_/,$courseid); + my %queue_status = + &Apache::bridgetask::get_student_status($symb,$cdom,$cnum, + $udom,$uname); + return if (!defined($queue_status{'gradingqueue'})); + } + $$ctr++; + my %aggregates = (); my $result=&Apache::loncommon::start_data_table_row().'<td align="right">'. - '<input type="hidden" name="ctr'.($ctr-1).'" value="'.$student.'" />'. - "\n".$ctr.' </td><td> '. + '<input type="hidden" name="ctr'.($$ctr-1).'" value="'.$student.'" />'. + "\n".$$ctr.' </td><td> '. '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom. '\');" target="_self">'.$fullname.'</a> '. '<span class="LC_internal_info">('.$uname.($env{'user.domain'} eq $udom ? '' : ':'.$udom).')</span></td>'."\n"; @@ -3739,7 +3913,6 @@ sub viewstudentgrade { my ($aggtries,$totaltries); unless (exists($aggregates{$part})) { $totaltries = $record{'resource.'.$part.'.tries'}; - $aggtries = $totaltries; if ($$last_resets{$part}) { $aggtries = &get_num_tries(\%record,$$last_resets{$part}, @@ -4028,6 +4201,8 @@ sub split_part_type { sub csvupload_javascript_reverse_associate { my $error1=&mt('You need to specify the username or the student/employee ID'); my $error2=&mt('You need to specify at least one grading field'); + &js_escape(\$error1); + &js_escape(\$error2); return(<<ENDPICK); function verify(vf) { var foundsomething=0; @@ -4068,6 +4243,8 @@ ENDPICK sub csvupload_javascript_forward_associate { my $error1=&mt('You need to specify the username or the student/employee ID'); my $error2=&mt('You need to specify at least one grading field'); + &js_escape(\$error1); + &js_escape(\$error2); return(<<ENDPICK); function verify(vf) { var foundsomething=0; @@ -4145,6 +4322,7 @@ sub csvupload_fields { } my @fields=(['ID','Student/Employee ID'], + ['clicker','Clicker ID'], ['username','Student Username'], ['domain','Student Domain']); my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb); @@ -4176,6 +4354,7 @@ ENDPICK sub checkforfile_js { my $alertmsg = &mt('Please use the browse button to select a file from your local directory.'); + &js_escape(\$alertmsg); my $result = &Apache::lonhtmlcommon::scripttag(<<CSVFORMJS); function checkUpload(formname) { if (formname.upfile.value == "") { @@ -4339,13 +4518,45 @@ sub csvuploadassign { if (!$username) { my $id=$entries{$fields{'ID'}}; $id=~s/\s//g; - my %ids=&Apache::lonnet::idget($domain,$id); - $username=$ids{$id}; + if ($id ne '') { + my %ids=&Apache::lonnet::idget($domain,[$id]); + $username=$ids{$id}; + } else { + if ($entries{$fields{'clicker'}}) { + my $clicker = $entries{$fields{'clicker'}}; + $clicker=~s/\s//g; + if ($clicker ne '') { + my %clickers = &Apache::lonnet::idget($domain,[$clicker],'clickers'); + if ($clickers{$clicker} ne '') { + my $match = 0; + my @inclass; + foreach my $poss (split(/,/,$clickers{$clicker})) { + if (exists($$classlist{"$poss:$domain"})) { + $username = $poss; + push(@inclass,$poss); + $match ++; + + } + } + if ($match > 1) { + undef($username); + $request->print('<p class="LC_warning">'. + &mt('Score not saved for clicker: [_1] (matched multiple usernames: [_2])', + $clicker,join(', ',@inclass)).'</p>'); + } + } + } + } + } } if (!exists($$classlist{"$username:$domain"})) { my $id=$entries{$fields{'ID'}}; $id=~s/\s//g; - if ($id) { + my $clicker = $entries{$fields{'clicker'}}; + $clicker=~s/\s//g; + if ($clicker) { + push(@skipped,"$clicker:$domain"); + } elsif ($id) { push(@skipped,"$id:$domain"); } else { push(@skipped,"$username:$domain"); @@ -4445,6 +4656,7 @@ sub pickStudentPage { my ($request,$symb) = @_; my $alertmsg = &mt('Please select the student you wish to grade.'); + &js_escape(\$alertmsg); $request->print(&Apache::lonhtmlcommon::scripttag(<<LISTJAVASCRIPT)); function checkPickOne(formname) { @@ -5482,10 +5694,12 @@ sub scantron_selectphase { my $default_form_data=&defaultFormData($symb); my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'}; + my $alertmsg = &mt('Please use the browse button to select a file from your local directory.'); + &js_escape(\$alertmsg); $r->print(&Apache::lonhtmlcommon::scripttag(' function checkUpload(formname) { if (formname.upfile.value == "") { - alert("'.&mt('Please use the browse button to select a file from your local directory.').'"); + alert("'.$alertmsg.'"); return false; } formname.submit(); @@ -7472,6 +7686,7 @@ sub verify_bubbles_checked { my (@ansnums) = @_; my $ansnumstr = join('","',@ansnums); my $warning = &mt("A bubble or 'No bubble' selection has not been made for one or more lines."); + &js_escape(\$warning); my $output = &Apache::lonhtmlcommon::scripttag((<<ENDSCRIPT)); function verify_bubble_radio(form) { var ansnumArray = new Array ("$ansnumstr"); @@ -8393,9 +8608,14 @@ SCANTRONFORM } if ((exists($grader_randomlists_by_symb{$ressymb})) || (ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) { + my $currcode; + if (exists($grader_randomlists_by_symb{$ressymb})) { + $currcode = $scancode; + } my ($analysis,$parts) = &scantron_partids_tograde($resource,$env{'request.course.id'}, - $uname,$udom,undef,$bubbles_per_row); + $uname,$udom,undef,$bubbles_per_row, + $currcode); $partids_by_symb{$ressymb} = $parts; } else { $partids_by_symb{$ressymb} = $grader_partids_by_symb{$ressymb}; @@ -8662,7 +8882,9 @@ sub scantron_upload_scantron_data { (' 'x2).&mt('(shows course personnel)'); my $default_form_data=&defaultFormData($symb); my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.'); + &js_escape(\$nofile_alert); my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded."); + &js_escape(\$nocourseid_alert); $r->print(&Apache::lonhtmlcommon::scripttag(' function checkUpload(formname) { if (formname.upfile.value == "") { @@ -9048,10 +9270,14 @@ sub checkscantron_results { my $ressymb = $resource->symb(); if ((exists($grader_randomlists_by_symb{$ressymb})) || (ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) { + my $currcode; + if (exists($grader_randomlists_by_symb{$ressymb})) { + $currcode = $scancode; + } (my $analysis,$parts) = &scantron_partids_tograde($resource,$env{'request.course.id'}, $username,$domain,undef, - $bubbles_per_row); + $bubbles_per_row,$currcode); } else { $parts = $grader_partids_by_symb{$ressymb}; } @@ -9428,7 +9654,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.=&selectfield(0). + $result.=&selectfield(1). '<input type="hidden" name="command" value="viewgrades" /> <div> <input type="submit" value="'.&mt('Next').' →" /> @@ -9484,13 +9710,8 @@ 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']); + (&substatus_options, + 'select_form_order' => ['yes','queued','graded','incorrect','all']); my $result='<div class="LC_columnSection"> <fieldset> @@ -9526,6 +9747,16 @@ sub selectfield { return $result; } +sub substatus_options { + return &Apache::lonlocal::texthash( + 'yes' => 'with submissions', + 'queued' => 'in grading queue', + 'graded' => 'with ungraded submissions', + 'incorrect' => 'with incorrect submissions', + 'all' => 'with any status', + ); +} + sub reset_perm { undef(%perm); }