'."\n";
+ 'onchange="javascript:changeOneScore(\''.$part.'\',\''.$student.'\')" >'."\n";
$result.= (($status eq 'excused') ? ' '.&mt('excused').' '
: ' '.&mt('excused').' ')."\n";
$result.=''.&mt('reset status').' ';
@@ -3444,12 +3509,10 @@ sub viewstudentgrade {
#--- change scores for all the students in a section/class
# record does not get update if unchanged
sub editgrades {
- my ($request) = @_;
+ my ($request,$symb) = @_;
- my $symb=&get_symb($request);
my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
my $title=''.&mt('Current Grade Status').' ';
- $title.=''.&mt('Current Resource: [_1]',$env{'form.probTitle'}).' '."\n";
$title.=''.&mt('Section: [_1]',$section_display).' '."\n";
my $result= &Apache::loncommon::start_data_table().
@@ -3461,6 +3524,7 @@ sub editgrades {
'incorrect'=>'incorrect_by_override',
'excused' =>'excused',
'ungraded' =>'ungraded_attempted',
+ 'credited' =>'credit_attempted',
'nothing' => '',
);
my ($classlist,undef,$fullname) = &getclasslist($env{'form.section'},'0');
@@ -3470,7 +3534,11 @@ sub editgrades {
my %columns = ();
my ($i,$ctr,$count,$rec_update) = (0,0,0,0);
- my (@parts) = sort(&getpartlist($symb));
+ my $partserror;
+ my (@parts) = sort(&getpartlist($symb,\$partserror));
+ if ($partserror) {
+ return &navmap_errormsg();
+ }
my $header;
while ($ctr < $env{'form.totalparts'}) {
my $partid = $env{'form.partid_'.$ctr};
@@ -3652,8 +3720,7 @@ sub editgrades {
&Apache::loncommon::end_data_table_row();
}
}
- $result .= &Apache::loncommon::end_data_table().
- &show_grading_menu_form($symb);
+ $result .= &Apache::loncommon::end_data_table();
my $msg = ''.
&mt('Number of records updated = [_1] for [quant,_2,student].',
$rec_update,$count).' '.
@@ -3681,7 +3748,7 @@ sub split_part_type {
#
#--- Javascript to handle csv upload
sub csvupload_javascript_reverse_associate {
- my $error1=&mt('You need to specify the username or ID');
+ 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');
return(<print('
ENDPICK
}
sub checkforfile_js {
my $alertmsg = &mt('Please use the browse button to select a file from your local directory.');
- my $result =<
+ my $result = &Apache::lonhtmlcommon::scripttag(<
CSVFORMJS
return $result;
}
sub upcsvScores_form {
- my ($request) = shift;
- my ($symb)=&get_symb($request);
+ my ($request,$symb) = @_;
if (!$symb) {return '';}
my $result=&checkforfile_js();
- $env{'form.probTitle'} = &Apache::lonnet::gettitle($symb);
- my ($table) = &showResourceInfo($symb,$env{'form.probTitle'});
- $result.=$table;
- $result.=''."\n";
- $result.=''."\n";
- $result.=' '.&mt('Specify a file containing the class scores for current resource.').
- ' '."\n";
- $result.=''."\n";
+ $result.=&Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ' '.&mt('Specify a file containing the class scores for current resource.').' '.
+ &Apache::loncommon::end_data_table_header_row().
+ &Apache::loncommon::start_data_table_row().'';
my $upload=&mt("Upload Scores");
my $upfile_select=&Apache::loncommon::upfile_select_html();
my $ignore=&mt('Ignore First Line');
@@ -3870,25 +3926,21 @@ sub upcsvScores_form {
ENDUPFORM
$result.=&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
- &mt("How do I create a CSV file from a spreadsheet"))
- .'
'."\n";
- $result.='
'."\n";
- $result.=&show_grading_menu_form($symb);
+ &mt("How do I create a CSV file from a spreadsheet")).
+ ''.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
return $result;
}
sub csvuploadmap {
- my ($request)= @_;
- my ($symb)=&get_symb($request);
+ my ($request,$symb)= @_;
if (!$symb) {return '';}
my $datatoken;
@@ -3899,12 +3951,15 @@ sub csvuploadmap {
&Apache::loncommon::load_tmp_file($request);
}
my @records=&Apache::loncommon::upfile_record_sep();
- if ($env{'form.noFirstLine'}) { shift(@records); }
&csvuploadmap_header($request,$symb,$datatoken,$#records+1);
my ($i,$keyfields);
if (@records) {
- my @fields=&csvupload_fields($symb);
-
+ my $fieldserror;
+ my @fields=&csvupload_fields($symb,\$fieldserror);
+ if ($fieldserror) {
+ $request->print(&navmap_errormsg());
+ return;
+ }
if ($env{'form.upfile_associate'} eq 'reverse') {
&Apache::loncommon::csv_print_samples($request,\@records);
$i=&Apache::loncommon::csv_print_select_table($request,\@records,
@@ -3925,39 +3980,27 @@ sub csvuploadmap {
}
}
&csvuploadmap_footer($request,$i,$keyfields);
- $request->print(&show_grading_menu_form($symb));
return '';
}
sub csvuploadoptions {
- my ($request)= @_;
- my ($symb)=&get_symb($request);
- my $checked=(($env{'form.noFirstLine'})?'1':'0');
- my $ignore=&mt('Ignore First Line');
+ my ($request,$symb)= @_;
+ my $overwrite=&mt('Overwrite any existing score');
$request->print(<
-Uploading Class Grade Options
-
- Overwrite any existing score
+ $overwrite
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 Users are in domain: ".$domform."
\n");
+ $request->print("\n".&mt('Users are in domain: [_1]',$domform)."
\n");
}
foreach my $key (sort(keys(%env))) {
if ($key !~ /^form\.(.*)$/) { next; }
@@ -3970,7 +4013,6 @@ ENDPICK
# FIXME do a check for any invalid user ids?...
$request->print('
'."\n");
- $request->print(&show_grading_menu_form($symb));
return '';
}
@@ -3992,15 +4034,12 @@ sub get_fields {
}
sub csvuploadassign {
- my ($request)= @_;
- my ($symb)=&get_symb($request);
+ my ($request,$symb)= @_;
if (!$symb) {return '';}
my $error_msg = '';
&Apache::loncommon::load_tmp_file($request);
my @gradedata = &Apache::loncommon::upfile_record_sep();
- if ($env{'form.noFirstLine'}) { shift(@gradedata); }
my %fields=&get_fields();
- $request->print('Assigning Grades ');
my $courseid=$env{'request.course.id'};
my ($classlist) = &getclasslist('all',0);
my @notallowed;
@@ -4053,6 +4092,9 @@ sub csvuploadassign {
my $pcr=$entries{$fields{$dest}} / $wgt;
my $award=($pcr == 0) ? 'incorrect_by_override'
: 'correct_by_override';
+ if ($pcr>1) {
+ push(@skipped,&mt("[_1]: point value larger than weight","$username:$domain"));
+ }
$grades{"resource.$part.awarded"}=$pcr;
$grades{"resource.$part.solved"}=$award;
$points{$part}=1;
@@ -4080,27 +4122,32 @@ sub csvuploadassign {
$env{'request.course.id'},
$domain,$username);
if ($result eq 'ok') {
+# Successfully stored
$request->print('.');
- } else {
+# Remove from grading queue
+ &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'},
+ $domain,$username);
+ $countdone++;
+ } else {
$request->print("".
&mt("Failed to save data for student [_1]. Message when trying to save was: [_2]",
"$username:$domain",$result)."
");
}
$request->rflush();
- $countdone++;
}
}
- $request->print(''.&mt("Saved [_1] students",$countdone)." \n");
+ $request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));
if (@skipped) {
- $request->print(''.&mt('Skipped Students').'
');
- foreach my $student (@skipped) { $request->print("$student \n"); }
+ $request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt('No scores stored for the following username(s):'),1).' ');
+ $request->print(join(', ',@skipped));
}
if (@notallowed) {
- $request->print(''.&mt('Students Not Allowed to Modify').'
');
- foreach my $student (@notallowed) { $request->print("$student \n"); }
+ $request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt('Modification of scores not allowed for the following username(s):'),1).' ');
+ $request->print(join(', ',@notallowed));
}
$request->print(" \n");
- $request->print(&show_grading_menu_form($symb));
return $error_msg;
}
#------------- end of section for handling csv file upload ---------
@@ -4111,11 +4158,10 @@ sub csvuploadassign {
#
#--- Select a page/sequence and a student to grade
sub pickStudentPage {
- my ($request) = shift;
+ my ($request,$symb) = @_;
my $alertmsg = &mt('Please select the student you wish to grade.');
- $request->print(<
+ $request->print(&Apache::lonhtmlcommon::scripttag(<
LISTJAVASCRIPT
&commonJSfunctions($request);
- my ($symb) = &get_symb($request);
+
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
@@ -4140,7 +4185,12 @@ LISTJAVASCRIPT
&mt('Manual Grading by Page or Sequence').'';
$result.=''."\n";
+ 'onclick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' →" />'."\n";
- $studentTable.=&show_grading_menu_form($symb);
$request->print($studentTable);
return '';
}
sub getSymbMap {
+ my ($map_error) = @_;
my $navmap = Apache::lonnavmaps::navmap->new();
-
+ unless (ref($navmap)) {
+ if (ref($map_error)) {
+ $$map_error = 'navmap';
+ }
+ return;
+ }
my %symbx = ();
my @titles = ();
my $minder = 0;
@@ -4259,9 +4313,7 @@ sub getSymbMap {
#
#--- Displays a page/sequence w/wo problems, w/wo submissions
sub displayPage {
- my ($request) = shift;
-
- my ($symb) = &get_symb($request);
+ my ($request,$symb) = @_;
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
@@ -4279,7 +4331,6 @@ sub displayPage {
if (!&canview($usec)) {
$request->print(''.&mt('Unable to view requested student. ([_1])',$env{'form.student'}).' ');
- $request->print(&show_grading_menu_form($symb));
return;
}
my $result=' '.$env{'form.title'}.' ';
@@ -4295,11 +4346,14 @@ sub displayPage {
$request->print($result);
my $navmap = Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ $request->print(&navmap_errormsg());
+ return;
+ }
my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'});
my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
if (!$map) {
$request->print(''.&mt('Unable to view requested sequence. ([_1])',$resUrl).' ');
- $request->print(&show_grading_menu_form($symb));
return;
}
my $iterator = $navmap->getIterator($map->map_start(),
@@ -4312,8 +4366,7 @@ sub displayPage {
' '."\n".
' '."\n".
' '."\n".
- ' '."\n".
- ' '."\n";
+ ' '."\n";
if (defined($env{'form.CODE'})) {
$studentTable.=
@@ -4322,7 +4375,9 @@ sub displayPage {
my $checkIcon = ' ';
- $studentTable.=' '.&mt('Note: Problems graded correct by the computer are marked with a [_1] symbol.',$checkIcon)."\n".
+ $studentTable.=' '.
+ &mt('Problems graded correct by the computer are marked with a [_1] symbol.',$checkIcon).
+ ' '."\n".
&Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row().
' Prob. '.
@@ -4345,8 +4400,8 @@ sub displayPage {
&Apache::loncommon::start_data_table_row().
''.$prob.
(scalar(@{$parts}) == 1 ? ''
- : ' ('.&mt('[_1] parts)',
- scalar(@{$parts}))
+ : ' ('.&mt('[_1]parts)',
+ scalar(@{$parts}).' ')
).
' ';
$studentTable.='';
@@ -4393,11 +4448,13 @@ sub displayPage {
}
if (&canmodify($usec)) {
+ $studentTable.=&gradeBox_start();
foreach my $partid (@{$parts}) {
$studentTable.=&gradeBox($request,$symbx,$uname,$udom,$question,$partid,\%record);
$studentTable.=' '."\n";
$question++;
}
+ $studentTable.=&gradeBox_end();
$prob++;
}
$studentTable.=' ';
@@ -4406,11 +4463,11 @@ sub displayPage {
$curRes = $iterator->next();
}
- $studentTable.=''."\n".
- ' '.
- ''."\n";
- $studentTable.=&show_grading_menu_form($symb);
+ $studentTable.=
+ ''."\n".
+ ' '.
+ ''."\n";
$request->print($studentTable);
return '';
@@ -4438,6 +4495,7 @@ sub displaySubByDates {
my $interaction;
my $no_increment = 1;
+ my %lastrndseed;
for ($version=1;$version<=$$record{'version'};$version++) {
my $timestamp =
&Apache::lonlocal::locallocaltime($$record{$version.':timestamp'});
@@ -4455,37 +4513,60 @@ sub displaySubByDates {
my @versionKeys = split(/\:/,$$record{$version.':keys'});
my @displaySub = ();
foreach my $partid (@{$parts}) {
+ my ($hidden,$type);
+ $type = $$record{$version.':resource.'.$partid.'.type'};
+ if (($type eq 'anonsurvey') || ($type eq 'anonsurveycred')) {
+ $hidden = 1;
+ }
my @matchKey = ($isTask ? sort(grep /^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys)
: sort(grep /^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys));
-
# next if ($$record{"$version:resource.$partid.solved"} eq '');
my $display_part=&get_display_part($partid,$symb);
foreach my $matchKey (@matchKey) {
if (exists($$record{$version.':'.$matchKey}) &&
$$record{$version.':'.$matchKey} ne '') {
-
+
my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/)
: ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/));
- $displaySub[0].=''.&mt('Part:').' '.$display_part.' ';
- $displaySub[0].='('.&mt('ID').' '.
- $responseId.') ';
- if ($$record{"$where.$partid.tries"} eq '') {
- $displaySub[0].=&mt('Trial not counted');
- } else {
- $displaySub[0].=&mt('Trial [_1]',
+ $displaySub[0].=''.&mt('Part: [_1]',$display_part).' '
+ .' '
+ .'('.&mt('Response ID: [_1]',$responseId).')'
+ .' '
+ .' ';
+ if ($hidden) {
+ $displaySub[0].= &mt('Anonymous Survey').' ';
+ } else {
+ my ($trial,$rndseed,$newvariation);
+ if ($type eq 'randomizetry') {
+ $trial = $$record{"$where.$partid.tries"};
+ $rndseed = $$record{"$where.$partid.rndseed"};
+ }
+ if ($$record{"$where.$partid.tries"} eq '') {
+ $displaySub[0].=&mt('Trial not counted');
+ } else {
+ $displaySub[0].=&mt('Trial: [_1]',
$$record{"$where.$partid.tries"});
- }
- my $responseType=($isTask ? 'Task'
+ if ($rndseed || $lastrndseed{$partid}) {
+ if ($rndseed ne $lastrndseed{$partid}) {
+ $newvariation = ' ('.&mt('New variation this try').')';
+ }
+ }
+ $lastrndseed{$partid} = $rndseed;
+ }
+ my $responseType=($isTask ? 'Task'
: $responseType->{$partid}->{$responseId});
- if (!exists($orders{$partid})) { $orders{$partid}={}; }
- if (!exists($orders{$partid}->{$responseId})) {
- $orders{$partid}->{$responseId}=
- &get_order($partid,$responseId,$symb,$uname,$udom,
- $no_increment);
- }
- $displaySub[0].=' '.
- &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom).' ';
+ if (!exists($orders{$partid})) { $orders{$partid}={}; }
+ if ((!exists($orders{$partid}->{$responseId})) || ($trial)) {
+ $orders{$partid}->{$responseId}=
+ &get_order($partid,$responseId,$symb,$uname,$udom,
+ $no_increment,$type,$trial,$rndseed);
+ }
+ $displaySub[0].=''.$newvariation.''; # /nobreak
+ $displaySub[0].=' '.
+ &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom,$type,$trial,$rndseed).' ';
+ }
}
}
if (exists($$record{"$where.$partid.checkedin"})) {
@@ -4525,7 +4606,7 @@ sub displaySubByDates {
}
sub updateGradeByPage {
- my ($request) = shift;
+ my ($request,$symb) = @_;
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
@@ -4536,7 +4617,6 @@ sub updateGradeByPage {
my $usec=$classlist->{$env{'form.student'}}[5];
if (!&canmodify($usec)) {
$request->print(''.&mt('Unable to modify requested student ([_1])',$env{'form.student'}).' ');
- $request->print(&show_grading_menu_form($env{'form.symb'}));
return;
}
my $result=' '.$env{'form.title'}.' ';
@@ -4545,13 +4625,16 @@ sub updateGradeByPage {
$request->print($result);
+
my $navmap = Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ $request->print(&navmap_errormsg());
+ return;
+ }
my ($mapUrl, $id, $resUrl) = &Apache::lonnet::decode_symb( $env{'form.page'});
my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
if (!$map) {
$request->print(''.&mt('Unable to grade requested sequence ([_1]).',$resUrl).' ');
- my ($symb)=&get_symb($request);
- $request->print(&show_grading_menu_form($symb));
return;
}
my $iterator = $navmap->getIterator($map->map_start(),
@@ -4581,7 +4664,7 @@ sub updateGradeByPage {
&Apache::loncommon::start_data_table_row().
''.$prob.
(scalar(@{$parts}) == 1 ? ''
- : ' ('.&mt('[quant,_1, part]',scalar(@{$parts}))
+ : ' ('.&mt('[quant,_1,part]',scalar(@{$parts}))
.')').' ';
$studentTable.=' '.$title.' ';
@@ -4677,7 +4760,6 @@ sub updateGradeByPage {
}
$studentTable.=&Apache::loncommon::end_data_table();
- $studentTable.=&show_grading_menu_form($env{'form.symb'});
my $grademsg=($changeflag == 0 ? &mt('No score was changed or updated.') :
&mt('The scores were changed for [quant,_1,problem].',
$changeflag));
@@ -4690,7 +4772,7 @@ sub updateGradeByPage {
#
#-------------------------------------------------------------------
-#--------------------Scantron Grading-----------------------------------
+#-------------------- Bubblesheet (Scantron) Grading -------------------
#
#------ start of section for handling grading by page/sequence ---------
@@ -4755,9 +4837,7 @@ the homework problem.
sub defaultFormData {
my ($symb)=@_;
- return ' '."\n".
- ' '."\n".
- ' '."\n";
+ return ' ';
}
@@ -4768,14 +4848,19 @@ sub defaultFormData {
Return html dropdown of possible sequences to grade
Arguments:
- $symb - $symb of the current resource
+ $symb - $symb of the current resource
+ $map_error - ref to scalar which will container error if
+ $navmap object is unavailable in &getSymbMap().
=cut
sub getSequenceDropDown {
- my ($symb)=@_;
+ my ($symb,$map_error)=@_;
my $result=''."\n";
- my ($titles,$symbx) = &getSymbMap();
+ my ($titles,$symbx) = &getSymbMap($map_error);
+ if (ref($map_error)) {
+ return if ($$map_error);
+ }
my ($curpage)=&Apache::lonnet::decode_symb($symb);
my $ctr=0;
foreach (@$titles) {
@@ -5038,12 +5123,15 @@ sub scantron_CODEunique {
=cut
sub scantron_selectphase {
- my ($r,$file2grade) = @_;
- my ($symb)=&get_symb($r);
+ my ($r,$file2grade,$symb) = @_;
if (!$symb) {return '';}
- my $sequence_selector=&getSequenceDropDown($symb);
+ my $map_error;
+ my $sequence_selector=&getSequenceDropDown($symb,\$map_error);
+ if ($map_error) {
+ $r->print(' '.&navmap_errormsg().' ');
+ return;
+ }
my $default_form_data=&defaultFormData($symb);
- my $grading_menu_button=&show_grading_menu_form($symb);
my $file_selector=&scantron_uploads($file2grade);
my $format_selector=&scantron_scantab();
my $CODE_selector=&scantron_CODElist();
@@ -5052,6 +5140,52 @@ sub scantron_selectphase {
$ssi_error = 0;
+ if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||
+ &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
+
+ # Chunk of form to prompt for a scantron file upload.
+
+ $r->print('
+
+ '.&Apache::loncommon::start_data_table('LC_scantron_action').'
+ '.&Apache::loncommon::start_data_table_header_row().'
+
+ '.&mt('Specify a bubblesheet data file to upload.').'
+
+ '.&Apache::loncommon::end_data_table_header_row().'
+ '.&Apache::loncommon::start_data_table_row().'
+
+');
+ my $default_form_data=&defaultFormData($symb);
+ my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'};
+ $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.').'");
+ return false;
+ }
+ formname.submit();
+ }'));
+ $r->print('
+
+');
+
+ $r->print('
+
+ '.&Apache::loncommon::end_data_table_row().'
+ '.&Apache::loncommon::end_data_table().'
+');
+ }
+
# Chunk of form to prompt for a file to grade and how:
$result.= '
@@ -5069,10 +5203,10 @@ sub scantron_selectphase {
'.&mt('Sequence to grade:').' '.$sequence_selector.'
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
- '.&mt('Filename of scoring office file:').' '.$file_selector.'
+ '.&mt('Filename of bubblesheet data file:').' '.$file_selector.'
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
- '.&mt('Format of data file:').' '.$format_selector.'
+ '.&mt('Format of bubblesheet data file:').' '.$format_selector.'
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
'.&mt('Saved CODEs to validate against:').' '.$CODE_selector.'
@@ -5090,7 +5224,7 @@ sub scantron_selectphase {
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
-
+
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::end_data_table().'
@@ -5099,53 +5233,7 @@ sub scantron_selectphase {
$r->print($result);
- if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||
- &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
-
- # Chunk of form to prompt for a scantron file upload.
-
- $r->print('
-
- '.&Apache::loncommon::start_data_table('LC_scantron_action').'
- '.&Apache::loncommon::start_data_table_header_row().'
-
- '.&mt('Specify a Scantron data file to upload.').'
-
- '.&Apache::loncommon::end_data_table_header_row().'
- '.&Apache::loncommon::start_data_table_row().'
-
-');
- my $default_form_data=&defaultFormData(&get_symb($r,1));
- my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};
- my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'};
- $r->print('
-
-
-
-');
- $r->print('
-
- '.&Apache::loncommon::end_data_table_row().'
- '.&Apache::loncommon::end_data_table().'
-');
- }
# Chunk of the form that prompts to view a scoring office file,
# corrected file, skipped records in a file.
@@ -5178,7 +5266,7 @@ sub scantron_selectphase {
&Apache::loncommon::start_data_table('LC_scantron_action')."\n".
&Apache::loncommon::start_data_table_header_row()."\n".
'
- '.&mt('Review scantron data and submissions for a previously graded folder/sequence')."\n".
+ '.&mt('Review bubblesheet data and submissions for a previously graded folder/sequence')."\n".
' '."\n".
&Apache::loncommon::end_data_table_header_row()."\n".
&Apache::loncommon::start_data_table_row()."\n".
@@ -5200,12 +5288,11 @@ sub scantron_selectphase {
&Apache::loncommon::start_data_table_row()."\n".
''."\n".
' '."\n".
- ' '."\n".
+ ' '."\n".
' '."\n".
&Apache::loncommon::end_data_table_row()."\n".
&Apache::loncommon::end_data_table()."\n".
' ');
- $r->print($grading_menu_button);
return;
}
@@ -5241,7 +5328,7 @@ sub scantron_selectphase {
CODEstart - (only matter if a CODE exists) column in the line where
the CODE starts
CODElength - length of the CODE
- IDstart - column where the student/employee ID number starts
+ IDstart - column where the student/employee ID starts
IDlength - length of the student/employee ID info
Qstart - column where the information from the bubbled
'questions' start
@@ -5341,7 +5428,7 @@ sub username_to_idmap {
$whichline - line number of the passed in scanline
$field - type of change to process
(either
- 'ID' -> correct the student/employee ID number
+ 'ID' -> correct the student/employee ID
'CODE' -> correct the CODE
'answer' -> fixup the submitted answers)
@@ -6105,8 +6192,7 @@ sub scantron_warning_screen {
=cut
sub scantron_do_warning {
- my ($r)=@_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb)=@_;
if (!$symb) {return '';}
my $default_form_data=&defaultFormData($symb);
$r->print(&scantron_form_start().$default_form_data);
@@ -6131,7 +6217,7 @@ sub scantron_do_warning {
');
}
- $r->print(" ".&show_grading_menu_form($symb));
+ $r->print(" ");
return '';
}
@@ -6187,8 +6273,7 @@ SCANTRONFORM
=cut
sub scantron_validate_file {
- my ($r) = @_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb) = @_;
if (!$symb) {return '';}
my $default_form_data=&defaultFormData($symb);
@@ -6215,7 +6300,12 @@ sub scantron_validate_file {
$r->print(''.&mt('Gathering necessary information.').'
');$r->rflush();
#get the student pick code ready
$r->print(&Apache::loncommon::studentbrowser_javascript());
- my $max_bubble=&scantron_get_maxbubble();
+ my $nav_error;
+ my $max_bubble=&scantron_get_maxbubble(\$nav_error);
+ if ($nav_error) {
+ $r->print(&navmap_errormsg());
+ return '';
+ }
my $result=&scantron_form_start($max_bubble).$default_form_data;
$r->print($result);
@@ -6251,7 +6341,7 @@ sub scantron_validate_file {
' '.&mt('No').
' '.
&mt('Grading will take longer if you use verification.').' '.
- &mt("Alternatively, the 'Review scantron data' utility (see grading menu) can be used for all students after grading is complete.").' '.
+ &mt("Alternatively, the 'Review bubblesheet data' utility (see grading menu) can be used for all students after grading is complete.").' '.
' '.
' '."\n");
} else {
@@ -6275,7 +6365,7 @@ sub scantron_validate_file {
$r->print(" ".&mt("this scanline saving it for later."));
}
}
- $r->print(" ".&show_grading_menu_form($symb));
+ $r->print(" ");
return '';
}
@@ -6627,6 +6717,10 @@ sub scantron_validate_sequence {
my ($r,$currentphase) = @_;
my $navmap=Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ $r->print(&navmap_errormsg());
+ return (1,$currentphase);
+ }
my (undef,undef,$sequence)=
&Apache::lonnet::decode_symb($env{'form.selectpage'});
@@ -6658,8 +6752,13 @@ sub scantron_validate_ID {
#get scantron line setup
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
-
- &scantron_get_maxbubble(); # parse needs the bubble_lines.. array.
+
+ my $nav_error;
+ &scantron_get_maxbubble(\$nav_error); # parse needs the bubble_lines.. array.
+ if ($nav_error) {
+ $r->print(&navmap_errormsg());
+ return(1,$currentphase);
+ }
my %found=('ids'=>{},'usernames'=>{});
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
@@ -6777,10 +6876,10 @@ sub scantron_get_correction {
if ($closest > 0) {
foreach my $testcode (@{$closest}) {
my $checked='';
- if (!$i) { $checked=' checked="checked" '; }
+ if (!$i) { $checked=' checked="checked"'; }
$r->print("
-
+
".&mt("Use the similar CODE [_1] instead.",
"".$testcode." ")."
@@ -6791,18 +6890,17 @@ sub scantron_get_correction {
}
}
if ($$scan_record{'scantron.CODE'}=~/\S/ ) {
- my $checked; if (!$i) { $checked=' checked="checked" '; }
+ my $checked; if (!$i) { $checked=' checked="checked"'; }
$r->print("
-
+
".&mt("Use the CODE [_1] that is was on the paper, ignoring the error.",
"".$$scan_record{'scantron.CODE'}." ")."
");
$r->print("\n ");
}
- $r->print(<
+ $r->print(&Apache::lonhtmlcommon::scripttag(<
ENDSCRIPT
my $href="/adm/pickcode?".
"form=".&escape("scantronupload").
@@ -6882,8 +6979,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.");
- my $output = (<
+ my $output = &Apache::lonhtmlcommon::scripttag((<
ENDSCRIPT
return $output;
}
@@ -7018,7 +7113,7 @@ sub prompt_for_corrections {
($responsetype_per_response{$question-1} eq 'imageresponse') ||
($responsetype_per_response{$question-1} eq 'reactionresponse') ||
($responsetype_per_response{$question-1} eq 'organicresponse')) {
- $r->print(&mt("Although this particular question type requires handgrading, the instructions for this question in the exam directed students to leave [quant,_1,line] blank on their scantron sheets.",$lines).' '.&mt('A non-zero score can be assigned to the student during scantron grading by selecting a bubble in at least one line.').' '.&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.').' '.&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.").' ');
+ $r->print(&mt("Although this particular question type requires handgrading, the instructions for this question in the exam directed students to leave [quant,_1,line] blank on their bubblesheets.",$lines).' '.&mt('A non-zero score can be assigned to the student during bubblesheet grading by selecting a bubble in at least one line.').' '.&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.').' '.&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.").' ');
} else {
$r->print(&mt("Select at most one bubble in a single line and select 'No Bubble' in all the other lines. ")." ");
}
@@ -7212,7 +7307,12 @@ sub scantron_validate_CODE {
my %allcodes=&get_codes();
- &scantron_get_maxbubble(); # parse needs the lines per response array.
+ my $nav_error;
+ &scantron_get_maxbubble(\$nav_error); # parse needs the lines per response array.
+ if ($nav_error) {
+ $r->print(&navmap_errormsg());
+ return(1,$currentphase);
+ }
my ($scanlines,$scan_data)=&scantron_getfile();
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
@@ -7266,7 +7366,12 @@ sub scantron_validate_doublebubble {
#get scantron line setup
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
- &scantron_get_maxbubble(); # parse needs the bubble line array.
+ my $nav_error;
+ &scantron_get_maxbubble(\$nav_error); # parse needs the bubble line array.
+ if ($nav_error) {
+ $r->print(&navmap_errormsg());
+ return(1,$currentphase);
+ }
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
my $line=&scantron_get_line($scanlines,$scan_data,$i);
@@ -7284,6 +7389,7 @@ sub scantron_validate_doublebubble {
sub scantron_get_maxbubble {
+ my ($nav_error) = @_;
if (defined($env{'form.scantron_maxbubble'}) &&
$env{'form.scantron_maxbubble'}) {
&restore_bubble_lines();
@@ -7294,6 +7400,12 @@ sub scantron_get_maxbubble {
&Apache::lonnet::decode_symb($env{'form.selectpage'});
my $navmap=Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ if (ref($nav_error)) {
+ $$nav_error = 1;
+ }
+ return;
+ }
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
@@ -7383,7 +7495,11 @@ sub scantron_validate_missingbubbles {
#get scantron line setup
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
- my $max_bubble=&scantron_get_maxbubble();
+ my $nav_error;
+ my $max_bubble=&scantron_get_maxbubble(\$nav_error);
+ if ($nav_error) {
+ return(1,$currentphase);
+ }
if (!$max_bubble) { $max_bubble=2**31; }
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
my $line=&scantron_get_line($scanlines,$scan_data,$i);
@@ -7429,10 +7545,9 @@ sub scantron_validate_missingbubbles {
sub scantron_process_students {
- my ($r) = @_;
+ my ($r,$symb) = @_;
my (undef,undef,$sequence)=&Apache::lonnet::decode_symb($env{'form.selectpage'});
- my ($symb)=&get_symb($r);
if (!$symb) {
return '';
}
@@ -7443,13 +7558,24 @@ sub scantron_process_students {
my $classlist=&Apache::loncoursedata::get_classlist();
my %idmap=&username_to_idmap($classlist);
my $navmap=Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ $r->print(&navmap_errormsg());
+ return '';
+ }
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
my (%grader_partids_by_symb,%grader_randomlists_by_symb);
&graders_resources_pass(\@resources,\%grader_partids_by_symb,
\%grader_randomlists_by_symb);
+ my $resource_error;
foreach my $resource (@resources) {
- my $ressymb = $resource->symb();
+ my $ressymb;
+ if (ref($resource)) {
+ $ressymb = $resource->symb();
+ } else {
+ $resource_error = 1;
+ last;
+ }
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
$env{'user.name'},$env{'user.domain'},1);
@@ -7461,6 +7587,10 @@ sub scantron_process_students {
}
}
}
+ if ($resource_error) {
+ $r->print(&navmap_errormsg());
+ return '';
+ }
my ($uname,$udom);
my $result= <print(&navmap_errormsg());
+ return '';
+ }
# If an ssi failed in scantron_get_maxbubble, put an error message out to
# the user and return.
@@ -7493,7 +7628,6 @@ SCANTRONFORM
if ($ssi_error) {
$r->print("");
&ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
&Apache::lonnet::remove_lock($lock);
return ''; # Dunno why the other returns return '' rather than just returning.
}
@@ -7526,9 +7660,15 @@ SCANTRONFORM
}
($uname,$udom)=split(/:/,$uname);
- my %partids_by_symb;
+ my (%partids_by_symb,$res_error);
foreach my $resource (@resources) {
- my $ressymb = $resource->symb();
+ my $ressymb;
+ if (ref($resource)) {
+ $ressymb = $resource->symb();
+ } else {
+ $res_error = 1;
+ last;
+ }
if ((exists($grader_randomlists_by_symb{$ressymb})) ||
(ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) {
my ($analysis,$parts) =
@@ -7539,6 +7679,12 @@ SCANTRONFORM
}
}
+ if ($res_error) {
+ &scantron_add_delay(\@delayqueue,$line,
+ 'An error occurred while grading student '.$uname,2);
+ next;
+ }
+
&Apache::lonxml::clear_problem_counter();
&Apache::lonnet::appenv($scan_record);
@@ -7559,7 +7705,6 @@ SCANTRONFORM
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
&ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
&Apache::lonnet::remove_lock($lock);
return ''; # Why return ''? Beats me.
}
@@ -7587,7 +7732,6 @@ SCANTRONFORM
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
&ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
&Apache::lonnet::remove_lock($lock);
delete($completedstudents{$uname});
return '';
@@ -7643,7 +7787,6 @@ SCANTRONFORM
# $r->print("took $lasttime
");
$r->print("");
- $r->print(&show_grading_menu_form($symb));
return '';
}
@@ -7700,7 +7843,7 @@ sub grade_student_bubbles {
}
sub scantron_upload_scantron_data {
- my ($r)=@_;
+ my ($r,$symb)=@_;
my $dom = $env{'request.role.domain'};
my $domdesc = &Apache::lonnet::domain($dom,'description');
$r->print(&Apache::loncommon::coursebrowser_javascript($dom));
@@ -7709,16 +7852,17 @@ sub scantron_upload_scantron_data {
'coursename',$dom);
my $syllabuslink = ''.&mt('Syllabus').' '.
(' 'x2).&mt('(shows course personnel)');
- my $default_form_data=&defaultFormData(&get_symb($r,1));
- $r->print('
-
-
+'));
+ $r->print('
'.&mt('Send scanned bubblesheet data to a course').'
');
return '';
@@ -7768,8 +7912,7 @@ sub scantron_upload_scantron_data {
sub scantron_upload_scantron_data_save {
- my($r)=@_;
- my ($symb)=&get_symb($r,1);
+ my($r,$symb)=@_;
my $doanotherupload=
'
');
- $r->print(&show_grading_menu_form(&get_symb($r,1)));
return;
}
my $orig='/uploaded/'.$cdom.'/'.$cname.'/scantron_orig_'.$file;
@@ -7870,15 +8085,12 @@ sub scantron_download_scantron_data {
'',' ').'
');
- $r->print(&show_grading_menu_form(&get_symb($r,1)));
return '';
}
sub checkscantron_results {
- my ($r) = @_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb) = @_;
if (!$symb) {return '';}
- my $grading_menu_button=&show_grading_menu_form($symb);
my $cid = $env{'request.course.id'};
my %lettdig = &letter_to_digits();
my $numletts = scalar(keys(%lettdig));
@@ -7892,6 +8104,10 @@ sub checkscantron_results {
my $classlist=&Apache::loncoursedata::get_classlist();
my %idmap=&Apache::grades::username_to_idmap($classlist);
my $navmap=Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ $r->print(&navmap_errormsg());
+ return '';
+ }
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
my (%grader_partids_by_symb,%grader_randomlists_by_symb);
@@ -7906,12 +8122,16 @@ sub checkscantron_results {
my %completedstudents;
my $count=&Apache::grades::get_todo_count($scanlines,$scan_data);
- my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Scantron/Submissions Comparison Status',
- 'Progress of Scantron Data/Submission Records Comparison',$count,
+ my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Bubblesheet/Submissions Comparison Status',
+ 'Progress of Bubblesheet Data/Submission Records Comparison',$count,
'inline',undef,'checkscantron');
my ($username,$domain,$started);
-
- &scantron_get_maxbubble(); # Need the bubble lines array to parse.
+ my $nav_error;
+ &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse.
+ if ($nav_error) {
+ $r->print(&navmap_errormsg());
+ return '';
+ }
&Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,
'Processing first student');
@@ -7984,14 +8204,14 @@ sub checkscantron_results {
if ($scandata{$pid} eq $record{$pid}) {
my $css_class = ($passed % 2)?'LC_odd_row':'LC_even_row';
$okstudents .= ''.
-''.&mt('Scantron').' '.$showscandata.' '.$last.' '.$pid.' '."\n".
+''.&mt('Bubblesheet').' '.$showscandata.' '.$last.' '.$pid.' '."\n".
' '."\n".
''."\n".
'Submissions '.$showrecord.' '."\n";
$passed ++;
} else {
my $css_class = ($failed % 2)?'LC_odd_row':'LC_even_row';
- $badstudents .= ''.&mt('Scantron').' '.$scandata{$pid}.' '.$last.' '.$pid.' '."\n".
+ $badstudents .= ''.&mt('Bubblesheet').' '.$scandata{$pid}.' '.$last.' '.$pid.' '."\n".
' '."\n".
''."\n".
'Submissions '.$record{$pid}.' '."\n".
@@ -8002,10 +8222,10 @@ sub checkscantron_results {
}
}
}
- $r->print(''.&mt('Comparison of scantron data (including corrections) with corresponding submission records (most recent submission) for [quant,_1,student] ([_2] scantron lines/student).',$numstudents,$env{'form.scantron_maxbubble'}).'
');
+ $r->print(''.&mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [quant,_1,student] ([_2] scantron lines/student).',$numstudents,$env{'form.scantron_maxbubble'}).'
');
$r->print(''.&mt('Exact matches for [quant,_1,student] .',$passed).' '.&mt('Discrepancies detected for [quant,_1,student] .',$failed).'
');
if ($passed) {
- $r->print(&mt('Students with exact correspondence between scantron data and submissions are as follows:').' ');
+ $r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').' ');
$r->print(&Apache::loncommon::start_data_table()."\n".
&Apache::loncommon::start_data_table_header_row()."\n".
''.&mt('Source').' '.&mt('Bubble records').' '.&mt('Name').' '.&mt('ID').' '.
@@ -8014,16 +8234,16 @@ sub checkscantron_results {
&Apache::loncommon::end_data_table().' ');
}
if ($failed) {
- $r->print(&mt('Students with differences between scantron data and submissions are as follows:').' ');
+ $r->print(&mt('Students with differences between bubblesheet data and submissions are as follows:').' ');
$r->print(&Apache::loncommon::start_data_table()."\n".
&Apache::loncommon::start_data_table_header_row()."\n".
''.&mt('Source').' '.&mt('Bubble records').' '.&mt('Name').' '.&mt('ID').' '.
&Apache::loncommon::end_data_table_header_row()."\n".
$badstudents."\n".
&Apache::loncommon::end_data_table()).' '.
- &mt('Differences can occur if submissions were modified using manual grading after a scantron grading pass.').' '.&mt('If unexpected discrepancies were detected, it is recommended that you inspect the original scantron sheets.');
+ &mt('Differences can occur if submissions were modified using manual grading after a bubblesheet grading pass.').' '.&mt('If unexpected discrepancies were detected, it is recommended that you inspect the original bubblesheets.');
}
- $r->print(' '.$grading_menu_button);
+ $r->print(' ');
return;
}
@@ -8165,48 +8385,34 @@ sub letter_to_digits {
#-------------------------- Menu interface -------------------------
#
-#--- Show a Grading Menu button - Calls the next routine ---
-sub show_grading_menu_form {
- my ($symb)=@_;
- my $result.=' '."\n";
- return $result;
-}
+#--- Href with symb and command ---
-# -- Retrieve choices for grading form
-sub savedState {
- my %savedState = ();
- if ($env{'form.saveState'}) {
- foreach (split(/:/,$env{'form.saveState'})) {
- my ($key,$value) = split(/=/,$_,2);
- $savedState{$key} = $value;
- }
- }
- return \%savedState;
+sub href_symb_cmd {
+ my ($symb,$cmd)=@_;
+ return '/adm/grades?symb='.&HTML::Entities::encode(&Apache::lonenc::check_encrypt($symb),'<>&"').'&command='.$cmd;
}
sub grading_menu {
- my ($request) = @_;
- my ($symb)=&get_symb($request);
+ my ($request,$symb) = @_;
if (!$symb) {return '';}
- my $probTitle = &Apache::lonnet::gettitle($symb);
- my ($table,undef,$hdgrade) = &showResourceInfo($symb,$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 $url1 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
+ 'command'=>'individual');
+ my $url1a = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
+
+ $fields{'command'}='ungraded';
+ my $url1b=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
+
+ $fields{'command'}='table';
+ my $url1c=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
+
+ $fields{'command'}='all_for_one';
+ my $url1d=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
+
+ $fields{'command'}='downloadfilesselect';
+ my $url1e=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
+
$fields{'command'} = 'csvform';
my $url2 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
@@ -8215,15 +8421,46 @@ sub grading_menu {
$fields{'command'} = 'scantron_selectphase';
my $url4 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
+
+ $fields{'command'} = 'initialverifyreceipt';
+ my $url5 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
- my @menu = ({ categorytitle=>'Course Grading',
+ my @menu = ({ categorytitle=>'Hand Grading',
items =>[
- { linktext => 'Manual Grading/View Submissions',
- url => $url1,
+ { linktext => 'Select individual students to grade',
+ url => $url1a,
permission => 'F',
- icon => 'edit-find-replace.png',
- linktitle => 'Start the process of hand grading submissions.'
+ icon => 'grade_students.png',
+ linktitle => 'Grade current resource for a selection of students.'
+ },
+ { linktext => 'Grade ungraded submissions.',
+ url => $url1b,
+ permission => 'F',
+ icon => 'ungrade_sub.png',
+ linktitle => 'Grade all submissions that have not been graded yet.'
},
+
+ { linktext => 'Grading table',
+ url => $url1c,
+ permission => 'F',
+ icon => 'grading_table.png',
+ linktitle => 'Grade current resource for all students.'
+ },
+ { linktext => 'Grade page/folder for one student',
+ url => $url1d,
+ permission => 'F',
+ icon => 'grade_PageFolder.png',
+ linktitle => 'Grade all resources in current page/sequence/folder for one student.'
+ },
+ { linktext => 'Download submissions',
+ url => $url1e,
+ permission => 'F',
+ icon => 'download_sub.png',
+ linktitle => 'Download all students submissions.'
+ }]},
+ { categorytitle=>'Automated Grading',
+ items =>[
+
{ linktext => 'Upload Scores',
url => $url2,
permission => 'F',
@@ -8236,171 +8473,135 @@ sub grading_menu {
icon => 'addClickerInfoFile.png',
linktitle => 'Specify a file containing the clicker information for this resource.'
},
- { linktext => 'Grade/Manage/Review Scantron Forms',
+ { linktext => 'Grade/Manage/Review Bubblesheets',
url => $url4,
permission => 'F',
- icon => 'stat.png',
+ icon => 'bubblesheet.png',
linktitle => 'Grade scantron exams, upload/download scantron data files, and review previously graded scantron exams.'
- }
+ },
+ { linktext => 'Verify Receipt Number',
+ url => $url5,
+ permission => 'F',
+ icon => 'receipt_number.png',
+ linktitle => 'Verify a system-generated receipt number for correct problem solution.'
+ }
+
]
});
- #$fields{'command'} = 'verify';
- #$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
- #
# Create the menu
my $Str;
- # $Str .= ''.&mt('Please select a grading task').' ';
$Str .= '\n";
- my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");
- $request->print(<
- 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;
- if (val < 5) formname.submit();
- if (val == 5) {
- if (!checkReceiptNo(formname,'notOK')) {
- return false;
- } else {
- formname.submit();
- }
- }
- }
+ $Str .= &Apache::lonhtmlcommon::generate_menu(@menu);
+ return $Str;
+}
- 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("$receiptalert");
- formname.receipt.value = "";
- formname.receipt.focus();
- return false;
- }
- return true;
- }
-
-GRADINGMENUJS
+
+sub ungraded {
+ my ($request)=@_;
+ &submit_options($request);
+}
+
+sub submit_options_sequence {
+ my ($request,$symb) = @_;
+ if (!$symb) {return '';}
&commonJSfunctions($request);
- return $Str;
+ my $result;
+
+ $result.='';
+ return $result;
}
+sub submit_options_table {
+ my ($request,$symb) = @_;
+ if (!$symb) {return '';}
+ &commonJSfunctions($request);
+ my $result;
+
+ $result.='';
+ return $result;
+}
+
+sub submit_options_download {
+ my ($request,$symb) = @_;
+ if (!$symb) {return '';}
+
+ &commonJSfunctions($request);
+
+ my $result='';
+ return $result;
+}
#--- Displays the submissions first page -------
sub submit_options {
- my ($request) = @_;
- my ($symb)=&get_symb($request);
+ my ($request,$symb) = @_;
if (!$symb) {return '';}
- my $probTitle = &Apache::lonnet::gettitle($symb);
- my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");
- $request->print(<
- 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 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("$receiptalert");
- formname.receipt.value = "";
- formname.receipt.focus();
- return false;
- }
- return true;
- }
-
-GRADINGMENUJS
&commonJSfunctions($request);
- my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle);
my $result;
- 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'});
-
- # Preselect sections
- my $selsec="";
- if (ref($sections)) {
- foreach my $section (sort(@$sections)) {
- $selsec.=''.$section.' '."\n";
- }
- }
$result.=''.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
+ return $result;
}
sub iclicker_eval {
@@ -8901,22 +9059,22 @@ sub interwrite_eval {
}
sub assign_clicker_grades {
- my ($r)=@_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb)=@_;
if (!$symb) {return '';}
# See which part we are saving to
- my ($partlist,$handgrade,$responseType) = &response_type($symb);
+ my $res_error;
+ my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error);
+ if ($res_error) {
+ return &navmap_errormsg();
+ }
# FIXME: This should probably look for the first handgradeable part
my $part=$$partlist[0];
# Start screen output
- my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});
-
- my $heading=&mt('Assigning grades based on clicker file');
- $result.=(<
-
-$heading
-ENDHEADER
+ my $result=&Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ' '.&mt('Assigning grades based on clicker file').' '.
+ &Apache::loncommon::end_data_table_header_row().
+ &Apache::loncommon::start_data_table_row().'';
# Get correct result
# FIXME: Possibly need delimiter other than ":"
my @correct=();
@@ -8951,6 +9109,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\:(.*)$/) {
@@ -8964,18 +9123,24 @@ ENDHEADER
$user=$env{'form.multi'.$id};
}
}
- if ($user) {
+ if ($user) {
+ if ($users{$user}) {
+ $result.=''.
+ &mt("More than one entry found for [_1] !",$user).
+ ' ';
+ }
+ $users{$user}=1;
my @answer=split(/\,/,$env{$key});
my $sum=0;
my $realnumber=$number;
for (my $i=0;$i<$number;$i++) {
- if ($answer[$i]) {
+ if ($correct[$i] eq '-') {
+ $realnumber--;
+ } elsif ($answer[$i]) {
if ($gradingmechanism eq 'attendance') {
$sum+=$pcorrect;
- } elsif ($answer[$i] eq '*') {
+ } elsif ($correct[$i] eq '*') {
$sum+=$pcorrect;
- } elsif ($answer[$i] eq '-') {
- $realnumber--;
} else {
if ($answer[$i] eq $correct[$i]) {
$sum+=$pcorrect;
@@ -9004,9 +9169,36 @@ ENDHEADER
}
# We are done
$result.=' '.&mt('Successfully stored grades for [quant,_1,student].',$storecount).
- '
'."\n".
- '
'."\n";
- return $result.&show_grading_menu_form($symb);
+ ''.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
+ return $result;
+}
+
+sub navmap_errormsg {
+ return ''.
+ &mt('An error occurred retrieving information about resources in the course.').'
'.
+ &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this grading page.','
',' ').
+ '
';
+}
+
+sub startpage {
+ my ($r,$symb,$crumbs,$onlyfolderflag,$nodisplayflag) = @_;
+ unshift(@$crumbs,{href=>&href_symb_cmd($symb,'gradingmenu'),text=>"Grading"});
+ $r->print(&Apache::loncommon::start_page('Grading',undef,
+ {'bread_crumbs' => $crumbs}));
+ &Apache::lonquickgrades::startGradeScreen($r,'grading');
+ unless ($nodisplayflag) {
+ $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag));
+ }
+}
+
+sub select_problem {
+ my ($r)=@_;
+ $r->print(''.&mt('Select the problem or one of the problems you want to grade').' ');
+ $r->print(&Apache::lonstathelpers::problem_selector('.',undef,1));
+ $r->print(' ');
+ $r->print(' ');
}
sub handler {
@@ -9020,7 +9212,9 @@ sub handler {
$request->send_http_header;
return '' if $request->header_only;
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
- my $symb=&get_symb($request,1);
+
+# see what command we need to execute
+
my @commands=&Apache::loncommon::get_env_multiple('form.command');
my $command=$commands[0];
@@ -9028,113 +9222,165 @@ sub handler {
&Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));
}
+# see what the symb is
+
+ my $symb=$env{'form.symb'};
+ unless ($symb) {
+ (my $url=$env{'form.url'}) =~ s-^https*://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
+ $symb=&Apache::lonnet::symbread($url);
+ }
+ &Apache::lonenc::check_decrypt(\$symb);
+
$ssi_error = 0;
- my $brcrum = [{href=>"/adm/grades",text=>"Grading"}];
- $request->print(&Apache::loncommon::start_page('Grading',undef,
- {'bread_crumbs' => $brcrum}));
- if ($symb eq '' && $command eq '') {
- if ($env{'user.adv'}) {
- if (($env{'form.codeone'}) && ($env{'form.codetwo'}) &&
- ($env{'form.codethree'})) {
- my $token=$env{'form.codeone'}.'*'.$env{'form.codetwo'}.'*'.
- $env{'form.codethree'};
- my ($tsymb,$tuname,$tudom,$tcrsid)=
- &Apache::lonnet::checkin($token);
- if ($tsymb) {
- my ($map,$id,$url)=&Apache::lonnet::decode_symb($tsymb);
- if (&Apache::lonnet::allowed('mgr',$tcrsid)) {
- $request->print(&ssi_with_retries('/res/'.$url, $ssi_retries,
- ('grade_username' => $tuname,
- 'grade_domain' => $tudom,
- 'grade_courseid' => $tcrsid,
- 'grade_symb' => $tsymb)));
- } else {
- $request->print('Not authorized: '.$token.' ');
- }
- } else {
- $request->print('Not a valid DocID: '.$token.' ');
- }
- } else {
- $request->print(&Apache::lonxml::tokeninputfield());
- }
- }
+ if (($symb eq '' || $command eq '') && ($env{'request.course.id'})) {
+#
+# Not called from a resource, but inside a course
+#
+ &startpage($request,undef,[],1,1);
+ &select_problem($request);
} else {
&init_perm();
if ($command eq 'submission' && $perm{'vgr'}) {
- ($env{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));
+ &startpage($request,$symb,[{href=>"", text=>"Student Submissions"}]);
+ ($env{'form.student'} eq '' ? &listStudents($request,$symb) : &submission($request,0,0,$symb));
} elsif ($command eq 'pickStudentPage' && $perm{'vgr'}) {
- &pickStudentPage($request);
+ &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
+ {href=>'',text=>'Select student'}],1,1);
+ &pickStudentPage($request,$symb);
} elsif ($command eq 'displayPage' && $perm{'vgr'}) {
- &displayPage($request);
+ &startpage($request,$symb,
+ [{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
+ {href=>'',text=>'Select student'},
+ {href=>'',text=>'Grade student'}],1,1);
+ &displayPage($request,$symb);
} elsif ($command eq 'gradeByPage' && $perm{'mgr'}) {
- &updateGradeByPage($request);
+ &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'all_for_one'),text=>'Grade page/folder for one student'},
+ {href=>'',text=>'Select student'},
+ {href=>'',text=>'Grade student'},
+ {href=>'',text=>'Store grades'}],1,1);
+ &updateGradeByPage($request,$symb);
} elsif ($command eq 'processGroup' && $perm{'vgr'}) {
- &processGroup($request);
+ &startpage($request,$symb,[{href=>'',text=>'...'},
+ {href=>'',text=>'Modify grades'}]);
+ &processGroup($request,$symb);
} elsif ($command eq 'gradingmenu' && $perm{'vgr'}) {
- $request->print(&grading_menu($request));
- } elsif ($command eq 'submit_options' && $perm{'vgr'}) {
- $request->print(&submit_options($request));
+ &startpage($request,$symb);
+ $request->print(&grading_menu($request,$symb));
+ } elsif ($command eq 'individual' && $perm{'vgr'}) {
+ &startpage($request,$symb,[{href=>'',text=>'Select individual students to grade'}]);
+ $request->print(&submit_options($request,$symb));
+ } elsif ($command eq 'ungraded' && $perm{'vgr'}) {
+ &startpage($request,$symb,[{href=>'',text=>'Grade ungraded submissions'}]);
+ $request->print(&listStudents($request,$symb,'graded'));
+ } elsif ($command eq 'table' && $perm{'vgr'}) {
+ &startpage($request,$symb,[{href=>"", text=>"Grading table"}]);
+ $request->print(&submit_options_table($request,$symb));
+ } elsif ($command eq 'all_for_one' && $perm{'vgr'}) {
+ &startpage($request,$symb,[{href=>'',text=>'Grade page/folder for one student'}],1,1);
+ $request->print(&submit_options_sequence($request,$symb));
} elsif ($command eq 'viewgrades' && $perm{'vgr'}) {
- $request->print(&viewgrades($request));
+ &startpage($request,$symb,[{href=>&href_symb_cmd($symb,"table"), text=>"Grading table"},{href=>'', text=>"Modify grades"}]);
+ $request->print(&viewgrades($request,$symb));
} elsif ($command eq 'handgrade' && $perm{'mgr'}) {
- $request->print(&processHandGrade($request));
+ &startpage($request,$symb,[{href=>'',text=>'...'},
+ {href=>'',text=>'Store grades'}]);
+ $request->print(&processHandGrade($request,$symb));
} elsif ($command eq 'editgrades' && $perm{'mgr'}) {
- $request->print(&editgrades($request));
+ &startpage($request,$symb,[{href=>&href_symb_cmd($symb,"table"), text=>"Grading table"},
+ {href=>&href_symb_cmd($symb,'viewgrades').'&group=all§ion=all&Status=Active',
+ text=>"Modify grades"},
+ {href=>'', text=>"Store grades"}]);
+ $request->print(&editgrades($request,$symb));
+ } elsif ($command eq 'initialverifyreceipt' && $perm{'vgr'}) {
+ &startpage($request,$symb,[{href=>'',text=>'Verify Receipt Number'}]);
+ $request->print(&initialverifyreceipt($request,$symb));
} elsif ($command eq 'verify' && $perm{'vgr'}) {
- $request->print(&verifyreceipt($request));
+ &startpage($request,$symb,[{href=>&href_symb_cmd($symb,"initialverifyreceipt"),text=>'Verify Receipt Number'},
+ {href=>'',text=>'Verification Result'}]);
+ $request->print(&verifyreceipt($request,$symb));
} elsif ($command eq 'processclicker' && $perm{'mgr'}) {
- $request->print(&process_clicker($request));
+ &startpage($request,$symb,[{href=>'', text=>'Process clicker'}]);
+ $request->print(&process_clicker($request,$symb));
} elsif ($command eq 'processclickerfile' && $perm{'mgr'}) {
- $request->print(&process_clicker_file($request));
+ &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'processclicker'), text=>'Process clicker'},
+ {href=>'', text=>'Process clicker file'}]);
+ $request->print(&process_clicker_file($request,$symb));
} elsif ($command eq 'assignclickergrades' && $perm{'mgr'}) {
- $request->print(&assign_clicker_grades($request));
+ &startpage($request,$symb,[{href=>&href_symb_cmd($symb,'processclicker'), text=>'Process clicker'},
+ {href=>'', text=>'Process clicker file'},
+ {href=>'', text=>'Store grades'}]);
+ $request->print(&assign_clicker_grades($request,$symb));
} elsif ($command eq 'csvform' && $perm{'mgr'}) {
- $request->print(&upcsvScores_form($request));
+ &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
+ $request->print(&upcsvScores_form($request,$symb));
} elsif ($command eq 'csvupload' && $perm{'mgr'}) {
- $request->print(&csvupload($request));
+ &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
+ $request->print(&csvupload($request,$symb));
} elsif ($command eq 'csvuploadmap' && $perm{'mgr'} ) {
- $request->print(&csvuploadmap($request));
+ &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
+ $request->print(&csvuploadmap($request,$symb));
} elsif ($command eq 'csvuploadoptions' && $perm{'mgr'}) {
if ($env{'form.associate'} ne 'Reverse Association') {
- $request->print(&csvuploadoptions($request));
+ &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
+ $request->print(&csvuploadoptions($request,$symb));
} else {
if ( $env{'form.upfile_associate'} ne 'reverse' ) {
$env{'form.upfile_associate'} = 'reverse';
} else {
$env{'form.upfile_associate'} = 'forward';
}
- $request->print(&csvuploadmap($request));
+ &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
+ $request->print(&csvuploadmap($request,$symb));
}
} elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) {
- $request->print(&csvuploadassign($request));
+ &startpage($request,$symb,[{href=>'', text=>'Upload Scores'}],1,1);
+ $request->print(&csvuploadassign($request,$symb));
} elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) {
- $request->print(&scantron_selectphase($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&scantron_selectphase($request,undef,$symb));
} elsif ($command eq 'scantron_warning' && $perm{'mgr'}) {
- $request->print(&scantron_do_warning($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&scantron_do_warning($request,$symb));
} elsif ($command eq 'scantron_validate' && $perm{'mgr'}) {
- $request->print(&scantron_validate_file($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&scantron_validate_file($request,$symb));
} elsif ($command eq 'scantron_process' && $perm{'mgr'}) {
- $request->print(&scantron_process_students($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&scantron_process_students($request,$symb));
} elsif ($command eq 'scantronupload' &&
(&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||
&Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {
- $request->print(&scantron_upload_scantron_data($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&scantron_upload_scantron_data($request,$symb));
} elsif ($command eq 'scantronupload_save' &&
(&Apache::lonnet::allowed('usc',$env{'request.role.domain'})||
&Apache::lonnet::allowed('usc',$env{'request.course.id'}))) {
- $request->print(&scantron_upload_scantron_data_save($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&scantron_upload_scantron_data_save($request,$symb));
} elsif ($command eq 'scantron_download' &&
&Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
- $request->print(&scantron_download_scantron_data($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&scantron_download_scantron_data($request,$symb));
} elsif ($command eq 'checksubmissions' && $perm{'vgr'}) {
- $request->print(&checkscantron_results($request));
+ &startpage($request,$symb,[{href=>'', text=>'Grade/Manage/Review Bubblesheets'}],1,1);
+ $request->print(&checkscantron_results($request,$symb));
+ } elsif ($command eq 'downloadfilesselect' && $perm{'vgr'}) {
+ &startpage($request,$symb,[{href=>'', text=>'Select which submissions to download'}]);
+ $request->print(&submit_options_download($request,$symb));
+ } elsif ($command eq 'downloadfileslink' && $perm{'vgr'}) {
+ &startpage($request,$symb,
+ [{href=>&href_symb_cmd($symb,'downloadfilesselect'), text=>'Select which submissions to download'},
+ {href=>'', text=>'Download submissions'}]);
+ &submit_download_link($request,$symb);
} elsif ($command) {
+ &startpage($request,$symb,[{href=>'', text=>'Access denied'}]);
$request->print(''.&mt('Access Denied ([_1])',$command).'
');
}
}
if ($ssi_error) {
&ssi_print_error($request);
}
+ &Apache::lonquickgrades::endGradeScreen($request);
$request->print(&Apache::loncommon::end_page());
&reset_caches();
return '';
@@ -9234,6 +9480,13 @@ ssi_with_retries()
=item scantron_get_maxbubble() :
+ Arguments:
+ $nav_error - Reference to scalar which is a flag to indicate a
+ failure to retrieve a navmap object.
+ if $nav_error is set to 1 by scantron_get_maxbubble(), the
+ calling routine should trap the error condition and display the warning
+ found in &navmap_errormsg().
+
Returns the maximum number of bubble lines that are expected to
occur. Does this by walking the selected sequence rendering the
resource and then checking &Apache::lonxml::get_problem_counter()
@@ -9299,6 +9552,11 @@ ssi_with_retries()
Validates all scanlines in the selected file to not have any
invalid or underspecified student/employee IDs
+=item navmap_errormsg() :
+
+ Returns HTML mark-up inside a
with a link to re-initialize the course.
+ Should be called whenever the request to instantiate a navmap object fails.
+
=back
=cut