--- loncom/interface/lonparmset.pm 2022/03/24 15:57:36 1.606 +++ loncom/interface/lonparmset.pm 2022/07/03 04:31:07 1.615 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.606 2022/03/24 15:57:36 raeburn Exp $ +# $Id: lonparmset.pm,v 1.615 2022/07/03 04:31:07 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1252,6 +1252,7 @@ function validateParms() { var dlKeyRegExp = /^deeplink_key_/; var dlMenusRegExp = /^deeplink_menus_/; var dlCollsRegExp = /^deeplink_colls_/; + var dlTargetRegExp = /^deeplink_target_/; var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/; if ((document.parmform.elements.length != 'undefined') && (document.parmform.elements.length) != 'null') { if (document.parmform.elements.length) { @@ -1406,6 +1407,17 @@ function validateParms() { } document.parmform.elements['set_'+identifier].value += posslinkmenu; } + } else if (dlTargetRegExp.test(name)) { + var identifier = name.replace(dlTargetRegExp,''); + var idx = document.parmform.elements[i].selectedIndex; + if (idx > 0) { + var possdeeplink = document.parmform.elements[i].options[idx].value + possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,''); + if (document.parmform.elements['set_'+identifier].value) { + possdeeplink = ','+possdeeplink; + } + document.parmform.elements['set_'+identifier].value += possdeeplink; + } } } } @@ -1461,6 +1473,8 @@ END # Javascript function toggleSecret, for overview mode. sub done_proctor_js { + my $defaultdone = &mt('Done'); + &js_escape(\$defaultdone); return <<"END"; function toggleSecret(form,radio,key) { var radios = form[radio+key]; @@ -1477,6 +1491,15 @@ function toggleSecret(form,radio,key) { document.getElementById('done_'+key+'_proctorkey').value=''; } } + if (document.getElementById('done_'+key+'_buttontext')) { + if (radios[i].value == '') { + document.getElementById('done_'+key+'_buttontext').value = ''; + } else { + if (document.getElementById('done_'+key+'_buttontext').value == '') { + document.getElementById('done_'+key+'_buttontext').value = '$defaultdone'; + } + } + } } } } @@ -2074,6 +2097,7 @@ sub parm_control_group { # @param {hash reference} $uris - hash resource/map id -> resource src # @param {hash reference} $keyorder - hash parameter key -> appearance rank for this parameter when looking through every resource and every parameter, starting at 100 (integer) # @param {hash reference} $defkeytype - hash parameter name -> parameter type +# @param {string} $pssymb - resource symb (when a single resource is selected) sub extractResourceInformation { my $ids = shift; my $typep = shift; @@ -2742,8 +2766,9 @@ sub displaymenu { # @param {string} $pschp - selected map pc, or 'all' # @param {hash reference} $maptitles - hash map id or src -> map title # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb +# @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general') sub mapmenu { - my ($r,$allmaps,$pschp,$maptitles,$symbp)=@_; + my ($r,$allmaps,$pschp,$maptitles,$symbp,$parmlev)=@_; my %allmaps_inverted = reverse %$allmaps; my $navmap = Apache::lonnavmaps::navmap->new(); my $tree=[]; @@ -2791,7 +2816,11 @@ sub mapmenu { } } # Show it ... - $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',' id="mapmenu"')); + my $rowattr = ' id="mapmenu"'; + if ($parmlev eq 'general') { + $rowattr .= ' style="display:none"'; + } + $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',$rowattr)); if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) { my $icon = ''; my $whitespace = @@ -3033,19 +3062,33 @@ sub keysindisplayorder { # # @param {Apache2::RequestRec} $r - the Apache request # @param {string} $sortorder - realmstudent|studentrealm +# @param {string} $context - newoverview|overview sub sortmenu { - my ($r,$sortorder)=@_; - $r->print('

