$text";
}
# Add the graphic
@@ -805,14 +801,10 @@ sub help_open_menu {
my ($topic,$component_help,$faq,$bug,$stayOnPage,$width,$height,$text)
= @_;
$stayOnPage = 0 if (not defined $stayOnPage);
- # formerly only used pop-up help (stayOnPage = 0)
+ # only use pop-up help (stayOnPage == 0)
# if environment.remote is on (using remote control UI)
- # if ($env{'browser.interface'} eq 'textual' ||
- # $env{'environment.remote'} eq 'off' ) {
- # $stayOnPage=1;
- #}
- # Now making pop-up help the default even with remote control
- if ($env{'browser.interface'} eq 'textual') {
+ if ($env{'browser.interface'} eq 'textual' ||
+ $env{'environment.remote'} eq 'off' ) {
$stayOnPage=1;
}
my $output;
@@ -834,15 +826,13 @@ sub help_open_menu {
sub top_nav_help {
my ($text) = @_;
-
$text = &mt($text);
-
- my $stayOnPage =
+ my $stay_on_page =
($env{'browser.interface'} eq 'textual' ||
$env{'environment.remote'} eq 'off' );
- my $link= ($stayOnPage) ? "javascript:helpMenu('display')"
+ my $link = ($stay_on_page) ? "javascript:helpMenu('display')"
: "javascript:helpMenu('open')";
- my $banner_link = &update_help_link(undef,undef,undef,undef,$stayOnPage);
+ my $banner_link = &update_help_link(undef,undef,undef,undef,$stay_on_page);
my $title = &mt('Get help');
@@ -870,7 +860,7 @@ sub help_menu_js {
'js_ready' => 1,
'add_entries' => {
'border' => '0',
- 'rows' => "105,*",},});
+ 'rows' => "110,*",},});
my $end_page =
&Apache::loncommon::end_page({'frameset' => 1,
'js_ready' => 1,});
@@ -1084,6 +1074,138 @@ sub changable_area {
=pod
+=item * viewport_geometry_js {
+
+Provides javascript object (Geometry) which can provide information about the viewport geometry for the client browser.
+
+=cut
+
+
+sub viewport_geometry_js {
+ return <<"GEOMETRY";
+var Geometry = {};
+function init_geometry() {
+ if (Geometry.init) { return };
+ Geometry.init=1;
+ if (window.innerHeight) {
+ Geometry.getViewportHeight = function() { return window.innerHeight; };
+ Geometry.getViewportWidth = function() { return window.innerWidth; };
+ Geometry.getHorizontalScroll = function() { return window.pageXOffset; };
+ Geometry.getVerticalScroll = function() { return window.pageYOffset; };
+ }
+ else if (document.documentElement && document.documentElement.clientHeight) {
+ Geometry.getViewportHeight =
+ function() { return document.documentElement.clientHeight; };
+ Geometry.getViewportWidth =
+ function() { return document.documentElement.clientWidth; };
+
+ Geometry.getHorizontalScroll =
+ function() { return document.documentElement.scrollLeft; };
+ Geometry.getVerticalScroll =
+ function() { return document.documentElement.scrollTop; };
+ }
+ else if (document.body.clientHeight) {
+ Geometry.getViewportHeight =
+ function() { return document.body.clientHeight; };
+ Geometry.getViewportWidth =
+ function() { return document.body.clientWidth; };
+ Geometry.getHorizontalScroll =
+ function() { return document.body.scrollLeft; };
+ Geometry.getVerticalScroll =
+ function() { return document.body.scrollTop; };
+ }
+}
+
+GEOMETRY
+}
+
+=pod
+
+=item * viewport_size_js {
+
+Provides a javascript function to set values of two form elements - width and height (elements are passed in as arguments to the javascript function) to the dimensions of the user's browser window.
+
+=cut
+
+sub viewport_size_js {
+ my $geometry = &viewport_geometry_js();
+ return <<"DIMS";
+
+$geometry
+
+function getViewportDims(width,height) {
+ init_geometry();
+ width.value = Geometry.getViewportWidth();
+ height.value = Geometry.getViewportHeight();
+ return;
+}
+
+DIMS
+}
+
+=pod
+
+=item * resize_textarea_js
+
+emits the needed javascript to resize a textarea to be as big as possible
+
+creates a function resize_textrea that takes two IDs first should be
+the id of the element to resize, second should be the id of a div that
+surrounds everything that comes after the textarea, this routine needs
+to be attached to the for the onload and onresize events.
+
+
+=cut
+
+sub resize_textarea_js {
+ my $geometry = &viewport_geometry_js();
+ return <<"RESIZE";
+
+RESIZE
+
+}
+
+=pod
+
=back
=head1 Excel and CSV file utility routines
@@ -1285,8 +1407,6 @@ sub domain_select {
=over 4
-=cut
-
=item * multiple_select_form($name,$value,$size,$hash,$order)
Returns a string containing a
Transaction '.$version.'
';
foreach my $key (sort(keys(%lasthash))) {
- my $value;
- if ($key =~ /timestamp/) {
- $value=scalar(localtime($returnhash{$version.':'.$key}));
- } else {
- $value=$returnhash{$version.':'.$key};
- }
- $prevattempts.='
'.&unescape($value).'
';
+ my $value = &format_previous_attempt_value($key,
+ $returnhash{$version.':'.$key});
+ $prevattempts.='
'.$value.'
';
}
}
}
$prevattempts.='
Current
';
foreach my $key (sort(keys(%lasthash))) {
- my $value;
- if ($key =~ /timestamp/) {
- $value=scalar(localtime($lasthash{$key}));
- } else {
- $value=$lasthash{$key};
- }
- $value=&unescape($value);
+ my $value = &format_previous_attempt_value($key,$lasthash{$key});
if ($key =~/$regexp$/ && (defined &$gradesub)) {$value = &$gradesub($value)}
$prevattempts.='
'.$value.'
';
}
@@ -2621,6 +2989,19 @@ sub get_previous_attempt {
}
}
+sub format_previous_attempt_value {
+ my ($key,$value) = @_;
+ if ($key =~ /timestamp/) {
+ $value = &Apache::lonlocal::locallocaltime($value);
+ } elsif (ref($value) eq 'ARRAY') {
+ $value = '('.join(', ', @{ $value }).')';
+ } else {
+ $value = &unescape($value);
+ }
+ return $value;
+}
+
+
sub relative_to_absolute {
my ($url,$output)=@_;
my $parser=HTML::TokeParser->new(\$output);
@@ -2779,9 +3160,9 @@ sub pprmlink {
if (!$symb) { $symb=&Apache::lonnet::symbread(); }
$symb=&escape($symb);
if ($target) { $target="target=\"$target\""; }
- return ''.$text.'';
+ return ''.$text.'';
}
##############################################
@@ -3458,9 +3839,6 @@ sub bodytag {
if (!$realm) { $realm=' '; }
# Set messages
my $messages=&domainlogo($domain);
-# Port for miniserver
- my $lonhttpdPort=$Apache::lonnet::perlvar{'lonhttpdPort'};
- if (!defined($lonhttpdPort)) { $lonhttpdPort='8080'; }
my $extra_body_attr = &make_attr_string($forcereg,\%design);
@@ -3578,7 +3956,7 @@ ENDROLE
my $imgsrc = $img;
if ($img =~ /^\/adm/) {
- $imgsrc = 'http://'.$ENV{'HTTP_HOST'}.':'.$lonhttpdPort.$img;
+ $imgsrc = &lonhttpdurl($img);
}
my $upperleft='';
@@ -3751,7 +4129,7 @@ table.thinborder tr td {
form, .inline { display: inline; }
.center { text-align: center; }
-.LC_filename {font-family: $mono;}
+.LC_filename {font-family: $mono; white-space:pre;}
.LC_error {
color: red;
font-size: larger;
@@ -3997,13 +4375,13 @@ table.LC_data_table, table.LC_mail_list
}
table.LC_nested_outer {
border: 1px solid #000000;
- border-collapse: separate;
+ border-collapse: collapse;
border-spacing: 0px;
width: 100%;
}
table.LC_nested {
border: 0px;
- border-collapse: separate;
+ border-collapse: collapse;
border-spacing: 0px;
width: 100%;
}
@@ -4055,7 +4433,8 @@ table.LC_nested tr.LC_info_row td {
font-size: small;
text-align: center;
}
-table.LC_nested tr.LC_info_row td.LC_left_item {
+table.LC_nested tr.LC_info_row td.LC_left_item,
+table.LC_nested_outer tr th.LC_left_item {
text-align: left;
}
table.LC_nested td {
@@ -4286,9 +4665,7 @@ table#LC_helpmenu_links a:hover {
border: 1px solid #8888FF;
background: #CCCCFF;
}
-
table.LC_pick_box {
- width: 100%;
border-collapse: separate;
background: white;
border: 1px solid black;
@@ -4301,6 +4678,14 @@ table.LC_pick_box td.LC_pick_box_title {
width: 184px;
padding: 8px;
}
+table.LC_pick_box td.LC_pick_box_value {
+ text-align: left;
+ padding: 8px;
+}
+table.LC_pick_box td.LC_pick_box_select {
+ text-align: left;
+ padding: 8px;
+}
table.LC_pick_box td.LC_pick_box_separator {
padding: 0px;
height: 1px;
@@ -4309,7 +4694,48 @@ table.LC_pick_box td.LC_pick_box_separat
table.LC_pick_box td.LC_pick_box_submit {
text-align: right;
}
-
+table.LC_pick_box td.LC_evenrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_pick_box td.LC_oddrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_helpform_receipt {
+ width: 620px;
+ border-collapse: separate;
+ background: white;
+ border: 1px solid black;
+ border-spacing: 1px;
+}
+table.LC_helpform_receipt td.LC_pick_box_title {
+ background: $tabbg;
+ font-weight: bold;
+ text-align: right;
+ width: 184px;
+ padding: 8px;
+}
+table.LC_helpform_receipt td.LC_evenrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_helpform_receipt td.LC_oddrow_value {
+ text-align: left;
+ padding: 8px;
+ background-color: $data_table_light;
+}
+table.LC_helpform_receipt td.LC_pick_box_separator {
+ padding: 0px;
+ height: 1px;
+ background: black;
+}
+span.LC_helpform_receipt_cat {
+ font-weight: bold;
+}
table.LC_group_priv_box {
background: white;
border: 1px solid black;
@@ -4454,6 +4880,10 @@ span.LC_nobreak {
white-space: nowrap;
}
+span.LC_cusr_emph {
+ font-style: italic;
+}
+
table.LC_docs_documents {
background: #BBBBBB;
border-width: 0px;
@@ -4521,6 +4951,53 @@ table.LC_docs_adddocs th {
background: #DDDDDD;
}
+table.LC_sty_begin {
+ background: #BBFFBB;
+}
+table.LC_sty_end {
+ background: #FFBBBB;
+}
+
+table.LC_double_column {
+ border-width: 0px;
+ border-collapse: collapse;
+ width: 100%;
+ padding: 2px;
+}
+
+table.LC_double_column tr td.LC_left_col {
+ top: 2px;
+ left: 2px;
+ width: 47%;
+ vertical-align: top;
+}
+
+table.LC_double_column tr td.LC_right_col {
+ top: 2px;
+ right: 2px;
+ width: 47%;
+ vertical-align: top;
+}
+
+span.LC_role_level {
+ font-weight: bold;
+}
+
+div.LC_left_float {
+ float: left;
+ padding-right: 5%;
+ padding:bottom: 4px;
+}
+
+div.LC_clear_float_header {
+ padding:bottom: 2px;
+}
+
+div.LC_clear_float_footer {
+ padding:top: 10px;
+ clear: both;
+}
+
END
}
@@ -4637,7 +5114,9 @@ Inputs: none
sub xml_begin {
my $output='';
- &Apache::lonhtmlcommon::init_htmlareafields();
+ if ($env{'internal.start_page'}==1) {
+ &Apache::lonhtmlcommon::init_htmlareafields();
+ }
if ($env{'browser.mathml'}) {
$output=''
@@ -5552,11 +6031,11 @@ sub get_secgrprole_info {
}
sub user_picker {
- my ($dom,$srch,$forcenewuser) = @_;
+ my ($dom,$srch,$forcenewuser,$caller) = @_;
my $currdom = $dom;
my %curr_selected = (
srchin => 'dom',
- srchby => 'uname',
+ srchby => 'lastname',
);
my $srchterm;
if (ref($srch) eq 'HASH') {
@@ -5575,16 +6054,26 @@ sub user_picker {
$srchterm = $srch->{'srchterm'};
}
my %lt=&Apache::lonlocal::texthash(
+ 'usr' => 'Search criteria',
'doma' => 'Domain/institution to search',
'uname' => 'username',
'lastname' => 'last name',
'lastfirst' => 'last name, first name',
'crs' => 'in this course',
- 'dom' => 'in this domain',
+ 'dom' => 'in selected LON-CAPA domain',
'alc' => 'all LON-CAPA',
- 'instd' => 'in institutional directory',
+ 'instd' => 'in institutional directory for selected domain',
'exact' => 'is',
'contains' => 'contains',
+ 'begins' => 'begins with',
+ 'youm' => "You must include some text to search for.",
+ 'thte' => "The text you are searching for must contain at least two characters when using a 'begins' type search.",
+ 'thet' => "The text you are searching for must contain at least three characters when using a 'contains' type search.",
+ 'yomc' => "You must choose a domain when using an institutional directory search.",
+ 'ymcd' => "You must choose a domain when using a domain search.",
+ 'whus' => "When using searching by last,first you must include a comma as separator between last name and first name.",
+ 'whse' => "When searching by last,first you must include at least one character in the first name.",
+ 'thfo' => "The following need to be corrected before the search can be run:",
);
my $domform = &select_dom_form($currdom,'srchdomain',1,1);
my $srchinsel = ' \n";
my $srchbysel = ' \n";
my $srchtypesel = '
END_BLOCK
@@ -5751,7 +6254,58 @@ END_BLOCK
return $output;
}
-
+sub username_rule_check {
+ my ($srch,$caller) = @_;
+ my ($response,@curr_rules,%inst_results,$rulematch);
+ my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($srch->{'srchdomain'});
+ if (ref($srch) eq 'HASH') {
+ (my $inst_response,%inst_results) =
+ &Apache::lonnet::get_instuser($srch->{'srchdomain'},
+ $srch->{'srchterm'});
+ my %domconfig = &Apache::lonnet::get_dom('configuration',
+ ['usercreation'],$srch->{'srchdomain'});
+ if (ref($domconfig{'usercreation'}) eq 'HASH') {
+ if (ref($domconfig{'usercreation'}{'username_rule'}) eq 'ARRAY') {
+ @curr_rules = @{$domconfig{'usercreation'}{'username_rule'}};
+ }
+ }
+ if (@curr_rules > 0) {
+ my $domdesc = &Apache::lonnet::domain($srch->{'srchdomain'},'description');
+ my $instuser_reqd;
+ my %rule_check = &Apache::lonnet::inst_rulecheck($srch->{'srchdomain'},$srch->{'srchterm'},\@curr_rules);
+ foreach my $rule (@curr_rules) {
+ if ($rule_check{$rule}) {
+ $rulematch = $rule;
+ if ($inst_response eq 'ok') {
+ if (keys(%inst_results) == 0) {
+ if ($caller eq 'new') {
+ $response = &mt('The username you chose matches the format of usernames defined for [_1], but the user does not exist in the institutional directory.',$domdesc).' '.&mt("You must choose a username with a different format -- one that will not conflict with 'official' institutional usernames.");
+ }
+ }
+ }
+ last;
+ }
+ }
+ if ($response) {
+ if ((ref($rules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) {
+ if (@{$ruleorder} > 0) {
+ $response .= ' '.&mt('Usernames with the following format(s) may only be used for verified users at [_1]:',$domdesc).'
';
+ foreach my $rule (@{$ruleorder}) {
+ if (grep(/^\Q$rule\E$/,@curr_rules)) {
+ if (ref($rules->{$rule}) eq 'HASH') {
+ $response .= '