--- loncom/homework/grades.pm 2020/08/29 16:39:00 1.772 +++ loncom/homework/grades.pm 2020/08/30 20:30:21 1.773 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.772 2020/08/29 16:39:00 raeburn Exp $ +# $Id: grades.pm,v 1.773 2020/08/30 20:30:21 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -147,7 +147,7 @@ sub nameUserString { } #--- Get the partlist and the response type for a given problem. --- -#--- Indicate if a response type is coded handgraded or not. --- +#--- Count responseIDs, essayresponse items, and dropbox items --- #--- Sets response_error pointer to "1" if navmaps object broken --- sub response_type { my ($symb,$response_error) = @_; @@ -165,6 +165,7 @@ sub response_type { return; } my $partlist = $res->parts(); + my ($numresp,$numessay,$numdropbox) = (0,0,0); my %vPart = map { $_ => 1 } (&Apache::loncommon::get_env_multiple('form.vPart')); my (%response_types,%handgrade); @@ -174,13 +175,20 @@ sub response_type { my @types = $res->responseType($part); my @ids = $res->responseIds($part); for (my $i=0; $i < scalar(@ids); $i++) { + $numresp ++; $response_types{$part}{$ids[$i]} = $types[$i]; + if ($types[$i] eq 'essay') { + $numessay ++; + if (&Apache::lonnet::EXT("resource.$part".'_'.$ids[$i].".uploadedfiletypes",$symb)) { + $numdropbox ++; + } + } $handgrade{$part.'_'.$ids[$i]} = &Apache::lonnet::EXT('resource.'.$part.'_'.$ids[$i]. '.handgrade',$symb); } } - return ($partlist,\%handgrade,\%response_types); + return ($partlist,\%handgrade,\%response_types,$numresp,$numessay,$numdropbox); } sub flatten_responseType { @@ -207,6 +215,118 @@ sub get_display_part { return $display; } +#--- Show parts and response type +sub showResourceInfo { + my ($symb,$partlist,$responseType,$formname,$checkboxes,$uploads) = @_; + unless ((ref($partlist) eq 'ARRAY') && (ref($responseType) eq 'HASH')) { + return '
'; + } + my $coltitle = &mt('Problem Part Shown'); + if ($checkboxes) { + $coltitle = &mt('Problem Part'); + } else { + my $checkedparts = 0; + foreach my $partid (&Apache::loncommon::get_env_multiple('form.vPart')) { + if (grep(/^\Q$partid\E$/,@{$partlist})) { + $checkedparts ++; + } + } + if ($checkedparts == scalar(@{$partlist})) { + return '
'; + } + if ($uploads) { + $coltitle = &mt('Problem Part Selected'); + } + } + my $result = '
'; + if ($checkboxes) { + my $legend = &mt('Parts to display'); + if ($uploads) { + $legend = &mt('Part(s) with dropbox'); + } + $result .= '
'.$legend.''. + ''. + ''.(' 'x2). + ''. + '
'; + } + $result .= '
'; + return $result; +} + +sub part_selector_js { + my $js = <<"END"; +function toggleParts(formname) { + if (document.getElementById('LC_partselector')) { + var index = ''; + if (document.forms.length) { + for (var i=0; i 1)) { + for (var i=0; i 1 ) { + $table = &showResourceInfo($symb,$partlist,$responseType,'gradesub',1); + } elsif ($divforres) { + $table = '
'; + } else { + $table = '
'; + } + } my %js_lt = &Apache::lonlocal::texthash ( 'multiple' => 'Please select a student or group of students before clicking on the Next button.', @@ -963,8 +1094,8 @@ LISTJAVASCRIPT $request->print($result); my $gradeTable='
'. - "\n"; - + "\n".$table; + $gradeTable .= &Apache::lonhtmlcommon::start_pick_box(); unless ($is_tool) { $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Problem Text')) @@ -979,7 +1110,6 @@ LISTJAVASCRIPT .&Apache::lonhtmlcommon::row_closure(); } - my $submission_options; my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); my $saveStatus = $stu_status eq '' ? 'Active' : $stu_status; $env{'form.Status'} = $saveStatus; @@ -999,7 +1129,7 @@ LISTJAVASCRIPT all => 'all submissions with details', ); } - $submission_options.= + my $submission_options = ''. ''."\n". @@ -1018,48 +1148,50 @@ LISTJAVASCRIPT } else { $viewtitle = &mt('View Submissions'); } + my ($compmsg,$nocompmsg); + $nocompmsg = ' checked="checked"'; + if ($numessay) { + $compmsg = $nocompmsg; + $nocompmsg = ''; + } $gradeTable .= &Apache::lonhtmlcommon::row_title($viewtitle) .$submission_options + .&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Send Messages')) + .'' + .'' + .'' .&Apache::lonhtmlcommon::row_closure(); - my $closure; - if (($is_tool) && (exists($env{'form.Status'}))) { - $closure = 1; - } $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Grading Increments')) .'' - .&Apache::lonhtmlcommon::row_closure($closure); - + .''; $gradeTable .= &build_section_inputs(). ''."\n". ''."\n". ''."\n"; - if (exists($env{'form.Status'})) { $gradeTable .= ''."\n"; } else { - if ($is_tool) { - $closure = 1; - } - $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Student Status')) + $gradeTable .= &Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Student Status')) .&Apache::lonhtmlcommon::StatusOptions( - $saveStatus,undef,1,'javascript:reLoadList(this.form);') - .&Apache::lonhtmlcommon::row_closure($closure); + $saveStatus,undef,1,'javascript:reLoadList(this.form);'); } - - unless ($is_tool) { - $closure = 1; - $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Check For Plagiarism')) - .'' - .&Apache::lonhtmlcommon::row_closure($closure); + if ($numessay) { + $gradeTable .= &Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(&mt('Check For Plagiarism')) + .''; } - $gradeTable .= &Apache::lonhtmlcommon::end_pick_box(); + $gradeTable .= &Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::end_pick_box(); my $regrademsg; if ($is_tool) { $regrademsg =&mt("To view/grade/regrade, click on the check box(es) next to the student's name(s). Then click on the Next button."); @@ -1447,8 +1579,8 @@ sub sub_page_js { SUBJAVASCRIPT } -#--- javascript for essay type problem -- -sub sub_page_kw_js { +#--- javascript for grading message center +sub sub_grademessage_js { my $request = shift; my $iconpath = $request->dir_config('lonIconsURL'); &commonJSfunctions($request); @@ -1494,55 +1626,17 @@ sub sub_page_kw_js { INNERJS - my $inner_js_highlight_central= (< - function updateChoice(flag) { - opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr); - opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize); - opener.document.SCORE.kwstyle.value = opener.radioSelection(document.hlCenter.kwdstyle); - opener.document.SCORE.refresh.value = "on"; - if (opener.document.SCORE.keywords.value!=""){ - opener.document.SCORE.submit(); - } - self.close() - } - -INNERJS - - my $start_page_msg_central = + my $start_page_msg_central = &Apache::loncommon::start_page('Message Central',$inner_js_msg_central, {'js_ready' => 1, 'only_body' => 1, 'bgcolor' =>'#FFFFFF',}); - my $end_page_msg_central = - &Apache::loncommon::end_page({'js_ready' => 1}); - - - my $start_page_highlight_central = - &Apache::loncommon::start_page('Highlight Central', - $inner_js_highlight_central, - {'js_ready' => 1, - 'only_body' => 1, - 'bgcolor' =>'#FFFFFF',}); - my $end_page_highlight_central = + my $end_page_msg_central = &Apache::loncommon::end_page({'js_ready' => 1}); my $docopen=&Apache::lonhtmlcommon::javascript_docopen(); $docopen=~s/^document\.//; - 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', @@ -1552,29 +1646,11 @@ INNERJS new => 'New', save => 'Save', canc => 'Cancel', - kehi => 'Keyword Highlight Options', - txtc => 'Text Color', - font => 'Font Size', - fnst => 'Font Style', ); - &js_escape(\%js_lt); &html_escape(\%html_js_lt); &js_escape(\%html_js_lt); $request->print(&Apache::lonhtmlcommon::scripttag(< + function updateChoice(flag) { + opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr); + opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize); + opener.document.SCORE.kwstyle.value = opener.radioSelection(document.hlCenter.kwdstyle); + opener.document.SCORE.refresh.value = "on"; + if (opener.document.SCORE.keywords.value!=""){ + opener.document.SCORE.submit(); + } + self.close() + } + +INNERJS + + my $start_page_highlight_central = + &Apache::loncommon::start_page('Highlight Central', + $inner_js_highlight_central, + {'js_ready' => 1, + 'only_body' => 1, + 'bgcolor' =>'#FFFFFF',}); + my $end_page_highlight_central = + &Apache::loncommon::end_page({'js_ready' => 1}); + + my $docopen=&Apache::lonhtmlcommon::javascript_docopen(); + $docopen=~s/^document\.//; + + 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( + save => 'Save', + canc => 'Cancel', + kehi => 'Keyword Highlight Options', + txtc => 'Text Color', + font => 'Font Size', + fnst => 'Font Style', + ); + &js_escape(\%js_lt); + &html_escape(\%html_js_lt); + &js_escape(\%html_js_lt); + $request->print(&Apache::lonhtmlcommon::scripttag(<print(&mt('An error occurred retrieving response types')); - return; - } + my ($partlist,$handgrade,$responseType,$numresp,$numessay,$numdropbox) = + &response_type($symb,\$res_error); + if ($res_error) { + $request->print(&mt('An error occurred retrieving response types')); + return; } - my ($numupload,$numessay) = (0,0); - if (ref($responseType) eq 'HASH') { - foreach my $part (sort(keys(%$responseType))) { - foreach my $id (sort(keys(%{ $responseType->{$part} }))) { - my $responsetype = $responseType->{$part}->{$id}; - if ($responsetype eq 'essay') { - my $uploadedfiletypes = - &Apache::lonnet::EXT("resource.$part".'_'."$id.uploadedfiletypes",$symb); - if ($uploadedfiletypes) { - $numupload++; - } else { - $numessay++; - } - } - } - } + unless ($numessay) { + $request->print(&mt('No essayresponse items found')); + return; } - if (($numupload) || ($numessay)) { + my @chosenparts = &Apache::loncommon::get_env_multiple('form.vPart'); + if (@chosenparts) { + $request->print(&showResourceInfo($symb,$partlist,$responseType, + undef,undef,1)); + } + if ($numessay) { my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'}; my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'}; my $getgroup = $env{'form.group'} eq '' ? 'all' : $env{'form.group'}; @@ -2084,10 +2229,12 @@ sub submit_download_link { my @students = map { $_.':'.$fullname->{$_} } (keys(%{$fullname})); if (@students) { @{$env{'form.stuinfo'}} = @students; - if ($numupload) { + if ($numdropbox) { &download_all_link($request,$symb); + } else { + $request->print(&mt('No essayrespose items with dropbox found')); } -# FIXME Need to provide a mechanism to download essays, i.e., if $numessay > 0 +# FIXME Need a mechanism to download essays, i.e., if $numessay > $numdropbox # Needs to omit user's identity if resource instance is for an anonymous survey. } else { $request->print(&mt('No students match the criteria you selected')); @@ -2116,14 +2263,14 @@ sub build_section_inputs { # --------------------------- show submissions of a student, option to grade sub submission { - my ($request,$counter,$total,$symb) = @_; + my ($request,$counter,$total,$symb,$divforres,$calledby) = @_; my ($uname,$udom) = ($env{'form.student'},$env{'form.userdom'}); $udom = ($udom eq '' ? $env{'user.domain'} : $udom); #has form.userdom changed for a student? my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'}); $env{'form.fullname'} = &Apache::loncommon::plainname($uname,$udom,'lastname') if $env{'form.fullname'} eq ''; - my $probtitle=&Apache::lonnet::gettitle($symb); if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; } + my $probtitle=&Apache::lonnet::gettitle($symb); my $is_tool = ($symb =~ /ext\.tool$/); my ($essayurl,%coursedesc_by_cid); @@ -2137,11 +2284,22 @@ sub submission { return; } + my $res_error; + my ($partlist,$handgrade,$responseType,$numresp,$numessay) = + &response_type($symb,\$res_error); + if ($res_error) { + $request->print(&navmap_errormsg()); + return; + } + if (!$env{'form.lastSub'}) { $env{'form.lastSub'} = 'datesub'; } unless ($is_tool) { if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; } if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; } } + if (($numessay) && ($calledby eq 'submission') && (!exists($env{'form.compmsg'}))) { + $env{'form.compmsg'} = 1; + } my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : ''); my $checkIcon = ''.&mt('Check Mark').
 	''); + } else { + $request->print('
'); + } &sub_page_js($request); - &sub_page_kw_js($request); + &sub_grademessage_js($request) if ($env{'form.compmsg'}); + &sub_page_kw_js($request) if ($numessay); # option to display problem, only once else it cause problems # with the form later since the problem has a form. @@ -2167,24 +2334,27 @@ sub submission { $request->print(&show_problem($request,$symb,$uname,$udom,0,1,$mode)); } - # kwclr is the only variable that is guaranteed not to be blank - # if this subroutine has been called once. my %keyhash = (); -# if ($env{'form.kwclr'} eq '' && $env{'form.handgrade'} eq 'yes') { - if (1) { + if (($env{'form.kwclr'} eq '' && $numessay) || ($env{'form.compmsg'})) { %keyhash = &Apache::lonnet::dump('nohist_handgrade', $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); - + } + # kwclr is the only variable that is guaranteed not to be blank + # if this subroutine has been called once. + if ($env{'form.kwclr'} eq '' && $numessay) { my $loginuser = $env{'user.name'}.':'.$env{'user.domain'}; $env{'form.keywords'} = $keyhash{$symb.'_keywords'} ne '' ? $keyhash{$symb.'_keywords'} : ''; $env{'form.kwclr'} = $keyhash{$loginuser.'_kwclr'} ne '' ? $keyhash{$loginuser.'_kwclr'} : 'red'; $env{'form.kwsize'} = $keyhash{$loginuser.'_kwsize'} ne '' ? $keyhash{$loginuser.'_kwsize'} : '0'; $env{'form.kwstyle'} = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : ''; - $env{'form.msgsub'} = $keyhash{$symb.'_subject'} ne '' ? + } + if ($env{'form.compmsg'}) { + $env{'form.msgsub'} = $keyhash{$symb.'_subject'} ne '' ? $keyhash{$symb.'_subject'} : $probtitle; $env{'form.savemsgN'} = $keyhash{$symb.'_savemsgN'} ne '' ? $keyhash{$symb.'_savemsgN'} : '0'; } + my $overRideScore = $env{'form.overRideScore'} eq '' ? 'no' : $env{'form.overRideScore'}; my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); $request->print(''."\n". @@ -2198,24 +2368,23 @@ sub submission { ''."\n". ''."\n". ''."\n". + ''."\n". &build_section_inputs(). ''."\n". ''."\n"); -# if ($env{'form.handgrade'} eq 'yes') { - if (1) { + if ($env{'form.compmsg'}) { + $request->print(''."\n". + ''."\n". + ''."\n"); + } + if ($numessay) { $request->print(''."\n". ''."\n". ''."\n". - ''."\n". - ''."\n". - ''."\n". - ''."\n"); - foreach my $partid (&Apache::loncommon::get_env_multiple('form.vPart')) { - $request->print(''."\n"); - } + ''."\n"); } - + my ($cts,$prnmsg) = (1,''); while ($cts <= $env{'form.savemsgN'}) { $prnmsg.=''.$boxtitle.''; $result.=''."\n"; -# if ($env{'form.handgrade'} eq 'no') { - unless ($is_tool) { + if (($numresp > $numessay) && !$is_tool) { $result.='

' .&mt('Part(s) graded correct by the computer is marked with a [_1] symbol.',$checkIcon) ."

\n"; } - # If any part of the problem is an essay-response (handgraded), then check for collaborators + # If any part of the problem is an essayresponse, then check for collaborators my $fullname; my $col_fullnames = []; -# if ($env{'form.handgrade'} eq 'yes') { - unless ($is_tool) { + if ($numessay) { (my $sub_result,$fullname,$col_fullnames)= &check_collaborators($symb,$uname,$udom,\%record,$handgrade, $counter); $result.=$sub_result; } $request->print($result."\n"); - + # print student answer/submission - # Options are (1) Handgraded submission only - # (2) Last submission, includes submission that is not handgraded - # (for multi-response type part) - # (3) Last submission plus the parts info - # (4) The whole record for this student - + # Options are (1) Last submission only + # (2) Last submission (with detailed information for that submission) + # (3) All transactions (by date) + # (4) The whole record (with detailed information for all transactions) + my ($string,$timestamp)= &get_last_submission(\%record,$is_tool); - + my $lastsubonly; if ($$timestamp eq '') { @@ -2379,9 +2538,6 @@ sub submission { my %seenparts; my @part_response_id = &flatten_responseType($responseType); foreach my $part (@part_response_id) { - next if ($env{'form.lastSub'} eq 'hdgrade' - && $$handgrade{$$part[0].'_'.$$part[1]} ne 'yes'); - my ($partid,$respid) = @{ $part }; my $display_part=&get_display_part($partid,$symb); if ($env{"form.$uname:$udom:$partid:submitted_by"}) { @@ -2396,7 +2552,7 @@ sub submission { $$fullname{$env{"form.$uname:$udom:$partid:submitted_by"}}.''). '
'); next; - } + } my $responsetype = $responseType->{$partid}->{$respid}; if (!exists($record{"resource.$partid.$respid.submission"})) { $lastsubonly.="\n".'
'. @@ -2475,8 +2631,9 @@ sub submission { } my $order=&get_order($partid,$respid,$symb,$uname,$udom, undef,$type,$trial,$rndseed); - if ($env{'form.lastSub'} eq 'lastonly' || $env{'form.lastSub'} eq 'datesub' || $env{'form.lastSub'} =~ /^(last|all)$/ || ($env{'form.lastSub'} eq 'hdgrade' && - $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) { + if (($env{'form.lastSub'} eq 'lastonly') || + ($env{'form.lastSub'} eq 'datesub') || + ($env{'form.lastSub'} =~ /^(last|all)$/)) { my $display_part=&get_display_part($partid,$symb); $lastsubonly.='
'. ''.&mt('Part: [_1]',$display_part).''. @@ -2530,8 +2687,7 @@ sub submission { if ($env{'form.lastSub'} eq 'datesub') { my ($parts,$handgrade,$responseType) = &response_type($symb,\$res_error); $request->print(&displaySubByDates($symb,\%record,$parts,$responseType,$checkIcon,$uname,$udom)); - - } + } if ($env{'form.lastSub'} =~ /^(last|all)$/) { my $identifier = (&canmodify($usec)? $counter : ''); $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom, @@ -2550,32 +2706,31 @@ sub submission { $request->print('
'."\n"); } - # essay grading message center -# if ($env{'form.handgrade'} eq 'yes') { - if (1) { - my $result='
'; - - $result.='
'. - &mt('Send Message').'
'; - my ($lastname,$givenn) = split(/,/,$env{'form.fullname'}); - my $msgfor = $givenn.' '.$lastname; - if (scalar(@$col_fullnames) > 0) { - my $lastone = pop(@$col_fullnames); - $msgfor .= ', '.(join ', ',@$col_fullnames).' and '.$lastone.'.'; - } - $msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript - $result.=''."\n". - ''."\n"; - $result.=' '. - &mt('Compose message to student'.(scalar(@$col_fullnames) >= 1 ? 's' : '')).')'. - ' '."\n". - '
 ('. - &mt('Message will be sent when you click on Save & Next below.').")\n"; - $result.='
'; - $request->print($result); + # grading message center + + if ($env{'form.compmsg'}) { + my $result='
'. + '

'.&mt('Send Message').'

'. + '
'; + my ($lastname,$givenn) = split(/,/,$env{'form.fullname'}); + my $msgfor = $givenn.' '.$lastname; + if (scalar(@$col_fullnames) > 0) { + my $lastone = pop(@$col_fullnames); + $msgfor .= ', '.(join ', ',@$col_fullnames).' and '.$lastone.'.'; + } + $msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript + $result.=''."\n". + ''."\n". + ' '. + &mt('Compose message to student'.(scalar(@$col_fullnames) >= 1 ? 's' : '')).')'. + ' '."\n". + '
 ('. + &mt('Message will be sent when you click on Save & Next below.').")\n". + '
'; + $request->print($result); } my %seen = (); @@ -2597,8 +2752,6 @@ sub submission { my $part_resp = join('_',@{ $part_response_id }); next if ($seen{$partid} > 0); $seen{$partid}++; - next if ($$handgrade{$part_resp} ne 'yes' - && $env{'form.lastSub'} eq 'hdgrade'); push(@partlist,$partid); push(@gradePartRespid,$partid.'.'.$respid); $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record)); @@ -3077,11 +3230,17 @@ sub processHandGrade { } } -# if ($env{'form.handgrade'} eq 'yes') { - if (1) { + my $res_error; + my ($partlist,$handgrade,$responseType,$numresp,$numessay) = &response_type($symb,\$res_error); + if ($res_error) { + $request->print(&navmap_errormsg()); + return; + } + + my %keyhash = (); + if ($numessay) { # Keywords sorted in alphabatical order my $loginuser = $env{'user.name'}.':'.$env{'user.domain'}; - my %keyhash = (); $env{'form.keywords'} =~ s/,\s{0,}|\s+/ /g; $env{'form.keywords'} =~ s/^\s+|\s+$//; my (@keywords) = sort(split(/\s+/,$env{'form.keywords'})); @@ -3091,7 +3250,9 @@ sub processHandGrade { $keyhash{$loginuser.'_kwclr'} = $env{'form.kwclr'}; $keyhash{$loginuser.'_kwsize'} = $env{'form.kwsize'}; $keyhash{$loginuser.'_kwstyle'} = $env{'form.kwstyle'}; + } + if ($env{'form.compmsg'}) { # message center - Order of message gets changed. Blank line is eliminated. # New messages are saved in env for the next student. # All messages are saved in nohist_handgrade.db @@ -3106,17 +3267,20 @@ sub processHandGrade { $ctr = 0; while ($ctr < $ngrade) { if ($env{'form.newmsg'.$ctr} ne '') { - $keyhash{$symb.'_savemsg'.$idx} = $env{'form.newmsg'.$ctr}; - $env{'form.savemsg'.$idx} = $env{'form.newmsg'.$ctr}; - $idx++; + $keyhash{$symb.'_savemsg'.$idx} = $env{'form.newmsg'.$ctr}; + $env{'form.savemsg'.$idx} = $env{'form.newmsg'.$ctr}; + $idx++; } $ctr++; } $env{'form.savemsgN'} = --$idx; $keyhash{$symb.'_savemsgN'} = $env{'form.savemsgN'}; - my $putresult = &Apache::lonnet::put - ('nohist_handgrade',\%keyhash,$cdom,$cnum); } + if (($numessay) || ($env{'form.compmsg'})) { + my $putresult = &Apache::lonnet::put + ('nohist_handgrade',\%keyhash,$cdom,$cnum); + } + # Called by Save & Refresh from Highlight Attribute Window my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1'); if ($env{'form.refresh'} eq 'on') { @@ -3156,7 +3320,6 @@ sub processHandGrade { } return $a cmp $b; } (keys(%$fullname))) { -# FIXME: this is fishy, looks like the button label if ($nextflg == 1 && $button =~ /Next$/) { push(@parsedlist,$item); } @@ -3167,14 +3330,7 @@ sub processHandGrade { } } $ctr = 0; -# FIXME: this is fishy, looks like the button label @parsedlist = reverse @parsedlist if ($button eq 'Previous'); - my $res_error; - my ($partlist) = &response_type($symb,\$res_error); - if ($res_error) { - $request->print(&navmap_errormsg()); - return; - } foreach my $student (@parsedlist) { my $submitonly=$env{'form.submitonly'}; my ($uname,$udom) = split(/:/,$student); @@ -3427,7 +3583,7 @@ sub handback_files { &Apache::lonnet::file_name_version_ext($answer_file); my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/); my $getpropath = 1; - my ($dir_list,$listerror) = + my ($dir_list,$listerror) = &Apache::lonnet::dirlist($portfolio_root.$portfolio_path, $domain,$stuname,$getpropath); my $version = &Apache::lonnet::get_next_version($answer_name,$answer_ext,$dir_list); @@ -3887,7 +4043,6 @@ sub viewgrades { my $part_resp = join('_',@{ $part_response_id }); next if $seen{$partid}; $seen{$partid}++; -# my $handgrade=$$handgrade{$part_resp}; my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb); $weight{$partid} = $wgt eq '' ? '1' : $wgt; @@ -10339,11 +10494,30 @@ sub submit_options_download { my ($request,$symb) = @_; if (!$symb) {return '';} + my $res_error; + my ($partlist,$handgrade,$responseType,$numresp,$numessay,$numdropbox) = + &response_type($symb,\$res_error); + if ($res_error) { + $request->print(&mt('An error occurred retrieving response types')); + return; + } + unless ($numessay) { + $request->print(&mt('No essayresponse items found')); + return; + } + my $table; + if (ref($partlist) eq 'ARRAY') { + if (scalar(@$partlist) > 1 ) { + $table = &showResourceInfo($symb,$partlist,$responseType,'gradingMenu',1,1); + } + } + my $is_tool = ($symb =~ /ext\.tool$/); &commonJSfunctions($request); my $result=''."\n". - ''."\n"; + $table."\n". + ''."\n"; $result.='

'.&mt('Select Students for whom to Download Submissions').' @@ -11121,7 +11295,7 @@ sub navmap_errormsg { } sub startpage { - my ($r,$symb,$crumbs,$onlyfolderflag,$nodisplayflag,$stuvcurrent,$stuvdisp,$nomenu,$js,$onload) = @_; + my ($r,$symb,$crumbs,$onlyfolderflag,$nodisplayflag,$stuvcurrent,$stuvdisp,$nomenu,$js,$onload,$divforres) = @_; my %args; if ($onload) { my %loaditems = ( @@ -11141,7 +11315,7 @@ sub startpage { } } unless ($nodisplayflag) { - $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp)); + $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp,$divforres)); } } @@ -11205,18 +11379,24 @@ sub handler { &select_problem($request); } else { if ($command eq 'submission' && $perm{'vgr'}) { - my ($stuvcurrent,$stuvdisp,$versionform,$js); + my ($stuvcurrent,$stuvdisp,$versionform,$js,$onload); if (($env{'form.student'} ne '') && ($env{'form.userdom'} ne '')) { ($stuvcurrent,$stuvdisp,$versionform,$js) = &choose_task_version_form($symb,$env{'form.student'}, $env{'form.userdom'}); } - &startpage($request,$symb,[{href=>"", text=>"Student Submissions"}],undef,undef,$stuvcurrent,$stuvdisp,undef,$js); + my $divforres; + if ($env{'form.student'} eq '') { + $js .= &part_selector_js(); + $onload = "toggleParts('gradesub');"; + } else { + $divforres = 1; + } + &startpage($request,$symb,[{href=>"", text=>"Student Submissions"}],undef,undef,$stuvcurrent,$stuvdisp,undef,$js,$onload,$divforres); if ($versionform) { $request->print($versionform); } - $request->print('
'); - ($env{'form.student'} eq '' ? &listStudents($request,$symb) : &submission($request,0,0,$symb)); + ($env{'form.student'} eq '' ? &listStudents($request,$symb,'',$divforres) : &submission($request,0,0,$symb,$divforres,$command)); } elsif ($command eq 'versionsub' && $perm{'vgr'}) { my ($stuvcurrent,$stuvdisp,$versionform,$js) = &choose_task_version_form($symb,$env{'form.student'}, @@ -11246,7 +11426,7 @@ sub handler { &updateGradeByPage($request,$symb); } elsif ($command eq 'processGroup' && $perm{'vgr'}) { &startpage($request,$symb,[{href=>'',text=>'...'}, - {href=>'',text=>'Modify grades'}]); + {href=>'',text=>'Modify grades'}],undef,undef,undef,undef,undef,undef,undef,1); &processGroup($request,$symb); } elsif ($command eq 'gradingmenu' && $perm{'vgr'}) { &startpage($request,$symb); @@ -11255,7 +11435,10 @@ sub handler { &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'}]); + my $js = &part_selector_js(); + my $onload = "toggleParts('gradesub');"; + &startpage($request,$symb,[{href=>'',text=>'Grade ungraded submissions'}], + undef,undef,undef,undef,undef,$js,$onload); $request->print(&listStudents($request,$symb,'graded')); } elsif ($command eq 'table' && $perm{'vgr'}) { &startpage($request,$symb,[{href=>"", text=>"Grading table"}]); @@ -11353,12 +11536,16 @@ sub handler { &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'}]); + my $js = &part_selector_js(); + my $onload = "toggleParts('gradingMenu');"; + &startpage($request,$symb,[{href=>'', text=>'Select which submissions to download'}], + undef,undef,undef,undef,undef,$js,$onload); $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 submitted files'}]); + {href=>'', text=>'Download submitted files'}], + undef,undef,undef,undef,undef,undef,undef,1); &submit_download_link($request,$symb); } elsif ($command) { &startpage($request,$symb,[{href=>'', text=>'Access denied'}]);