'."\n";
for (my $row=1; $row<=8; $row++) {
foreach my $cat (keys(%category_members)) {
if ($category_positions{$cat} ne "$col,$row") { next; }
#$output.='
-//
-
-ENDCLOSE
-}
-
sub dc_popup_js {
my %lt = &Apache::lonlocal::texthash(
more => '(More ...)',
@@ -2199,12 +2354,12 @@ END
}
# This creates a "done button" for timed events. The confirmation box is a jQuery
-# dialog widget. If the interval parameter requires a proctor key for the timed
-# event to be marked done, there will also be a textbox where that can be entered.
-# Clicking OK will set the value of LC_interval_done to 'true', and, if needed will
-# set the value of LC_interval_done_proctorpass to the text entered in that box,
+# dialog widget. If the interval parameter requires a proctor key for the timed
+# event to be marked done, there will also be a textbox where that can be entered.
+# Clicking OK will set the value of LC_interval_done to 'true', and, if needed will
+# set the value of LC_interval_done_proctorpass to the text entered in that box,
# and submit the corresponding form.
-#
+#
# The &zero_time() routine in lonhomework.pm is called when a page is rendered if
# LC_interval_done is true.
#
@@ -2215,17 +2370,17 @@ sub done_button_js {
title => 'WARNING!',
preamble => 'You are trying to end this timed event early.',
map => 'Confirming that you are done will cause the time to expire and prevent you from changing any answers in the current folder.',
- resource => 'Confirming that you are done will cause the time to expire for this question, and prevent you from changing your answer(s).',
+ resource => 'Confirming that you are done will cause the time to expire for this question, and prevent you from changing your answer(s).',
okdone => 'Click "OK" if you are completely finished.',
cancel => 'Click "Cancel" to continue working.',
proctor => 'Ask a proctor to enter the key, then click "OK" if you are completely finished.',
ok => 'OK',
exit => 'Cancel',
key => 'Key:',
- nokey => 'A proctor key is required',
+ nokey => 'A proctor key is required',
);
my $shownsymb = &HTML::Entities::encode(&Apache::lonenc::check_encrypt($env{'request.symb'}));
- my $navmap = Apache::lonnavmaps::navmap->new();
+ my $navmap = Apache::lonnavmaps::navmap->new();
my ($missing,$tried) = (0,0);
if (ref($navmap)) {
my @resources=();
@@ -2274,7 +2429,7 @@ sub done_button_js {
if ($height !~ /^\d+$/) {
$height = 400;
if ($missing) {
- $height += 60;
+ $height += 60;
}
}
if ($width !~ /^\d+$/) {
@@ -2318,8 +2473,8 @@ sub done_button_js {
click: function() {
var proctorkey = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
if ((proctorkey == '') || (proctorkey == null)) {
- alert("$lt{'nokey'}");
- } else {
+ alert("$lt{'nokey'}");
+ } else {
\$( '[name="LC_interval_done"]' )[0].value = 'true';
\$( '[name="LC_interval_done_proctorpass"]' )[0].value = proctorkey;
\$( '[name="LCdoneButton"]' )[0].submit();
@@ -2412,6 +2567,126 @@ END
}
}
+sub view_as_js {
+ my ($url,$symb) = @_;
+ my %lt = &Apache::lonlocal::texthash(
+ ente => 'Enter a username or a student/employee ID',
+ info => 'Information you entered does not match a valid course user',
+ );
+ &js_escape(\%lt);
+ return <<"END";
+
+function toggleViewAsUser(change) {
+ if (document.getElementById('LC_selectuser')) {
+ var seluserid = document.getElementById('LC_selectuser');
+ var currstyle = seluserid.style.display;
+ if (change == 'off') {
+ document.userview.elements['LC_viewas'].value = '';
+ document.userview.elements['vuname'].value = '';
+ document.userview.elements['vid'].value = '';
+ document.userview.submit();
+ return;
+ }
+ if ((document.getElementById('usexpand')) && (document.getElementById('uscollapse'))) {
+ if (currstyle == 'inline') {
+ seluserid.style.display = 'none';
+ document.getElementById('usexpand').style.display= 'inline';
+ document.getElementById('uscollapse').style.display = 'none';
+ } else {
+ seluserid.style.display = 'inline';
+ toggleIdentifier(document.userview);
+ document.getElementById('usexpand').style.display = 'none';
+ document.getElementById('uscollapse').style.display = 'inline';
+ }
+ }
+ }
+ return;
+}
+
+function validCourseUser(form,change) {
+ var possuname = form.elements['vuname'].value;
+ var possuid = form.elements['vid'].value;
+ var domelem = form.elements['vudom'];
+ var possudom = '';
+ if ((domelem.tagName === 'INPUT') && ((domelem.type === 'text') || (domelem.type === 'hidden'))) {
+ possudom = domelem.value;
+ } else if (domelem.tagName === 'SELECT') {
+ possudom = domelem.options[domelem.selectedIndex].value;
+ }
+ if ((possuname == '') && (possuid == '')) {
+ if (change == 'off') {
+ form.elements['LC_viewas'].value = '';
+ form.submit();
+ } else {
+ alert("$lt{'ente'}");
+ }
+ return;
+ }
+ var http = new XMLHttpRequest();
+ var url = "/adm/courseuser";
+ var params = "uname="+possuname+"&uid="+possuid+"&udom="+possudom;
+ http.open("POST", url, true);
+ http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ http.onreadystatechange = function() {
+ if (http.readyState == 4 && http.status == 200) {
+ var data = JSON.parse(http.responseText);
+ if (Array.isArray(data.match)) {
+ var len = data.match.length;
+ if (len == 2) {
+ if (data.match[0] != '' && data.match[1] != '') {
+ form.elements['LC_viewas'].value = data.match[0]+':'+data.match[1];
+ form.submit();
+ }
+ } else {
+ alert("$lt{'info'}");
+ }
+ }
+ }
+ return;
+ }
+ http.send(params);
+ return false;
+}
+
+function toggleIdentifier(form) {
+ if ((document.getElementById('LC_vuname')) && (document.getElementById('LC_vid'))) {
+ var identifylabel = document.getElementById('LC_vuidentifier');
+ var identifier;
+ var userbyuname;
+ var radioelem = form.elements['vuidentifier'];
+ if (radioelem.length > 0) {
+ var i;
+ for (i=0; i
+
ENDSERVERFORM
}
sub constspaceform {
+ my ($frameset) = @_;
+ my ($target,$printtarget);
+ if ($frameset) {
+ $target = ' target="_parent"';
+ $printtarget = ' target="_parent"';
+ } else {
+ unless ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
+ (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
+ $target = ' target="_top"';
+ $printtarget = ' target="_top"';
+ }
+ }
return(<
+
-
-
+
ENDCONSTSPACEFORM
}
-sub get_nav_status {
- my $navstatus="swmenu.w_loncapanav_flag=";
- if ($env{'environment.remotenavmap'} eq 'on') {
- $navstatus.="1";
- } else {
- $navstatus.="-1";
- }
- return $navstatus;
-}
-
sub hidden_button_check {
if ( $env{'request.course.id'} eq ''
|| $env{'request.role.adv'} ) {
@@ -2679,12 +3038,12 @@ sub hidden_button_check {
}
sub roles_selector {
- my ($cdom,$cnum,$httphost) = @_;
+ my ($cdom,$cnum,$httphost,$target,$menucoll,$menuref) = @_;
my $crstype = &Apache::loncommon::course_type();
my $now = time;
my (%courseroles,%seccount,%courseprivs,%roledesc);
my $is_cc;
- my ($js,$form,$switcher);
+ my ($js,$form,$switcher,$has_opa_priv);
my $ccrole;
if ($crstype eq 'Community') {
$ccrole = 'co';
@@ -2714,7 +3073,7 @@ sub roles_selector {
if (exists($reqprivs->{$destination})) {
if ($reqprivs->{$destination} =~ /,/) {
@{$privref} = split(/,/,$reqprivs->{$destination});
- } else {
+ } else {
$privref = [$reqprivs->{$destination}];
}
}
@@ -2785,32 +3144,45 @@ sub roles_selector {
}
}
if ((keys(%seccount) > 1) || ($numdiffsec > 1)) {
+ my $targetattr;
+ if ($target ne '') {
+ $targetattr = ' target="'.$target.'"';
+ }
my @submenu;
- $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,\%roledesc,$privref);
+ $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,
+ \%roledesc,$privref,$menucoll,$menuref);
$form =
- ''."\n";
+ $form .= ''."\n".
+ ''."\n";
foreach my $role (@roles_order) {
my $include;
if (defined($courseroles{$role})) {
if ($env{'request.role'} =~ m{^\Q$role\E}) {
if ($seccount{$role} > 1) {
$include = 1;
+ } else {
+ if ($env{'user.priv.'.$env{'request.role'}."./$cdom/$cnum"} =~/opa\&([^\:]*)/) {
+ $has_opa_priv = 1;
+ }
}
} else {
$include = 1;
}
}
if ($include) {
+ if ($env{"user.priv.$role./$cdom/$cnum./$cdom/$cnum"} =~/opa\&([^\:]*)/) {
+ $has_opa_priv = 1;
+ }
push(@submenu,['javascript:adhocRole('."'$role'".')',
&Apache::lonnet::plaintext($role,$crstype)]);
}
@@ -2823,7 +3195,7 @@ sub roles_selector {
$include = 1;
}
} else {
- $include = 1;
+ $include = 1;
}
if ($include) {
my $rolename;
@@ -2835,16 +3207,19 @@ sub roles_selector {
} else {
$rolename = &Apache::lonnet::plaintext($role);
}
+ if ($env{"user.priv.$role./$cdom/$cnum./$cdom/$cnum"} =~/opa\&([^\:]*)/) {
+ $has_opa_priv = 1;
+ }
push(@submenu,['javascript:adhocRole('."'$role'".')',
$rolename]);
}
}
}
if (@submenu > 0) {
- $switcher = &create_submenu('','',&mt('Switch role'),\@submenu);
+ $switcher = &create_submenu('#',$target,&mt('Switch role'),\@submenu);
}
}
- return ($js,$form,$switcher);
+ return ($js,$form,$switcher,$has_opa_priv);
}
sub get_all_courseroles {
@@ -2907,7 +3282,7 @@ sub get_all_courseroles {
push(@{$courseroles->{'st'}},keys(%sections_count));
$seccount->{'st'} = scalar(keys(%sections_count));
}
- $seccount->{'st'} ++; # Increment for a section-less student role.
+ $seccount->{'st'} ++; # Increment for a section-less student role.
my $rolehash = {
'roles' => $courseroles,
'seccount' => $seccount,
@@ -2964,7 +3339,7 @@ sub get_customadhoc_roles {
foreach my $role (keys(%{$domdefaults{'adhocroles'}})) {
next if (($role eq '') || ($role =~ /\W/));
$seccount->{"$prefix/$role"} = $numsec;
- $roledesc->{"$prefix/$role"} = $description->{$role};
+ $roledesc->{"$prefix/$role"} = $description->{$role};
if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0)) {
if (exists($env{"user.priv.$prefix/$role./$cdom/$cnum./"})) {
$courseprivs->{"$prefix/$role./$cdom/$cnum./"} =
@@ -3011,7 +3386,8 @@ sub get_customadhoc_roles {
}
sub jump_to_role {
- my ($cdom,$cnum,$seccount,$courseroles,$courseprivs,$roledesc,$privref) = @_;
+ my ($cdom,$cnum,$seccount,$courseroles,$courseprivs,$roledesc,$privref,
+ $menucoll,$menuref) = @_;
my %lt = &Apache::lonlocal::texthash(
this => 'This role has section(s) associated with it.',
ente => 'Enter a specific section.',
@@ -3022,6 +3398,7 @@ sub jump_to_role {
role => 'The role you selected is not permitted to view the current page.',
swit => 'Switch role, but display Main Menu page instead?',
);
+ &js_escape(\%lt);
my $js;
if (ref($courseroles) eq 'HASH') {
$js = ' var secpick = new Array("'.$lt{'ente'}.'","'.$lt{'orlb'}.'");'."\n".
@@ -3044,6 +3421,8 @@ sub jump_to_role {
}
}
my $checkroles = 0;
+ my $fallback = '/adm/menu';
+ my $displaymsg = $lt{'swit'};
if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0) && (ref($courseprivs) eq 'HASH')) {
my %disallowed;
foreach my $role (sort(keys(%{$courseprivs}))) {
@@ -3065,8 +3444,22 @@ sub jump_to_role {
$checkroles = 1;
$js .= " var disallow = new Array('".join("','",keys(%disallowed))."');\n".
" var rolecheck = 1;\n";
+ if ($menucoll) {
+ if (ref($menuref) eq 'HASH') {
+ if ($menuref->{'main'} eq 'n') {
+ $fallback = '/adm/navmaps';
+ if (&Apache::loncommon::course_type() eq 'Community') {
+ $displaymsg = &mt('Switch role, but display Community Contents page instead?');
+ } else {
+ $displaymsg = &mt('Switch role, but display Course Contents page instead?');
+ }
+ &js_escape(\$displaymsg);
+ }
+ }
+ }
}
}
+ &js_escape(\$fallback);
if (!$checkroles) {
$js .= " var disallow = new Array();\n".
" rolecheck = 0;\n";
@@ -3089,8 +3482,8 @@ function adhocRole(newrole) {
if (rolecheck > 0) {
for (var i=0; i{'starttime'} < $now) &&
@@ -3243,13 +3645,14 @@ sub countdown_timer {
$title = $alttxt.' ';
}
my $desc = &mt('Countdown to due date/time');
+
return <
$collapse
-
+
$expand
$title
@@ -3259,6 +3662,101 @@ END
return;
}
+sub placement_progress {
+ my ($totalpoints,$incomplete) = &Apache::lonplacementtest::check_completion(undef,undef,1);
+ my $complete = 100 - $incomplete;
+ return ''.
+ &mt('Test is [_1]% complete',$complete).'';
+}
+
+sub linkprot_exit {
+ if (($env{'request.course.id'}) && ($env{'request.deeplink.login'})) {
+ my ($deeplink_symb,$deeplink);
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ if (($cnum ne '') && ($cdom ne '')) {
+ $deeplink_symb = &Apache::loncommon::deeplink_login_symb($cnum,$cdom);
+ if ($deeplink_symb) {
+ if ($deeplink_symb =~ /\.(page|sequence)$/) {
+ my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[2]);
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (ref($navmap)) {
+ $deeplink = $navmap->get_mapparam(undef,$mapname,'0.deeplink');
+ }
+ } else {
+ $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$deeplink_symb);
+ }
+ if ($deeplink ne '') {
+ my ($state,$others,$listed,$scope,$protect,$display,$target,$exit) = split(/,/,$deeplink);
+ my %lt = &Apache::lonlocal::texthash(
+ title => 'Exit Tool',
+ okdone => 'Click "OK" to exit embedded tool',
+ cancel => 'Click "Cancel" to continue working.',
+ ok => 'OK',
+ exit => 'Cancel',
+ );
+ if ($exit) {
+ my ($show,$text) = split(/:/,$exit);
+ unless ($show eq 'no') {
+ my $height = 250;
+ my $width = 300;
+ my $exitbuttontext;
+ if ($text eq '') {
+ $exitbuttontext = &mt('Exit Tool');
+ } else {
+ $exitbuttontext = $text;
+ }
+ return <
+
+
+
+
+
'.&mt($category_names{$cat}).' |

+
+
+
+
+END
+ }
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
# ================================================================ Main Program
BEGIN {
@@ -3275,13 +3773,13 @@ BEGIN {
$category_positions{$entries[2]}=$entries[1];
$category_names{$entries[2]}=$entries[3];
} elsif ($configline=~/^prim\:/) {
- my @entries = (split(/\:/, $configline))[1..6];
+ my @entries = (split(/\:/, $configline))[1..7];
push(@primary_menu,\@entries);
} elsif ($configline=~/^primsub\:/) {
- my ($parent,@entries) = (split(/\:/, $configline))[1..4];
+ my ($parent,@entries) = (split(/\:/, $configline))[1..5];
push(@{$primary_submenu{$parent}},\@entries);
} elsif ($configline=~/^scnd\:/) {
- my @entries = (split(/\:/, $configline))[1..5];
+ my @entries = (split(/\:/, $configline))[1..6];
push(@secondary_menu,\@entries);
} elsif ($configline=~/^scndsub\:/) {
my ($parent,@entries) = (split(/\:/, $configline))[1..4];
$lt{'okdone'} $lt{'cancel'}
+