'); } # Returns a hash parameter key -> order (integer) giving the order for some parameters. @@ -3635,7 +3678,7 @@ ENDPARMSELSCRIPT $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel')); &levelmenu($r,\%alllevs,$parmlev); $r->print(&Apache::lonhtmlcommon::row_closure()); - &mapmenu($r,\%allmaps,$pschp,\%maptitles, \%symbp); + &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev); $r->print(&Apache::lonhtmlcommon::row_closure()); $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View'))); &partmenu($r,\%allparts,\@psprt); @@ -3932,7 +3975,7 @@ ENDTABLEHEADFOUR #-------------------------------------------- for each map, gather information my $mapid; - foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys(%maplist)) { + foreach $mapid (sort { $a <=> $b } keys(%maplist)) { my $maptitle = $maplist{$mapid}; #----------------------- loop through ids and get all parameter types for map @@ -4687,9 +4730,12 @@ sub parse_listdata_key { # @param {string} $caller - name of the calling sub (overview|newoverview) # @param {hash reference} $classlist - from loncoursedata::get_classlist # @param {boolean} $readonly - true if editing not allowed +# @param {string} $parmlev - full|map +# @param {hash reference} $hash_for_realm - keys: realm, values: numeric order +# @param {string} $pschp - selected map pc, or 'all' # @returns{integer} - number of $listdata parameters processed sub listdata { - my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly)=@_; + my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly,$parmlev,$hash_for_realm,$pschp)=@_; # Start list output @@ -4715,6 +4761,20 @@ sub listdata { foreach my $key (sort { my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata); my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata); + my ($aid,$bid); + if ($caller eq 'newoverview') { + if (ref($hash_for_realm) eq 'HASH') { + if (($parmlev eq 'map') && ($pschp eq 'all')) { + my ($aurl) = ($ares =~ /^(.+\.(?:sequence|page))___\(all\)$/); + my ($burl) = ($bres =~ /^(.+\.(?:sequence|page))___\(all\)$/); + $aid = $hash_for_realm->{$aurl}; + $bid = $hash_for_realm->{$burl}; + } elsif ($parmlev eq 'full') { + $aid = $hash_for_realm->{$ares}; + $bid = $hash_for_realm->{$bres}; + } + } + } # get the numerical order for the param $aparm=$keyorder{'parameter_0_'.$aparm}; @@ -4724,7 +4784,21 @@ sub listdata { if ($sortorder eq 'realmstudent') { if ($ares ne $bres ) { - $result = ($ares cmp $bres); + if ($caller eq 'newoverview') { + if (ref($hash_for_realm) eq 'HASH') { + if (($parmlev eq 'map') && ($pschp eq 'all')) { + $result = ($aid <=> $bid); + } elsif ($parmlev eq 'full') { + $result = ($aid <=> $bid); + } else { + $result = ($ares cmp $bres); + } + } else { + $result = ($ares cmp $bres); + } + } else { + $result = ($ares cmp $bres); + } } elsif ($astudent ne $bstudent) { $result = ($astudent cmp $bstudent); } elsif ($apart ne $bpart ) { @@ -4734,7 +4808,21 @@ sub listdata { if ($astudent ne $bstudent) { $result = ($astudent cmp $bstudent); } elsif ($ares ne $bres ) { - $result = ($ares cmp $bres); + if ($caller eq 'newoverview') { + if (ref($hash_for_realm) eq 'HASH') { + if (($parmlev eq 'map') && ($pschp eq 'all')) { + $result = ($aid <=> $bid); + } elsif ($parmlev eq 'full') { + $result = ($aid <=> $bid); + } else { + $result = ($ares cmp $bres); + } + } else { + $result = ($ares cmp $bres); + } + } else { + $result = ($ares cmp $bres); + } } elsif ($apart ne $bpart ) { $result = ($apart cmp $bpart); } @@ -4814,6 +4902,12 @@ sub listdata { } if ($is_map) { my $leveltitle = &mt('Folder/Map'); + my $title = &Apache::lonnet::gettitle($mapurl); + if (ref($hash_for_realm) eq 'HASH') { + if ($hash_for_realm->{$mapurl} eq '1') { + $title = &mt('Main Content'); + } + } unless (($name eq 'hiddenresource') || ($name eq 'encrypturl')) { if ($caller eq 'newoverview') { my $altkey = $thiskey; @@ -4830,9 +4924,10 @@ sub listdata { $is_recursive = 1; } } - $realm=''.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).'
('.$mapurl.')
'; + $realm=''.$leveltitle.': '.$title.'
('.$mapurl.')
'; } elsif ($middle) { my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle); + next if (($url =~ /\.(page|sequence)$/) && ($parmlev eq 'full') && ($caller eq 'newoverview')); $realm=''.&mt('Resource'). ': '.&Apache::lonnet::gettitle($middle). '
('.$url.' in '.$map.' id: '. @@ -4954,13 +5049,17 @@ sub listdata { sub get_date_interval_from_form { my ($key) = @_; my $seconds = 0; + my $numnotnull = 0; foreach my $which (['days', 86400], ['hours', 3600], ['minutes', 60], ['seconds', 1]) { my ($name, $factor) = @{ $which }; if (defined($env{'form.'.$name.'_'.$key})) { - $seconds += $env{'form.'.$name.'_'.$key} * $factor; + unless ($env{'form.'.$name.'_'.$key} eq '') { + $numnotnull ++; + $seconds += $env{'form.'.$name.'_'.$key} * $factor; + } } } if (($key =~ /\.interval$/) && @@ -4979,6 +5078,7 @@ sub get_date_interval_from_form { $seconds .= '_'.$env{'form.done_'.$key.'_proctorkey'}; } } + return if (!$numnotnull); return $seconds; } @@ -5068,7 +5168,7 @@ sub string_deeplink_selector { my ($thiskey, $showval, $readonly) = @_; my (@components,%values,@current,%titles,%options,%optiontext,%defaults, %selectnull,%domlti,%crslti,@possmenus); - @components = ('state','others','listing','scope','protect','menus'); + @components = ('state','others','listing','scope','protect','menus','target'); %titles = &Apache::lonlocal::texthash ( state => 'Access status', others => 'Hide other resources', @@ -5076,6 +5176,7 @@ sub string_deeplink_selector { scope => 'Access scope for link', protect => 'Link protection', menus => 'Menu Items Displayed', + target => 'Embedded?', ); %options = ( state => ['only','off','both'], @@ -5084,6 +5185,7 @@ sub string_deeplink_selector { scope => ['res','map','rec'], protect => ['none','key','ltid','ltic'], menus => ['std','colls'], + target => ['_self','_top'], ); %optiontext = &Apache::lonlocal::texthash ( only => 'deep only', @@ -5105,6 +5207,8 @@ sub string_deeplink_selector { ltid => 'LTI access (domain)' , std => 'Standard (all menus)', colls => 'Numbered collection', + _self => 'Embedded', + _top => 'Not embedded', ); %selectnull = &Apache::lonlocal::texthash ( ltic => 'Select Launcher', @@ -5120,6 +5224,7 @@ sub string_deeplink_selector { ($values{'scope'}) = ($current[3] =~ /^(res|map|rec)$/); ($values{'protect'}) = ($current[4] =~ /^(key:[a-zA-Z\d_.!\@#\$%^&*()+=-]+|ltic:\d+|ltid:\d+)$/); ($values{'menus'}) = ($current[5] =~ /^(\d+)$/); + ($values{'target'}) = ($current[6] =~ /^(_self|_top)$/); } else { $defaults{'state'} = 'off', $defaults{'others'} = 'unhide', @@ -5127,6 +5232,7 @@ sub string_deeplink_selector { $defaults{'scope'} = 'res'; $defaults{'protect'} = 'none'; $defaults{'menus'} = '0'; + $defaults{'target'} = '_top'; } my $disabled; if ($readonly) { @@ -5308,7 +5414,7 @@ my %strings = => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'], ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']], 'string_deeplink' - => [['on','Set choices for link protection, resource listing, access scope, and shown menu items']], + => [['on','Set choices for link protection, resource listing, access scope, shown menu items, and embedding']], ); @@ -5319,7 +5425,7 @@ my %stringmatches = ( => [['_allowfrom_','[^\!]+'], ['_denyfrom_','\!']], 'string_deeplink' - => [['on','^(only|off|both)\,(hide|unhide)\,(full|absent|grades|details|datestatus)\,(res|map|rec)\,(none|key\:\w+|ltic\:\d+|ltid\:\d+)\,(\d+|)$']], + => [['on','^(only|off|both)\,(hide|unhide)\,(full|absent|grades|details|datestatus)\,(res|map|rec)\,(none|key\:\w+|ltic\:\d+|ltid\:\d+)\,(\d+|)\,_(self|top)$']], ); my %stringtypes = ( @@ -5639,6 +5745,11 @@ sub date_interval_selector { $showval %= $factor; my %select = ((map {$_ => $_} (0..$max)), 'select_form_order' => [0..$max]); + if ($currval eq '') { + unshift(@{$select{'select_form_order'}},''); + $select{''} = ''; + $amount = ''; + } $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey, \%select,'',$readonly); $result .= ' '.&mt($name); @@ -5646,29 +5757,29 @@ sub date_interval_selector { if ($name eq 'interval') { unless ($skipval{'done'}) { my $checkedon = ''; + my $checkedoff = ''; my $checkedproc = ''; my $currproctorkey = ''; my $currprocdisplay = 'hidden'; my $currdonetext = &mt('Done'); - my $checkedoff = ' checked="checked"'; if ($currval =~ /^(?:\d+)_done$/) { $checkedon = ' checked="checked"'; - $checkedoff = ''; } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) { $currdonetext = $1; $checkedon = ' checked="checked"'; - $checkedoff = ''; } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) { $currproctorkey = $1; $checkedproc = ' checked="checked"'; - $checkedoff = ''; $currprocdisplay = 'text'; } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) { $currdonetext = $1; $currproctorkey = $2; $checkedproc = ' checked="checked"'; - $checkedoff = ''; $currprocdisplay = 'text'; + } elsif ($currval ne '') { + $checkedoff = ' checked="checked"'; + } else { + $currdonetext = ''; } my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"'; my $disabled; @@ -5685,7 +5796,8 @@ sub date_interval_selector { '&').'"'.$disabled.' />
'. ''.&mt('Button text').': '. - '&').'"'.$disabled.' />'; + '&').'"'.$disabled.' />
'; } } unless ($readonly) { @@ -5938,10 +6050,8 @@ ENDOVER $r->print('
'); $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel')); &levelmenu($r,\%alllevs,$parmlev); - if ($parmlev ne 'general') { - $r->print(&Apache::lonhtmlcommon::row_closure()); - &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp); - } + $r->print(&Apache::lonhtmlcommon::row_closure()); + &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev); $r->print(&Apache::lonhtmlcommon::row_closure(1)); $r->print(&Apache::lonhtmlcommon::end_pick_box()); $r->print('
'); @@ -5979,7 +6089,7 @@ ENDOVER $r->print('
'); my $sortorder=$env{'form.sortorder'}; unless ($sortorder) { $sortorder='realmstudent'; } - &sortmenu($r,$sortorder); + &sortmenu($r,$sortorder,'newoverview'); $r->print('
'); $r->print('

'); @@ -6004,7 +6114,15 @@ ENDOVER # List data - &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly); + my $hash_for_realm; + if (($parmlev eq 'map') && (keys(%allmaps))) { + %{$hash_for_realm} = reverse(%allmaps); + } elsif (($parmlev eq 'full') && (keys(%symbp))) { + for (my $i=0; $i<@ids; $i++) { + $hash_for_realm->{$symbp{$ids[$i]}} = $i; + } + } + &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly,$parmlev,$hash_for_realm,$pschp); } $r->print(&tableend()); unless ($readonly) { @@ -6111,7 +6229,7 @@ sub overview { my $sortorder=$env{'form.sortorder'}; unless ($sortorder) { $sortorder='realmstudent'; } - &sortmenu($r,$sortorder); + &sortmenu($r,$sortorder,'overview'); my $submitbutton = '';