new_window = true;
+$labeltext
+
+
+NEW_WINDOW_CHECKBOX
+ }
+
#
$r->print("".$env{'course.'.$env{'request.course.id'}.'.description'}.
" ".localtime(time)." ");
#
if ($chosen_output->{'base'} !~ /^final table/) {
- $r->print("".$chosen_output->{'shortdesc'}." ");
+ $r->print("".&mt($chosen_output->{'shortdesc'})." ");
}
my $Str = "\n";
# First, the @StudentData fields need to be listed
@@ -710,6 +749,58 @@ sub html_initialize {
$Str .= "";
$r->print($Str);
$r->rflush();
+
+ $r->print(<
+// get the left offset of a given widget as an absolute position
+function getLeftOffset (element) {
+ return collect(element, "offsetLeft");
+}
+
+// get the top offset of a given widget as an absolute position
+function getTopOffset (element) {
+ return collect(element, "offsetTop");
+}
+
+function collect(element, att) {
+ var val = 0;
+ while(element) {
+ val += element[att];
+ element = element.offsetParent;
+ }
+ return val;
+}
+
+var currentDiv;
+var currentElement;
+function popup_score(element, score) {
+ popdown_score();
+ var left = getLeftOffset(element);
+ var top = getTopOffset(element);
+ var div = document.createElement("div");
+ div.className = "LC_chrt_popup";
+ div.appendChild(document.createTextNode(score));
+ div.style.position = "absolute";
+ div.style.top = (top - 25) + "px";
+ div.style.left = (left - 10) + "px";
+ currentDiv = div;
+ document.body.insertBefore(div, document.body.childNodes[0]);
+ element.className = "LC_chrt_popup_up";
+ currentElement = element;
+}
+
+function popdown_score() {
+ if (currentDiv) {
+ document.body.removeChild(currentDiv);
+ }
+ if (currentElement) {
+ currentElement.className = 'LC_chrt_popup_exists';
+ }
+ currentDiv = undefined;
+}
+
+JS
+
#
# Let the user know what we are doing
my $studentcount = scalar(@Apache::lonstatistics::Students);
@@ -753,12 +844,20 @@ sub html_outputstudent {
my @tmp = &Apache::loncoursedata::get_current_state
($student->{'username'},$student->{'domain'},undef,
$env{'request.course.id'});
- if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:/)) {
+ if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:(.*)/)) {
%StudentsData = @tmp;
- }
- if (scalar(@tmp) < 1) {
+ } else {
+ my $error = $1;
+ if (scalar(@tmp) < 1) {
+ $Str .= ''
+ .&mt('No Course Data')
+ .' '."\n";
+ } else {
+ $Str .= ''
+ .&mt('Error getting student data ([_1])',$error)
+ .' '."\n";
+ }
$nodata_count++;
- $Str .= 'No Course Data '."\n";
$r->print($Str);
$r->rflush();
return;
@@ -777,7 +876,8 @@ sub html_outputstudent {
} else {
($performance,$performance_length,$score,$seq_max,$rawdata) =
&student_performance_on_sequence($student,\%StudentsData,
- $navmap,$seq,$show_links);
+ $navmap,$seq,$show_links,
+ $chosen_output->{ignore_weight});
}
my $ratio='';
if ($chosen_output->{'every_problem'} &&
@@ -856,18 +956,18 @@ sub html_finish {
}
$r->rflush();
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
- undef($navmap);
+ &html_cleanup();
return;
}
sub StudentAverageTotal {
my $Str = ''.&mt('Summary Tables').' '.$/;
- $Str .= ''."\n";
- $Str .= ''.
+ $Str .= &Apache::loncommon::start_data_table();
+ $Str .= &Apache::loncommon::start_data_table_header_row().
''.&mt('Title').' '.
''.&mt('Average').' '.
''.&mt('Maximum').' '.
- ' '.$/;
+ &Apache::loncommon::end_data_table_header_row().$/;
foreach my $seq (@sequences) {
my $symb = $seq->symb;
my $ave;
@@ -881,11 +981,13 @@ sub StudentAverageTotal {
}
my $max = $Statistics->{$symb}->{'max'};
$ave = sprintf("%.2f",$ave);
- $Str .= ''.$seq->compTitle.' '.
+ $Str .= &Apache::loncommon::start_data_table_row().
+ ''.$seq->compTitle.' '.
''.$ave.' '.
- ''.$max.' '.' '."\n";
+ ''.$max.' '.' '.
+ &Apache::loncommon::end_data_table_row()."\n";
}
- $Str .= "
\n";
+ $Str .= &Apache::loncommon::end_data_table()."\n";
return $Str;
}
@@ -896,31 +998,36 @@ sub SingleStudentTotal {
$student->{'fullname'},
$student->{'username'},$student->{'domain'}).'';
$Str .= $/;
- $Str .= ''."\n";
+ $Str .= &Apache::loncommon::start_data_table()."\n";
$Str .=
- ''.
+ &Apache::loncommon::start_data_table_header_row().
''.&mt('Sequence or Folder').' ';
if ($chosen_output->{'base'} eq 'tries') {
$Str .= ''.&mt('Parts Correct').' ';
} else {
$Str .= ''.&mt('Score').' ';
}
- $Str .= ''.&mt('Maximum').' '." \n";
+ $Str .= ''.&mt('Maximum').' '.
+ &Apache::loncommon::end_data_table_header_row()."\n";
my $total = 0;
my $total_max = 0;
foreach my $seq (@sequences) {
my $value = $Statistics->{$seq->symb}->{'score'};
my $max = $Statistics->{$seq->symb}->{'max'};
- $Str .= ''.&HTML::Entities::encode($seq->compTitle).' '.
+ $Str .= &Apache::loncommon::start_data_table_row().
+ ''.&HTML::Entities::encode($seq->compTitle).' '.
''.$value.' '.
- ''.$max.' '."\n";
+ ''.$max.' '.
+ &Apache::loncommon::end_data_table_row()."\n";
$total += $value;
$total_max +=$max;
}
- $Str .= ''.&mt('Total').' '.
+ $Str .= &Apache::loncommon::start_data_table_row().
+ ''.&mt('Total').' '.
''.$total.' '.
- ''.$total_max." \n";
- $Str .= "
\n";
+ ''.$total_max.' '.
+ &Apache::loncommon::end_data_table_row()."\n";
+ $Str .= &Apache::loncommon::end_data_table()."\n";
return $Str;
}
@@ -963,8 +1070,7 @@ my %formula_data;
my $navmap;
my @sequences;
-sub excel_initialize {
- my ($r) = @_;
+sub excel_cleanup {
#
undef ($excel_sheet);
undef ($excel_workbook);
@@ -980,6 +1086,12 @@ sub excel_initialize {
#
undef($navmap);
undef(@sequences);
+}
+
+sub excel_initialize {
+ my ($r) = @_;
+
+ &excel_cleanup();
($navmap,@sequences) =
&Apache::lonstatistics::selected_sequences_with_assessments();
if (! ref($navmap)) {
@@ -1135,9 +1247,11 @@ sub excel_initialize {
! defined($formula_data{$symb}->{'Excel:endcell'})) {
$formula_data{$symb}->{'Excel:endcell'} = $formula_data{$symb}->{'Excel:startcell'};
}
+
+ my $start = $formula_data{$symb}->{'Excel:startcell'};
+ my $end = $formula_data{$symb}->{'Excel:endcell'};
$formula_data{$symb}->{'Excel:sum'}= $excel_sheet->store_formula
- ('=SUM('.$formula_data{$symb}->{'Excel:startcell'}.
- ':'.$formula_data{$symb}->{'Excel:endcell'}.')');
+ ("=IF(COUNT($start\:$end),SUM($start\:$end),\"\")");
# Determine cell the score is held in
$formula_data{$symb}->{'Excel:scorecell'} =
&Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell
@@ -1222,7 +1336,7 @@ sub excel_initialize {
$weight = 1;
if ($chosen_output->{'scores'}) {
$weight = &Apache::lonnet::EXT
- ('resource.'.$part.'.weight',$resource->{'symb'},
+ ('resource.'.$part.'.weight',$resource->symb,
undef,undef,undef);
if (!defined($weight) || ($weight eq '')) {
$weight=1;
@@ -1246,7 +1360,7 @@ sub excel_initialize {
&Spreadsheet::WriteExcel::Utility::xl_rowcol_to_cell($maximum_data_row,$formula_data{$symb}->{'Excel:endcol'}));
$excel_sheet->repeat_formula($maximum_data_row,$cols_output++,
$formula_data{$symb}->{'Excel:sum'},undef,
- %replaceCells);
+ %replaceCells, %replaceCells);
} elsif ($chosen_output->{'sequence_sum'}) {
$excel_sheet->write($maximum_data_row,$cols_output++,$max);
@@ -1357,7 +1471,7 @@ sub excel_outputstudent {
foreach my $field (@to_show) {
my $value = $student->{$field};
if ($field eq 'comments') {
- $value = &Apache::lonmsg::retrieve_instructor_comments
+ $value = &Apache::lonmsgdisplay::retrieve_instructor_comments
($student->{'username'},$student->{'domain'});
}
$excel_sheet->write($rows_output,$cols_output++,$value);
@@ -1396,14 +1510,16 @@ sub excel_outputstudent {
} else {
($performance,$performance_length,$score,$seq_max,$rawdata) =
&student_performance_on_sequence($student,\%StudentsData,
- $navmap,$seq,'no');
+ $navmap,$seq,'no',
+ $chosen_output->{ignore_weight});
}
if ($chosen_output->{'every_problem'}) {
if ($chosen_output->{'correct'}) {
# only indiciate if each item is correct or not
foreach my $value (@$rawdata) {
- # nonzero means correct
- $value = 1 if ($value > 0);
+ # positive means correct, 0 or negative means
+ # incorrect
+ $value = $value > 0 ? 1 : 0;
$excel_sheet->write($rows_output,$cols_output++,$value);
}
} else {
@@ -1429,7 +1545,7 @@ sub excel_outputstudent {
# The undef is for the format
$excel_sheet->repeat_formula($rows_output,$cols_output++,
$formula_data{$symb}->{'Excel:sum'},undef,
- %replaceCells);
+ %replaceCells, %replaceCells);
} elsif ($chosen_output->{'sequence_sum'}) {
if ($score eq ' ') {
$cols_output++;
@@ -1465,14 +1581,12 @@ sub excel_outputstudent {
sub excel_finish {
my ($r) = @_;
if ($request_aborted || ! defined($navmap) || ! defined($excel_sheet)) {
+ &excel_cleanup();
return;
}
#
# Write the excel file
$excel_workbook->close();
- my $c = $r->connection();
- #
- return if($c->aborted());
#
# Close the progress window
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
@@ -1481,6 +1595,7 @@ sub excel_finish {
$r->print(' '.
'Your Excel spreadsheet. '."\n");
$r->rflush();
+ &excel_cleanup();
return;
}
@@ -1511,10 +1626,7 @@ my %prog_state; # progress window state
my $navmap;
my @sequences;
-sub csv_initialize{
- my ($r) = @_;
- #
- # Clean up
+sub csv_cleanup {
undef($outputfile);
undef($filename);
undef($request_aborted);
@@ -1522,6 +1634,12 @@ sub csv_initialize{
#
undef($navmap);
undef(@sequences);
+}
+
+sub csv_initialize{
+ my ($r) = @_;
+
+ &csv_cleanup();
($navmap,@sequences) =
&Apache::lonstatistics::selected_sequences_with_assessments();
if (! ref($navmap)) {
@@ -1635,7 +1753,7 @@ sub csv_outputstudent {
foreach my $field (@to_show) {
my $value = $student->{$field};
if ($field eq 'comments') {
- $value = &Apache::lonmsg::retrieve_instructor_comments
+ $value = &Apache::lonmsgdisplay::retrieve_instructor_comments
($student->{'username'},$student->{'domain'});
}
$Str .= '"'.&Apache::loncommon::csv_translate($value).'",';
@@ -1663,7 +1781,8 @@ sub csv_outputstudent {
} else {
($performance,$performance_length,$score,$seq_max,$rawdata) =
&student_performance_on_sequence($student,\%StudentsData,
- $navmap,$seq,'no');
+ $navmap,$seq,'no',
+ $chosen_output->{ignore_weight});
}
if ($chosen_output->{'every_problem'}) {
if ($chosen_output->{'correct'}) {
@@ -1707,26 +1826,37 @@ sub csv_outputstudent {
sub csv_finish {
my ($r) = @_;
if ($request_aborted || ! defined($navmap) || ! defined($outputfile)) {
+ &csv_cleanup();
return;
}
close($outputfile);
#
- my $c = $r->connection();
- return if ($c->aborted());
- #
# Close the progress window
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
#
# Tell the user where to get their csv file
$r->print(' '.
- ''.&mt('Your csv file.').' '."\n");
+ ''.&mt('Your CSV file.').' '."\n");
$r->rflush();
+ &csv_cleanup();
return;
}
}
+# This function will return an HTML string including a star, with
+# a mouseover popup showing the "real" value. An optional second
+# argument lets you show something other than a star.
+sub show_star {
+ my $popup = shift;
+ my $symbol = shift || '*';
+ # Escape the popup for JS.
+ $popup =~ s/([^-a-zA-Z0-9:;,._ ()|!\/?=&*])/'\\' . sprintf("%lo", ord($1))/ge;
+
+ return "";
+}
+
#######################################################
#######################################################
@@ -1792,12 +1922,12 @@ sub student_tries_on_sequence {
if ($status eq 'excused') {
$symbol = 'x';
$max--;
- } elsif ($status eq 'correct_by_override') {
+ } elsif ($status eq 'correct_by_override' && !$resource->is_task()) {
$symbol = '+';
$sum++;
} elsif ($tries > 0) {
if ($tries > 9) {
- $symbol = '*';
+ $symbol = show_star($tries);
} else {
$symbol = $tries;
}
@@ -1837,14 +1967,12 @@ sub student_tries_on_sequence {
#
if ( ($links eq 'yes' && $symbol ne ' ') ||
($links eq 'all')) {
- if (length($symbol) > 1) {
- &Apache::lonnet::logthis('length of symbol "'.$symbol.'" > 1');
- }
- $symbol = ''.$symbol.' ';
+ '&command=submission';
+ $symbol = &link($symbol, $link);
}
$value .= $symbol;
}
@@ -1859,6 +1987,37 @@ sub student_tries_on_sequence {
return ($Str,$performance_length,$sum,$max,\@TriesData);
}
+=pod
+
+=item &link
+
+Inputs:
+
+=over 4
+
+=item $text
+
+=item $target
+
+=back
+
+Takes the text and creates a link to the $text that honors
+the value of 'new window' if clicked on, but uses a real
+'href' so middle and right clicks still work.
+
+$target and $text are assumed to be already correctly escaped; i.e., it
+can be dumped out directly into the output stream as-is.
+
+=cut
+
+sub link {
+ my ($text,$target) = @_;
+ return
+ "$text ";
+}
+
#######################################################
#######################################################
@@ -1885,7 +2044,7 @@ Inputs:
#######################################################
#######################################################
sub student_performance_on_sequence {
- my ($student,$studentdata,$navmap,$seq,$links) = @_;
+ my ($student,$studentdata,$navmap,$seq,$links,$awarded_only) = @_;
$links = 'no' if (! defined($links));
my $Str = ''; # final result string
my ($score,$max) = (0,0);
@@ -1899,11 +2058,14 @@ sub student_performance_on_sequence {
my $resource_data = $studentdata->{$symb};
foreach my $part (@{$resource->parts()}) {
$partscore = undef;
- my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',
- $symb,
- $student->{'domain'},
- $student->{'username'},
- $student->{'section'});
+ my $weight;
+ if (!$awarded_only){
+ $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight',
+ $symb,
+ $student->{'domain'},
+ $student->{'username'},
+ $student->{'section'});
+ }
if (!defined($weight) || ($weight eq '')) {
$weight=1;
}
@@ -1919,7 +2081,7 @@ sub student_performance_on_sequence {
$hasdata = 1;
}
#
- $partscore = $weight*$awarded;
+ $partscore = &Apache::grades::compute_points($weight,$awarded);
if (! defined($awarded)) {
$partscore = undef;
}
@@ -1929,7 +2091,7 @@ sub student_performance_on_sequence {
$symbol = sprintf("%.0f",$symbol);
}
if (length($symbol) > 1) {
- $symbol = '*';
+ $symbol = show_star($symbol);
}
if (exists($resource_data->{'resource.'.$part.'.solved'}) &&
$resource_data->{'resource.'.$part.'.solved'} ne '') {
@@ -1960,11 +2122,12 @@ sub student_performance_on_sequence {
push (@ScoreData,$partscore);
#
if ( ($links eq 'yes' && $symbol ne ' ') || ($links eq 'all')) {
- $symbol = ''.$symbol.' ';
+ '&command=submission';
+ $symbol = &link($symbol, $link);
}
$Str .= $symbol;
}