--- loncom/interface/lonhtmlcommon.pm 2002/07/22 20:35:05 1.1
+++ loncom/interface/lonhtmlcommon.pm 2004/01/27 16:35:37 1.42
@@ -1,71 +1,504 @@
+# The LearningOnline Network with CAPA
+# a pile of common html routines
+#
+# $Id: lonhtmlcommon.pm,v 1.42 2004/01/27 16:35:37 www Exp $
+#
+# Copyright Michigan State University Board of Trustees
+#
+# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
+#
+# LON-CAPA is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# LON-CAPA is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with LON-CAPA; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# /home/httpd/html/adm/gpl.txt
+#
+# http://www.lon-capa.org/
+#
+######################################################################
+######################################################################
+
+=pod
+
+=head1 NAME
+
+Apache::lonhtmlcommon - routines to do common html things
+
+=head1 SYNOPSIS
+
+Referenced by other mod_perl Apache modules.
+
+=head1 INTRODUCTION
+
+lonhtmlcommon is a collection of subroutines used to present information
+in a consistent html format, or provide other functionality related to
+html.
+
+=head2 General Subroutines
+
+=over 4
+
+=cut
+
+######################################################################
+######################################################################
+
package Apache::lonhtmlcommon;
+use Time::Local;
+use Apache::lonlocal;
use strict;
-sub MapOptions {
- my ($data, $page)=@_;
- my $Str = '';
- $Str .= ''."\n";
+##############################################
+##############################################
+
+sub recent_filename {
+ my $area=shift;
+ return 'nohist_recent_'.&Apache::lonnet::escape($area);
+}
+
+sub store_recent {
+ my ($area,$name,$value)=@_;
+ my $file=&recent_filename($area);
+ my %recent=&Apache::lonnet::dump($file);
+ if (scalar(keys(%recent))>10) {
+# remove oldest value
+ my $oldest=time;
+ my $delkey='';
+ foreach (keys %recent) {
+ my $thistime=(split(/\&/,$recent{$_}))[0];
+ if ($thistime<$oldest) {
+ $oldest=$thistime;
+ $delkey=$_;
+ }
+ }
+ &Apache::lonnet::del($file,[$delkey]);
+ }
+# store new value
+ &Apache::lonnet::put($file,{ $name =>
+ time.'&'.&Apache::lonnet::escape($value) });
+}
+
+sub select_recent {
+ my ($area,$fieldname,$event)=@_;
+ my %recent=&Apache::lonnet::dump(&recent_filename($area));
+ my $return="\n\n";
+ return $return;
+}
+
+
+=pod
+
+=item textbox
+=cut
+
+##############################################
+##############################################
+sub textbox {
+ my ($name,$value,$size,$special) = @_;
+ $size = 40 if (! defined($size));
+ my $Str = '';
return $Str;
}
-sub StudentOptions {
- my ($cache, $students, $selectedName, $page)=@_;
+##############################################
+##############################################
- my $Str = '';
- $Str = ''."\n";
+##############################################
+##############################################
+
+=pod
+
+=item &get_date_from_form
+
+get_date_from_form retrieves the date specified in an &date_setter form.
+
+Inputs:
+
+=over 4
+
+=item $dname
+
+The name passed to &datesetter, which prefixes the form elements.
+
+=item $defaulttime
+
+The unix time to use as the default in case of poor inputs.
+
+=back
+
+Returns: Unix time represented in the form.
+
+=cut
+
+##############################################
+##############################################
+sub get_date_from_form {
+ my ($dname) = @_;
+ my ($sec,$min,$hour,$day,$month,$year);
+ #
+ if (defined($ENV{'form.'.$dname.'_second'})) {
+ my $tmpsec = $ENV{'form.'.$dname.'_second'};
+ if (($tmpsec =~ /^\d+$/) && ($tmpsec >= 0) && ($tmpsec < 60)) {
+ $sec = $tmpsec;
+ }
+ }
+ if (defined($ENV{'form.'.$dname.'_minute'})) {
+ my $tmpmin = $ENV{'form.'.$dname.'_minute'};
+ if (($tmpmin =~ /^\d+$/) && ($tmpmin >= 0) && ($tmpmin < 60)) {
+ $min = $tmpmin;
+ }
+ }
+ if (defined($ENV{'form.'.$dname.'_hour'})) {
+ my $tmphour = $ENV{'form.'.$dname.'_hour'};
+ if (($tmphour =~ /^\d+$/) && ($tmphour >= 0) && ($tmphour < 24)) {
+ $hour = $tmphour;
+ }
+ }
+ if (defined($ENV{'form.'.$dname.'_day'})) {
+ my $tmpday = $ENV{'form.'.$dname.'_day'};
+ if (($tmpday =~ /^\d+$/) && ($tmpday > 0) && ($tmpday < 32)) {
+ $day = $tmpday;
+ }
+ }
+ if (defined($ENV{'form.'.$dname.'_month'})) {
+ my $tmpmonth = $ENV{'form.'.$dname.'_month'};
+ if (($tmpmonth =~ /^\d+$/) && ($tmpmonth > 0) && ($tmpmonth < 13)) {
+ $month = $tmpmonth - 1;
+ }
+ }
+ if (defined($ENV{'form.'.$dname.'_year'})) {
+ my $tmpyear = $ENV{'form.'.$dname.'_year'};
+ if (($tmpyear =~ /^\d+$/) && ($tmpyear > 1900)) {
+ $year = $tmpyear - 1900;
+ }
+ }
+ if (($year<70) || ($year>137)) { return undef; }
+ if (defined($sec) && defined($min) && defined($hour) &&
+ defined($day) && defined($month) && defined($year) &&
+ eval(&timelocal($sec,$min,$hour,$day,$month,$year))) {
+ return &timelocal($sec,$min,$hour,$day,$month,$year);
+ } else {
+ return undef;
+ }
+}
+
+##############################################
+##############################################
+
+=pod
+
+=item &pjump_javascript_definition()
+Returns javascript defining the 'pjump' function, which opens up a
+parameter setting wizard.
+
+=cut
+
+##############################################
+##############################################
+sub pjump_javascript_definition {
+ my $Str = <Active'."\n";
- $Str .= '
{'reportSelected'} eq $reports->{$_}) {
- $Str .= ' selected=""';
+=item $selectedSections A reference to an array containing the names of the
+currently selected sections.
+
+=back
+
+Returns: a string containing HTML for a multiple select box for
+selecting sections of a course.
+
+The form element name is 'Section'. @$sections is sorted prior to output.
+
+=cut
+
+########################################################
+########################################################
+sub MultipleSectionSelect {
+ my ($sections,$selectedSections)=@_;
+
+ my $Str = '';
+ $Str .= '
'."\n";
+ $Str .= ''."\n";
+
+ return $Str;
+}
+
+########################################################
+########################################################
+
+=pod
+
+=item &Title()
+
+Inputs: $pageName a string containing the name of the page to be sent
+to &Apache::loncommon::bodytag.
- $Str .= '
'."\n";
+Returns: string containing being and complete and
+as well as a '."\n";
return $Str;
}
+########################################################
+########################################################
+
=pod
-=item &CreateTableHeadings()
+=item &CreateHeadings()
This function generates the column headings for the chart.
=over 4
-Inputs: $CacheData, $studentInformation, $headings, $spacePadding
+Inputs: $CacheData, $keyID, $headings, $spacePadding
$CacheData: pointer to a hash tied to the cached data database
-$studentInformation: a pointer to an array containing the names of the data
+$keyID: a pointer to an array containing the names of the data
held in a column and is used as part of a key into $CacheData
$headings: The names of the headings for the student information
@@ -172,41 +638,53 @@ $Str: A formatted string of the table co
=cut
-sub CreateStudentInformationHeadings {
- my ($data,$studentInformation,$headings,$displayString)=@_;
+########################################################
+########################################################
+sub CreateHeadings {
+ my ($data,$keyID,$headings,$displayString,$format)=@_;
my $Str='';
+ my $formatting = '';
for(my $index=0; $index<(scalar @$headings); $index++) {
-# if(!&ShouldShowColumn($data, 'ChartHeading'.$index)) {
-# next;
-# }
- my $data=$headings->[$index];
- my $linkdata=$studentInformation->[$index];
+ my $currentHeading=$headings->[$index];
+ if($format eq 'preformatted') {
+ my @dataLength=split(//,$currentHeading);
+ my $length=scalar @dataLength;
+ $formatting = (' 'x
+ ($data->{$keyID->[$index].':columnWidth'}-$length));
+ }
+ my $linkdata=$keyID->[$index];
+
my $tempString = $displayString;
$tempString =~ s/LINKDATA/$linkdata/;
- $tempString =~ s/DISPLAYDATA/$data/;
+ $tempString =~ s/DISPLAYDATA/$currentHeading/;
+ $tempString =~ s/FORMATTING/$formatting/;
+
$Str .= $tempString;
}
return $Str;
}
+########################################################
+########################################################
+
=pod
=item &FormatStudentInformation()
-This function produces a formatted string of the student's information:
+This function produces a formatted string of the student\'s information:
username, domain, section, full name, and PID.
=over 4
-Input: $cache, $name, $studentInformation, $spacePadding
+Input: $cache, $name, $keyID, $spacePadding
$cache: This is a pointer to a hash that is tied to the cached data
$name: The name and domain of the current student in name:domain format
-$studentInformation: A pointer to an array holding the names used to
+$keyID: A pointer to an array holding the names used to
remove data from the hash. They represent the name of the data to be removed.
@@ -220,27 +698,250 @@ $Str: Formatted string.
=cut
+########################################################
+########################################################
sub FormatStudentInformation {
- my ($cache,$name,$studentInformation,$spacePadding)=@_;
+ my ($data,$name,$keyID,$displayString,$format)=@_;
my $Str='';
- my $data;
+ my $currentColumn;
+
+ for(my $index=0; $index<(scalar @$keyID); $index++) {
+ $currentColumn=$data->{$name.':'.$keyID->[$index]};
+
+ if($format eq 'preformatted') {
+ my @dataLength=split(//,$currentColumn);
+ my $length=scalar @dataLength;
+ $currentColumn.= (' 'x
+ ($data->{$keyID->[$index].':columnWidth'}-$length));
+ }
+
+ my $tempString = $displayString;
+ $tempString =~ s/DISPLAYDATA/$currentColumn/;
- for(my $index=0; $index<(scalar @$studentInformation); $index++) {
- if(!&ShouldShowColumn($cache, 'ChartHeading'.$index)) {
- next;
- }
- $data=$cache->{$name.':'.$studentInformation->[$index]};
- $Str .= $data;
-
- my @dataLength=split(//,$data);
- my $length=scalar @dataLength;
- $Str .= (' 'x($cache->{$studentInformation->[$index].'Length'}-
- $length));
- $Str .= $spacePadding;
+ $Str .= $tempString;
}
return $Str;
}
+########################################################
+########################################################
+
+=pod
+
+=item Progess Window Handling Routines
+
+These routines handle the creation, update, increment, and closure of
+progress windows. The progress window reports to the user the number
+of items completed and an estimate of the time required to complete the rest.
+
+=over 4
+
+
+=item &Create_PrgWin
+
+Writes javascript to the client to open a progress window and returns a
+data structure used for bookkeeping.
+
+Inputs
+
+=over 4
+
+=item $r Apache request
+
+=item $title The title of the progress window
+
+=item $heading A description (usually 1 line) of the process being initiated.
+
+=item $number_to_do The total number of items being processed.
+
+=back
+
+Returns a hash containing the progress state data structure.
+
+
+=item &Update_PrgWin
+
+Updates the text in the progress indicator. Does not increment the count.
+See &Increment_PrgWin.
+
+Inputs:
+
+=over 4
+
+=item $r Apache request
+
+=item $prog_state Pointer to the data structure returned by &Create_PrgWin
+
+=item $displaystring The string to write to the status indicator
+
+=back
+
+Returns: none
+
+
+=item Increment_PrgWin
+
+Increment the count of items completed for the progress window by 1.
+
+Inputs:
+
+=over 4
+
+=item $r Apache request
+
+=item $prog_state Pointer to the data structure returned by Create_PrgWin
+
+=item $extraInfo A description of the items being iterated over. Typically
+'student'.
+
+=back
+
+Returns: none
+
+
+=item Close_PrgWin
+
+Closes the progress window.
+
+Inputs:
+
+=over 4
+
+=item $r Apache request
+
+=item $prog_state Pointer to the data structure returned by Create_PrgWin
+
+=back
+
+Returns: none
+
+=back
+
+=cut
+
+########################################################
+########################################################
+
+# Create progress
+sub Create_PrgWin {
+ my ($r, $title, $heading, $number_to_do)=@_;
+ $r->print('");
+
+ my %prog_state;
+ $prog_state{'done'}=0;
+ $prog_state{'firststart'}=&Time::HiRes::time();
+ $prog_state{'laststart'}=&Time::HiRes::time();
+ $prog_state{'max'}=$number_to_do;
+
+ $r->rflush();
+ return %prog_state;
+}
+
+# update progress
+sub Update_PrgWin {
+ my ($r,$prog_state,$displayString)=@_;
+ $r->print('');
+ $$prog_state{'laststart'}=&Time::HiRes::time();
+ $r->rflush();
+}
+
+# increment progress state
+sub Increment_PrgWin {
+ my ($r,$prog_state,$extraInfo)=@_;
+ $$prog_state{'done'}++;
+ my $time_est= (&Time::HiRes::time() - $$prog_state{'firststart'})/
+ $$prog_state{'done'} *
+ ($$prog_state{'max'}-$$prog_state{'done'});
+ $time_est = int($time_est);
+ if (int ($time_est/60) > 0) {
+ my $min = int($time_est/60);
+ my $sec = $time_est % 60;
+ $time_est = $min.' '.&mt('minutes');
+ if ($min < 10) {
+ if ($sec > 1) {
+ $time_est.= ', '.$sec.' '.&mt('seconds');
+ } elsif ($sec > 0) {
+ $time_est.= ', '.$sec.' '.&mt('second');
+ }
+ }
+ } else {
+ $time_est .= ' '.&mt('seconds');
+ }
+ my $lasttime = &Time::HiRes::time()-$$prog_state{'laststart'};
+ if ($lasttime > 9) {
+ $lasttime = int($lasttime);
+ } elsif ($lasttime < 0.01) {
+ $lasttime = 0;
+ } else {
+ $lasttime = sprintf("%3.2f",$lasttime);
+ }
+ if ($lasttime == 1) {
+ $lasttime = '('.$lasttime.' '.&mt('second for').' '.$extraInfo.')';
+ } else {
+ $lasttime = '('.$lasttime.' '.&mt('seconds for').' '.$extraInfo.')';
+ }
+ #
+ my $user_browser = $ENV{'browser.type'} if (exists($ENV{'browser.type'}));
+ my $user_os = $ENV{'browser.os'} if (exists($ENV{'browser.os'}));
+ if (! defined($user_browser) || ! defined($user_os)) {
+ (undef,$user_browser,undef,undef,undef,$user_os) =
+ &Apache::loncommon::decode_user_agent();
+ }
+ if ($user_browser eq 'explorer' && $user_os =~ 'mac') {
+ $lasttime = '';
+ }
+ $r->print('');
+ $$prog_state{'laststart'}=&Time::HiRes::time();
+ $r->rflush();
+}
+
+# close Progress Line
+sub Close_PrgWin {
+ my ($r,$prog_state)=@_;
+ $r->print(''."\n");
+ undef(%$prog_state);
+ $r->rflush();
+}
+
+
+# ------------------------------------------------------- Puts directory header
+
+sub crumbs {
+ my ($uri,$target,$prefix,$form)=@_;
+ my $output=' '.$prefix.'/';
+ if ($ENV{'user.adv'}) {
+ my $path=$prefix;
+ foreach (split('/',$uri)) {
+ unless ($_) { next; }
+ $path.='/'.$_;
+ my $linkpath=$path;
+ if ($form) {
+ $linkpath="javascript:$form.action='$path/';$form.submit();";
+ }
+ $output.=''.$_.'/';
+ }
+ } else {
+ $output.=$uri;
+ }
+ unless ($uri=~/\/$/) { $output=~s/\/$//; }
+ return $output.' ';
+}
+
+
1;
+
__END__