Diff for /loncom/interface/lonhtmlcommon.pm between versions 1.19 and 1.90

version 1.19, 2003/03/21 15:59:14 version 1.90, 2004/09/29 14:50:43
Line 56  html. Line 56  html.
 package Apache::lonhtmlcommon;  package Apache::lonhtmlcommon;
   
 use Time::Local;  use Time::Local;
   use Time::HiRes;
   use Apache::lonlocal;
 use strict;  use strict;
   
 ##############################################  ##############################################
Line 63  use strict; Line 65  use strict;
   
 =pod  =pod
   
   =item authorbombs
   
   =cut
   
   ##############################################
   ##############################################
   
   sub authorbombs {
       my $url=shift;
       $url=&Apache::lonnet::declutter($url);
       my ($udom,$uname)=($url=~/^(\w+)\/(\w+)\//);
       my %bombs=&Apache::lonmsg::all_url_author_res_msg($uname,$udom);
       foreach (keys %bombs) {
    if ($_=~/^$udom\/$uname\//) {
       return '<a href="/adm/bombs/'.$url.
    '"><img src="/adm/lonMisc/bomb.gif" border="0" /></a>'.
    &Apache::loncommon::help_open_topic('About_Bombs');
    }
       }
       return '';
   }
   
   ##############################################
   ##############################################
   
   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 remove_recent {
       my ($area,$names)=@_;
       my $file=&recent_filename($area);
       return &Apache::lonnet::del($file,$names);
   }
   
   sub select_recent {
       my ($area,$fieldname,$event)=@_;
       my %recent=&Apache::lonnet::dump(&recent_filename($area));
       my $return="\n<select name='$fieldname'".
    ($event?" onChange='$event'":'').
    ">\n<option value=''>--- ".&mt('Recent')." ---</option>";
       foreach (sort keys %recent) {
    unless ($_=~/^error\:/) {
       $return.="\n<option value='$_'>".
    &Apache::lonnet::unescape((split(/\&/,$recent{$_}))[1]).
    '</option>';
    }
       }
       $return.="\n</select>\n";
       return $return;
   }
   
   
   =pod
   
   =item textbox
   
   =cut
   
   ##############################################
   ##############################################
   sub textbox {
       my ($name,$value,$size,$special) = @_;
       $size = 40 if (! defined($size));
       my $Str = '<input type="text" name="'.$name.'" size="'.$size.'" '.
           'value="'.$value.'" '.$special.' />';
       return $Str;
   }
   
   ##############################################
   ##############################################
   
   =pod
   
   =item checkbox
   
   =cut
   
   ##############################################
   ##############################################
   sub checkbox {
       my ($name,$checked,$value) = @_;
       my $Str = '<input type="checkbox" name="'.$name.'" ';
       if (defined($value)) {
           $Str .= 'value="'.$value.'"';
       } 
       if ($checked) {
           $Str .= ' checked="1"';
       }
       $Str .= ' />';
       return $Str;
   }
   
   ##############################################
   ##############################################
   
   =pod
   
 =item &date_setter  =item &date_setter
   
   &date_setter returns html and javascript for a compact date-setting form.
   To retrieve values from it, use &get_date_from_form().
   
 Inputs  Inputs
   
 =over 4  =over 4
Line 82  The current setting for this time parame Line 208  The current setting for this time parame
 An undefined value is taken to indicate the value is the current time.  An undefined value is taken to indicate the value is the current time.
 Also, to be explicit, a value of 'now' also indicates the current time.  Also, to be explicit, a value of 'now' also indicates the current time.
   
   =item $special
   
   Additional html/javascript to be associated with each element in
   the date_setter.  See lonparmset for example usage.
   
   =item $includeempty 
   
   =item $state
   
   Specifies the initial state of the form elements.  Either 'disabled' or empty.
   Defaults to empty, which indiciates the form elements are not disabled. 
   
   =back
   
   Bugs
   
   The method used to restrict user input will fail in the year 2400.
   
 =cut  =cut
   
 ##############################################  ##############################################
 ##############################################  ##############################################
 sub date_setter {  sub date_setter {
     my ($formname,$dname,$currentvalue) = @_;      my ($formname,$dname,$currentvalue,$special,$includeempty,$state,
           $no_hh_mm_ss) = @_;
       if (! defined($state) || $state ne 'disabled') {
           $state = '';
       }
       if (! defined($no_hh_mm_ss)) {
           $no_hh_mm_ss = 0;
       }
     if (! defined($currentvalue) || $currentvalue eq 'now') {      if (! defined($currentvalue) || $currentvalue eq 'now') {
         $currentvalue = time;   unless ($includeempty) {
       $currentvalue = time;
    } else {
       $currentvalue = 0;
    }
     }      }
     # other potentially useful values:     wkday,yrday,is_daylight_savings      # other potentially useful values:     wkday,yrday,is_daylight_savings
     my ($sec,$min,$hour,$mday,$month,$year,undef,undef,undef) =       my ($sec,$min,$hour,$mday,$month,$year)=('','',undef,'','','');
         localtime($currentvalue);      if ($currentvalue) {
     $year += 1900;   ($sec,$min,$hour,$mday,$month,$year,undef,undef,undef) = 
       localtime($currentvalue);
    $year += 1900;
       }
     my $result = "\n<!-- $dname date setting form -->\n";      my $result = "\n<!-- $dname date setting form -->\n";
     $result .= <<ENDJS;      $result .= <<ENDJS;
 <script language="Javascript">  <script language="Javascript">
Line 128  sub date_setter { Line 286  sub date_setter {
             document.$formname.$dname\_day.value = 30;              document.$formname.$dname\_day.value = 30;
         }          }
     }      }
   
       function $dname\_disable() {
           document.$formname.$dname\_month.disabled=true;
           document.$formname.$dname\_day.disabled=true;
           document.$formname.$dname\_year.disabled=true;
           document.$formname.$dname\_hour.disabled=true;
           document.$formname.$dname\_minute.disabled=true;
           document.$formname.$dname\_second.disabled=true;
       }
   
       function $dname\_enable() {
           document.$formname.$dname\_month.disabled=false;
           document.$formname.$dname\_day.disabled=false;
           document.$formname.$dname\_year.disabled=false;
           document.$formname.$dname\_hour.disabled=false;
           document.$formname.$dname\_minute.disabled=false;
           document.$formname.$dname\_second.disabled=false;        
       }
   
       function $dname\_opencalendar() {
           if (! document.$formname.$dname\_month.disabled) {
               var calwin=window.open(
   "/adm/announcements?pickdate=yes&formname=$formname&element=$dname&month="+
   document.$formname.$dname\_month.value+"&year="+
   document.$formname.$dname\_year.value,
                "LONCAPAcal",
                 "height=350,width=350,scrollbars=yes,resizable=yes,menubar=no");
           }
   
       }
 </script>  </script>
 ENDJS  ENDJS
     $result .= "  <select name=\"$dname\_month\" ".      $result .= "  <nobr><select name=\"$dname\_month\" ".$special.' '.
           $state.' '.
         "onChange=\"javascript:$dname\_checkday()\" >\n";          "onChange=\"javascript:$dname\_checkday()\" >\n";
       # Month
     my @Months = qw/January February  March     April   May      June       my @Months = qw/January February  March     April   May      June 
                     July    August    September October November December/;                      July    August    September October November December/;
     # Pad @Months with a bogus value to make indexing easier      # Pad @Months with a bogus value to make indexing easier
     unshift(@Months,'If you can read this an error occurred');      unshift(@Months,'If you can read this an error occurred');
       if ($includeempty) { $result.="<option value=''></option>"; }
     for(my $m = 1;$m <=$#Months;$m++) {      for(my $m = 1;$m <=$#Months;$m++) {
         $result .= "      <option value=\"$m\" ";          $result .= "      <option value=\"$m\" ";
         $result .= "selected " if ($m-1 == $month);          $result .= "selected " if ($m-1 eq $month);
         $result .= "> $Months[$m] </option>\n";          $result .= "> ".&mt($Months[$m])." </option>\n";
     }      }
     $result .= "  </select>\n";      $result .= "  </select>\n";
     $result .= "  <input type=\"text\" name=\"$dname\_day\" ".      # Day
             "value=\"$mday\" size=\"3\" ".      $result .= "  <input type=\"text\" name=\"$dname\_day\" ".$state.' '.
               "value=\"$mday\" size=\"3\" ".$special.' '.
             "onChange=\"javascript:$dname\_checkday()\" />\n";              "onChange=\"javascript:$dname\_checkday()\" />\n";
     $result .= "  <input type=\"year\" name=\"$dname\_year\" ".      # Year
             "value=\"$year\" size=\"5\" ".      $result .= "  <input type=\"year\" name=\"$dname\_year\" ".$state.' '.
               "value=\"$year\" size=\"5\" ".$special.' '.
             "onChange=\"javascript:$dname\_checkday()\" />\n";              "onChange=\"javascript:$dname\_checkday()\" />\n";
     $result .= "&nbsp;&nbsp;";      $result .= "&nbsp;&nbsp;";
     $result .= "  <select name=\"$dname\_hour\" >\n";      if (! $no_hh_mm_ss) {
     for (my $h = 0;$h<24;$h++) {          # Hours
         $result .= "      <option value=\"$h\" ";          $result .= "  <select name=\"$dname\_hour\" ".$special." ".$state.' '.
         $result .= "selected " if ($hour == $h);              ">\n";
         $result .= "> ";          if ($includeempty) { $result.="<option value=''></option>"; }
         if ($h == 0) {          for (my $h = 0;$h<24;$h++) {
             $result .= "12 am";              $result .= "      <option value=\"$h\" ";
         } elsif($h == 12) {              $result .= "selected " if (defined($hour) && $hour == $h);
             $result .= "12 noon";              $result .= "> ";
         } elsif($h < 12) {              my $timest='';
             $result .= "$h am";              if ($h == 0) {
         } else {                  $timest .= "12 am";
             $result .= $h-12 ." pm";              } elsif($h == 12) {
         }                  $timest .= "12 noon";
         $result .= " </option>\n";              } elsif($h < 12) {
     }                   $timest .= "$h am";
     $result .= "  </select>\n";              } else {
     $result .= "  <input type=\"text\" name=\"$dname\_minute\" ".                  $timest .= $h-12 ." pm";
         "value=\"$min\" size=\"3\" /> m\n";              }
     $result .= "  <input type=\"text\" name=\"$dname\_second\" ".              $timest=&mt($timest);
         "value=\"$sec\" size=\"3\" /> s\n";              $result .= $timest." </option>\n";
     $result .= "<!-- end $dname date setting form -->\n";          } 
           $result .= "  </select>\n";
           $result .= "  <input type=\"text\" name=\"$dname\_minute\" ".
               $special.' '.
               $state.' '.
               "value=\"$min\" size=\"3\" /> m\n";
           $result .= "  <input type=\"text\" name=\"$dname\_second\" ".
               $special.' '.
               $state.' '.
               "value=\"$sec\" size=\"3\" /> s\n";
       }
       $result .= "<a href=\"javascript:$dname\_opencalendar()\">".
       &mt('Select Date')."</a></nobr>\n<!-- end $dname date setting form -->\n";
     return $result;      return $result;
 }  }
   
 ##############################################  ##############################################
 ##############################################  ##############################################
   
   =pod
   
 =item &get_date_from_form  =item &get_date_from_form
   
   get_date_from_form retrieves the date specified in an &date_setter form.
   
 Inputs:  Inputs:
   
 =over 4  =over 4
Line 208  sub get_date_from_form { Line 417  sub get_date_from_form {
         if (($tmpsec =~ /^\d+$/) && ($tmpsec >= 0) && ($tmpsec < 60)) {          if (($tmpsec =~ /^\d+$/) && ($tmpsec >= 0) && ($tmpsec < 60)) {
             $sec = $tmpsec;              $sec = $tmpsec;
         }          }
    if (!defined($tmpsec) || $tmpsec eq '') { $sec = 0; }
       } else {
           $sec = 0;
     }      }
     if (defined($ENV{'form.'.$dname.'_minute'})) {      if (defined($ENV{'form.'.$dname.'_minute'})) {
         my $tmpmin = $ENV{'form.'.$dname.'_minute'};          my $tmpmin = $ENV{'form.'.$dname.'_minute'};
         if (($tmpmin =~ /^\d+$/) && ($tmpmin >= 0) && ($tmpmin < 60)) {          if (($tmpmin =~ /^\d+$/) && ($tmpmin >= 0) && ($tmpmin < 60)) {
             $min = $tmpmin;              $min = $tmpmin;
         }          }
    if (!defined($tmpmin) || $tmpmin eq '') { $min = 0; }
       } else {
           $min = 0;
     }      }
     if (defined($ENV{'form.'.$dname.'_hour'})) {      if (defined($ENV{'form.'.$dname.'_hour'})) {
         my $tmphour = $ENV{'form.'.$dname.'_hour'};          my $tmphour = $ENV{'form.'.$dname.'_hour'};
         if (($tmphour =~ /^\d+$/) && ($tmphour > 0) && ($tmphour < 32)) {          if (($tmphour =~ /^\d+$/) && ($tmphour >= 0) && ($tmphour < 24)) {
             $hour = $tmphour;              $hour = $tmphour;
         }          }
       } else {
           $hour = 0;
     }      }
     if (defined($ENV{'form.'.$dname.'_day'})) {      if (defined($ENV{'form.'.$dname.'_day'})) {
         my $tmpday = $ENV{'form.'.$dname.'_day'};          my $tmpday = $ENV{'form.'.$dname.'_day'};
Line 239  sub get_date_from_form { Line 456  sub get_date_from_form {
             $year = $tmpyear - 1900;              $year = $tmpyear - 1900;
         }          }
     }      }
     if (eval(&timelocal($sec,$min,$hour,$day,$month,$year))) {      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);          return &timelocal($sec,$min,$hour,$day,$month,$year);
     } else {      } else {
         return undef;          return undef;
Line 251  sub get_date_from_form { Line 471  sub get_date_from_form {
   
 =pod  =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 = <<END;
       function pjump(type,dis,value,marker,ret,call) {
           parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
                    +"&value="+escape(value)+"&marker="+escape(marker)
                    +"&return="+escape(ret)
                    +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
                    "height=350,width=350,scrollbars=no,menubar=no");
       }
   END
       return $Str;
   }
   
   ##############################################
   ##############################################
   
   =pod
   
 =item &javascript_nothing()  =item &javascript_nothing()
   
 Return an appropriate null for the users browser.  This is used  Return an appropriate null for the users browser.  This is used
Line 280  sub javascript_nothing { Line 527  sub javascript_nothing {
   
 ##############################################  ##############################################
 ##############################################  ##############################################
   sub javascript_docopen {
       # safari does not understand document.open() and loads "text/html"
       my $nothing = "''";
 sub AscendOrderOptions {      my $user_browser;
     my ($order, $page, $formName)=@_;      my $user_os;
       $user_browser = $ENV{'browser.type'} if (exists($ENV{'browser.type'}));
     my $OpSel1 = '';      $user_os      = $ENV{'browser.os'}   if (exists($ENV{'browser.os'}));
     my $OpSel2 = '';      if (! defined($user_browser) || ! defined($user_os)) {
           (undef,$user_browser,undef,undef,undef,$user_os) = 
     if($order eq 'Ascending') {                             &Apache::loncommon::decode_user_agent();
         $OpSel1 = ' selected';  
     } else {  
         $OpSel2 = ' selected';  
     }  
   
     my $Str = '';  
     $Str .= '<select name="'.(($page)?$page:'').'Ascend"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
     $Str .= '<option'.$OpSel1.'>Ascending</option>'."\n".  
     '<option'.$OpSel2.'>Descending</option>'."\n";  
     $Str .= '</select>'."\n";  
   
     return $Str;  
 }  
   
 sub MapOptions {  
     my ($data, $page, $formName)=@_;  
     my $Str = '';  
     $Str .= '<select name="';  
     $Str .= (($page)?$page:'').'Maps"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected = 0;  
     foreach my $sequence (split(':',$data->{'orderedSequences'})) {  
  $Str .= '<option';  
         if($data->{$page.'Maps'} eq $data->{$sequence.':title'}) {  
             $Str .= ' selected';  
             $selected = 1;  
         }  
  $Str .= '>'.$data->{$sequence.':title'}.'</option>'."\n";       
     }  
     $Str .= '<option';  
     if(!$selected) {  
         $Str .= ' selected';  
     }  
     $Str .= '>All Maps</option>'."\n";  
   
     $Str .= '</select>'."\n";  
   
     return $Str;  
 }  
   
 sub ProblemOptions {  
     my ($data, $page, $map, $formName)=@_;  
     my $Str = '';  
     $Str .= '<select name="';  
     $Str .= (($page)?$page:'').'ProblemSelect"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected = 0;  
     foreach my $sequence (split(':',$data->{'orderedSequences'})) {  
  if($data->{$sequence.':title'} eq $map || $map eq 'All Maps') {  
     foreach my $problem (split(':', $data->{$sequence.':problems'})) {  
  $Str .= '<option';  
  if($data->{$page.'ProblemSelect'} eq   
    $data->{$problem.':title'}) {  
     $Str .= ' selected';  
     $selected = 1;  
  }  
  $Str .= '>'.$data->{$problem.':title'}.'</option>'."\n";  
     }  
  }  
     }      }
     $Str .= '<option';      if ($user_browser eq 'safari' && $user_os =~ 'mac') {
     if(!$selected) {          $nothing = "document.clear()";
         $Str .= ' selected';      } else {
    $nothing = "document.open('text/html','replace')";
     }      }
     $Str .= '>All Problems</option>'."\n";      return $nothing;
   
     $Str .= '</select>'."\n";  
   
     return $Str;  
 }  }
   
 sub PartOptions {  
     my ($data, $page, $parts, $formName)=@_;  
     my $Str = '';  
   
     if(!defined($parts)) {  
  return '';  
     }  
   
     $Str .= '<select name="';  
     $Str .= (($page)?$page:'').'PartSelect"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected = 0;  ##############################################
     foreach my $part (@$parts) {  ##############################################
  $Str .= '<option';  
  if($data->{$page.'PartSelect'} eq $part) {  
     $Str .= ' selected';  
     $selected = 1;  
  }  
  $Str .= '>'.$part.'</option>'."\n";       
     }  
     $Str .= '<option';  
     if(!$selected) {  
         $Str .= ' selected';  
     }  
     $Str .= '>All Parts</option>'."\n";  
   
     $Str .= '</select>'."\n";  =pod
   
     return $Str;  =item &StatusOptions()
 }  
   
 sub StudentOptions {  Returns html for a selection box which allows the user to choose the
     my ($cache, $students, $selectedName, $page, $formName)=@_;  enrollment status of students.  The selection box name is 'Status'.
   
     my $Str = '';  Inputs:
     $Str .= '<select name="'.(($page)?$page:'').'Student"';  
     if($formName) {  
         $Str .= ' onchange="document.'.$formName.'.submit()"';  
     }  
     $Str .= '>'."\n";  
   
     my $selected=0;  $status: the currently selected status.  If undefined the value of
   $ENV{'form.Status'} is taken.  If that is undefined, a value of 'Active'
   is used.
   
     foreach (@$students) {  $formname: The name of the form.  If defined the onchange attribute of
  $Str .= '<option';  the selection box is set to document.$formname.submit().
  if($selectedName eq $_) {  
             $Str .= ' selected';  
             $selected = 1;  
         }  
         $Str .= '>';  
         $Str .= $cache->{$_.':fullname'};  
         $Str .= '</option>'."\n";       
     }  
   
     $Str .= '<option';  $size: the size (number of lines) of the selection box.
     if($selectedName eq 'No Student Selected') {  
         $Str .= ' selected';  
         $selected = 1;  
     }  
     $Str .= '>No Student Selected</option>'."\n";  
   
     $Str .= '<option';  $onchange: javascript to use when the value is changed.  Enclosed in 
     if(!$selected) {  double quotes, ""s, not single quotes.
         $Str .= ' selected';  
     }  
     $Str .= '>All Students</option>'."\n";  
   
     $Str .= '</select>'."\n";  Returns: a perl string as described.
   
     return $Str;  =cut
 }  
   
   ##############################################
   ##############################################
 sub StatusOptions {  sub StatusOptions {
     my ($status, $formName)=@_;      my ($status, $formName,$size,$onchange)=@_;
       $size = 1 if (!defined($size));
       if (! defined($status)) {
           $status = 'Active';
           $status = $ENV{'form.Status'} if (exists($ENV{'form.Status'}));
       }
   
     my $OpSel1 = '';      my $OpSel1 = '';
     my $OpSel2 = '';      my $OpSel2 = '';
Line 462  sub StatusOptions { Line 595  sub StatusOptions {
   
     my $Str = '';      my $Str = '';
     $Str .= '<select name="Status"';      $Str .= '<select name="Status"';
     if(defined($formName) && $formName ne '') {      if(defined($formName) && $formName ne '' && ! defined($onchange)) {
         $Str .= ' onchange="document.'.$formName.'.submit()"';          $Str .= ' onchange="document.'.$formName.'.submit()"';
     }      }
       if (defined($onchange)) {
           $Str .= ' onchange="'.$onchange.'"';
       }
       $Str .= ' size="'.$size.'" ';
     $Str .= '>'."\n";      $Str .= '>'."\n";
     $Str .= '<option'.$OpSel1.'>Active</option>'."\n";      $Str .= '<option value="Active" '.$OpSel1.'>'.
     $Str .= '<option'.$OpSel2.'>Expired</option>'."\n";          &mt('Currently Enrolled').'</option>'."\n";
     $Str .= '<option'.$OpSel3.'>Any</option>'."\n";      $Str .= '<option value="Expired" '.$OpSel2.'>'.
           &mt('Previously Enrolled').'</option>'."\n";
       $Str .= '<option value="Any" '.$OpSel3.'>'.
           &mt('Any Enrollment Status').'</option>'."\n";
     $Str .= '</select>'."\n";      $Str .= '</select>'."\n";
 }  }
   
   
 ########################################################  ########################################################
 ########################################################  ########################################################
   
 =pod  =pod
   
 =item &MultipleSectionSelect()  =item Progess Window Handling Routines
   
 Inputs:   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  =over 4
   
 =item $sections A references to an array containing the names of all the  
 sections used in a class.  
   
 =item $selectedSections A reference to an array containing the names of the  =item &Create_PrgWin
 currently selected sections.  
   
 =back   Writes javascript to the client to open a progress window and returns a
   data structure used for bookkeeping.
   
 Returns: a string containing HTML for a multiple select box for  Inputs
 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 .= '<select name="Section" multiple="true" size="4">'."\n";  
   
     foreach (sort @$sections) {  =over 4
         $Str .= '<option';  
         foreach my $selected (@$selectedSections) {  
             if($_ eq $selected) {  
                 $Str .= ' selected=""';  
             }  
         }  
         $Str .= '>'.$_.'</option>'."\n";  
     }  
     $Str .= '</select>'."\n";  
       
     return $Str;  
 }  
   
 ########################################################  =item $r Apache request
 ########################################################  
   
 =pod  =item $title The title of the progress window
   
 =item &Title()  =item $heading A description (usually 1 line) of the process being initiated.
   
 Inputs: $pageName a string containing the name of the page to be sent  =item $number_to_do The total number of items being processed.
 to &Apache::loncommon::bodytag.  
   
 Returns: string containing being <html> and complete <head> and <title>  =item $type Either 'popup' or 'inline' (popup is assumed if nothing is
 as well as a <script> to focus the current window and change its width         specified)
 and height to 500.  Why?  I do not know.  If you find out, please update  
 this documentation.  
   
 =cut  =item $width Specify the width in charaters of the input field.
   
 ########################################################  =item $formname Only useful in the inline case, if a form already exists, this needs to be used and specfiy the name of the form, otherwise the Progress line will be created in a new form of it's own
 ########################################################  
 sub Title {  
     my ($pageName)=@_;  
   
     my $Str = '';  =item $inputname Only useful in the inline case, if a form and an input of type text exists, use this to specify the name of the input field 
   
     $Str .= '<html><head><title>'.$pageName.'</title></head>'."\n";  =back
     $Str .= &Apache::loncommon::bodytag($pageName)."\n";  
     $Str .= '<script>window.focus(); window.width=500;window.height=500;';  
     $Str .= '</script>'."\n";  
   
     return $Str;  Returns a hash containing the progress state data structure.
 }  
   
 ########################################################  
 ########################################################  
   
 =pod  =item &Update_PrgWin
   
 =item &CreateHeadings()  Updates the text in the progress indicator.  Does not increment the count.
   See &Increment_PrgWin.
   
 This function generates the column headings for the chart.  Inputs:
   
 =over 4  =over 4
   
 Inputs: $CacheData, $keyID, $headings, $spacePadding  =item $r Apache request
   
 $CacheData: pointer to a hash tied to the cached data database  
   
 $keyID: a pointer to an array containing the names of the data   =item $prog_state Pointer to the data structure returned by &Create_PrgWin
 held in a column and is used as part of a key into $CacheData  
   
 $headings: The names of the headings for the student information  =item $displaystring The string to write to the status indicator
   
 $spacePadding: The spaces to go between columns  =back
   
 Output: $Str  Returns: none
   
 $Str: A formatted string of the table column headings.  
   
 =back  =item Increment_PrgWin
   
 =cut  Increment the count of items completed for the progress window by 1.  
   
 ########################################################  Inputs:
 ########################################################  
 sub CreateHeadings {  
     my ($data,$keyID,$headings,$displayString,$format)=@_;  
     my $Str='';  
     my $formatting = '';  
   
     for(my $index=0; $index<(scalar @$headings); $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/$currentHeading/;  
         $tempString =~ s/FORMATTING/$formatting/;  
   
         $Str .= $tempString;  =over 4
     }  
   
     return $Str;  =item $r Apache request
 }  
   
 ########################################################  =item $prog_state Pointer to the data structure returned by Create_PrgWin
 ########################################################  
   
 =pod  =item $extraInfo A description of the items being iterated over.  Typically
   'student'.
   
 =item &FormatStudentInformation()  =back
   
 This function produces a formatted string of the student\'s information:  Returns: none
 username, domain, section, full name, and PID.  
   
 =over 4  
   
 Input: $cache, $name, $keyID, $spacePadding  =item Close_PrgWin
   
 $cache: This is a pointer to a hash that is tied to the cached data  Closes the progress window.
   
 $name:  The name and domain of the current student in name:domain format  Inputs:
   
 $keyID: A pointer to an array holding the names used to  =over 4 
   
 remove data from the hash.  They represent the name of the data to be removed.  =item $r Apache request
   
 $spacePadding: Extra spaces that represent the space between columns  =item $prog_state Pointer to the data structure returned by Create_PrgWin
   
 Output: $Str  =back
   
 $Str: Formatted string.  Returns: none
   
 =back  =back
   
Line 645  $Str: Formatted string. Line 719  $Str: Formatted string.
   
 ########################################################  ########################################################
 ########################################################  ########################################################
 sub FormatStudentInformation {  
     my ($data,$name,$keyID,$displayString,$format)=@_;  
     my $Str='';  
     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/;  
   
         $Str .= $tempString;  my $uniq=0;
     }  sub get_uniq_name {
       $uniq++;
     return $Str;      return 'uniquename'.$uniq;
 }  }
   
 ########################################################  
 ########################################################  
   
 # Create progress  # Create progress
 sub Create_PrgWin {  sub Create_PrgWin {
     my ($r, $title, $heading, $number_to_do)=@_;      my ($r, $title, $heading, $number_to_do,$type,$width,$formname,
     $r->print('<script>'.   $inputname)=@_;
     "popwin=open(\'\',\'popwin\',\'width=400,height=100\');".      if (!defined($type)) { $type='popup'; }
     "popwin.document.writeln(\'<html><head><title>$title</title></head>".      if (!defined($width)) { $width=55; }
       my %prog_state;
       $prog_state{'type'}=$type;
       if ($type eq 'popup') {
    $prog_state{'window'}='popwin';
    #the whole function called through timeout is due to issues
    #in mozilla Read BUG #2665 if you want to know the whole story
    &r_print($r,'<script>'.
           "var popwin;
            function openpopwin () {
            popwin=open(\'\',\'popwin\',\'width=400,height=100\');".
           "popwin.document.writeln(\'<html><head><title>$title</title></head>".
       "<body bgcolor=\"#88DDFF\">".        "<body bgcolor=\"#88DDFF\">".
               "<h4>$heading</h4>".                "<h4>$heading</h4>".
               "<form name=popremain>".                "<form name=popremain>".
               "<input type=text size=55 name=remaining value=Starting></form>".                '<input type="text" size="'.$width.'" name="remaining" value="'.
         &mt('Starting').'"></form>'.
               "</body></html>\');".                "</body></html>\');".
     "popwin.document.close();".          "popwin.document.close();}".
     "</script>");          "\nwindow.setTimeout(openpopwin,0)</script>");
    $prog_state{'formname'}='popremain';
    $prog_state{'inputname'}="remaining";
       } elsif ($type eq 'inline') {
    $prog_state{'window'}='window';
    if (!$formname) {
       $prog_state{'formname'}=&get_uniq_name();
       &r_print($r,'<form name="'.$prog_state{'formname'}.'">');
    } else {
       $prog_state{'formname'}=$formname;
    }
    if (!$inputname) {
       $prog_state{'inputname'}=&get_uniq_name();
       &r_print($r,$heading.' <input type="text" name="'.$prog_state{'inputname'}.
        '" size="'.$width.'" />');
    } else {
       $prog_state{'inputname'}=$inputname;
       
    }
    if (!$formname) { &r_print($r,'</form>'); }
    &Update_PrgWin($r,\%prog_state,&mt('Starting'));
       }
   
     my %prog_state;  
     $prog_state{'done'}=0;      $prog_state{'done'}=0;
     $prog_state{'firststart'}=time;      $prog_state{'firststart'}=&Time::HiRes::time();
     $prog_state{'laststart'}=time;      $prog_state{'laststart'}=&Time::HiRes::time();
     $prog_state{'max'}=$number_to_do;      $prog_state{'max'}=$number_to_do;
       
     $r->rflush();  
     return %prog_state;      return %prog_state;
 }  }
   
 # update progress  # update progress
 sub Update_PrgWin {  sub Update_PrgWin {
     my ($r,$prog_state,$displayString)=@_;      my ($r,$prog_state,$displayString)=@_;
     $r->print('<script>popwin.document.popremain.remaining.value="'.      &r_print($r,'<script>'.$$prog_state{'window'}.'.document.'.
               $displayString.'";</script>');       $$prog_state{'formname'}.'.'.
     $$prog_state{'laststart'}=time;       $$prog_state{'inputname'}.'.value="'.
     $r->rflush();       $displayString.'";</script>');
       $$prog_state{'laststart'}=&Time::HiRes::time();
 }  }
   
 # increment progress state  # increment progress state
 sub Increment_PrgWin {  sub Increment_PrgWin {
     my ($r,$prog_state,$extraInfo)=@_;      my ($r,$prog_state,$extraInfo)=@_;
     $$prog_state{'done'}++;      $$prog_state{'done'}++;
     my $time_est= (time - $$prog_state{'firststart'})/$$prog_state{'done'} *      my $time_est= (&Time::HiRes::time() - $$prog_state{'firststart'})/
           $$prog_state{'done'} *
  ($$prog_state{'max'}-$$prog_state{'done'});   ($$prog_state{'max'}-$$prog_state{'done'});
     $time_est = int($time_est);      $time_est = int($time_est);
     if (int ($time_est/60) > 0) {      #
  my $min = int($time_est/60);      my $min = int($time_est/60);
  my $sec = $time_est % 60;      my $sec = $time_est % 60;
  $time_est = $min.' minutes';      # 
  if ($sec > 1) {      my $str;
     $time_est.= ', '.$sec.' seconds';      if ($min == 1 && $sec > 1) {
  } elsif ($sec > 0) {          $str = '[_2] seconds';
     $time_est.= ', '.$sec.' second';      } elsif ($min == 1 && $sec < 2) {
  }          $str = '1 minute';
       } elsif ($min < 10 && $sec > 1) {
           $str = '[_1] minutes, [_2] seconds';
       } elsif ($min >= 10 || $sec < 2) {
           $str = '[_1] minutes';
       }
       $time_est = &mt($str,$min,$sec);
       #
       my $lasttime = &Time::HiRes::time()-$$prog_state{'laststart'};
       if ($lasttime > 9) {
           $lasttime = int($lasttime);
       } elsif ($lasttime < 0.01) {
           $lasttime = 0;
     } else {      } else {
  $time_est .= ' seconds';          $lasttime = sprintf("%3.2f",$lasttime);
     }      }
     my $lasttime = time-$$prog_state{'laststart'};  
     if ($lasttime == 1) {      if ($lasttime == 1) {
         $lasttime = '('.$lasttime.' second for '.$extraInfo.')';          $lasttime = '('.$lasttime.' '.&mt('second for').' '.$extraInfo.')';
     } else {      } else {
         $lasttime = '('.$lasttime.' seconds for '.$extraInfo.')';          $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();
     }      }
     $r->print('<script>popwin.document.popremain.remaining.value="'.      if ($user_browser eq 'explorer' && $user_os =~ 'mac') {
       $$prog_state{'done'}.'/'.$$prog_state{'max'}.          $lasttime = '';
       ': '.$time_est.' remaining '.$lasttime.'";'.'</script>');      }
     $$prog_state{'laststart'}=time;      &r_print($r,'<script>'.$$prog_state{'window'}.'.document.'.
     $r->rflush();       $$prog_state{'formname'}.'.'.
        $$prog_state{'inputname'}.'.value="'.
        $$prog_state{'done'}.'/'.$$prog_state{'max'}.
        ': '.$time_est.' '.&mt('remaining').' '.$lasttime.'";'.'</script>');
       $$prog_state{'laststart'}=&Time::HiRes::time();
 }  }
   
 # close Progress Line  # close Progress Line
 sub Close_PrgWin {  sub Close_PrgWin {
     my ($r,$prog_state)=@_;      my ($r,$prog_state)=@_;
     $r->print('<script>popwin.close()</script>'."\n");      if ($$prog_state{'type'} eq 'popup') {
    &r_print($r,'<script>popwin.close()</script>'."\n");
       } elsif ($$prog_state{'type'} eq 'inline') {
    &Update_PrgWin($r,$prog_state,&mt('Done'));
       }
     undef(%$prog_state);      undef(%$prog_state);
     $r->rflush();   
 }  }
   
   sub r_print {
       my ($r,$to_print)=@_;
       if ($r) {
    $r->print($to_print);
    $r->rflush();
       } else {
    print($to_print);
       }
   }
   
   # ------------------------------------------------------- Puts directory header
   
   sub crumbs {
       my ($uri,$target,$prefix,$form,$size,$noformat)=@_;
       if (! defined($size)) {
           $size = '+2';
       }
       my $output='';
       unless ($noformat) { $output.='<br /><tt><b>'; }
       $output.='<font size="'.$size.'">'.$prefix.'/';
       if ($ENV{'user.adv'}) {
    my $path=$prefix.'/';
    foreach (split('/',$uri)) {
       unless ($_) { next; }
       $path.=$_;
       unless ($path eq $uri) { $path.='/'; }
       my $linkpath=$path;
       if ($form) {
    $linkpath="javascript:$form.action='$path';$form.submit();";
       }
       $output.='<a href="'.$linkpath.'"'.($target?' target="'.$target.'"':'').'>'.$_.'</a>/';
    }
       } else {
    $output.=$uri;
       }
       unless ($uri=~/\/$/) { $output=~s/\/$//; }
       return $output.'</font>'.($noformat?'':'</b></tt><br />');
   }
   
   # --------------------- A function that generates a window for the spellchecker
   
   sub spellheader {
       my $nothing = &javascript_nothing();
       return (<<ENDCHECK);
   <script type="text/javascript"> 
   // BEGIN LON-CAPA Internal
   var checkwin;
   
   function spellcheckerwindow() {
       checkwin=window.open($nothing,'spellcheckwin','height=320,width=280,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
       checkwin.document.writeln('<html><body bgcolor="#DDDDDD"><form name="spellcheckform" action="/adm/spellcheck" method="post"><input type="hidden" name="text" value="" /></form></body></html>');
       checkwin.document.close();
   }
   // END LON-CAPA Internal
   </script>
   ENDCHECK
   }
   
   # ---------------------------------- Generate link to spell checker for a field
   
   sub spelllink {
       my ($form,$field)=@_;
       my $linktext=&mt('Check Spelling');
       return (<<ENDLINK);
   <a href="javascript:if (typeof(document.$form.onsubmit)!='undefined') { document.$form.onsubmit();};spellcheckerwindow();checkwin.document.forms.spellcheckform.text.value=this.document.forms.$form.$field.value;checkwin.document.forms.spellcheckform.submit();">$linktext</a>
   ENDLINK
   }
   
   # ------------------------------------------------- Output headers for HTMLArea
   
   sub htmlareaheaders {
       if (&htmlareablocked()) { return ''; }
       unless (&htmlareabrowser()) { return ''; }
       my $lang='en';
       if (&mt('htmlarea_lang') ne 'htmlarea_lang') {
    $lang=&mt('htmlarea_lang');
       }
       return (<<ENDHEADERS);
   <script type="text/javascript">
   _editor_url='/htmlarea/';
   _editor_lang='$lang';
   </script>
   <script type="text/javascript" src="/htmlarea/htmlarea.js"></script>
   ENDHEADERS
   }
   
   # ------------------------------------------------- Activate additional buttons
   
   sub htmlareaaddbuttons {
       if (&htmlareablocked()) { return ''; }
       unless (&htmlareabrowser()) { return ''; }
       return (<<ENDADDBUTTON);
       var config=new HTMLArea.Config();
       config.registerButton('ed_math','LaTeX Inline',
     '/htmlarea/images/ed_math.gif',false,
       function(editor,id) {
         editor.surroundHTML('&nbsp;<m>\$','\$</m>&nbsp;');
       }
     );
       config.registerButton('ed_math_eqn','LaTeX Equation',
     '/htmlarea/images/ed_math_eqn.gif',false,
       function(editor,id) {
         editor.surroundHTML(
        '&nbsp;\\n<center><m>\\\\[','\\\\]</m></center>\\n&nbsp;');
       }
     );
       config.toolbar.push(['ed_math','ed_math_eqn']);
   ENDADDBUTTON
   }
   
   # ----------------------------------------------------------------- Preferences
   
   sub disablelink {
       my @fields=@_;
       if (defined($#fields)) {
    unless ($#fields>=0) { return ''; }
       }
       return '<a href="/adm/preferences?action=set_wysiwyg&wysiwyg=off&returnurl='.&Apache::lonnet::escape($ENV{'REQUEST_URI'}).'">'.&mt('Disable WYSIWYG Editor').'</a>';
   }
   
   sub enablelink {
       my @fields=@_;
       if (defined($#fields)) {
    unless ($#fields>=0) { return ''; }
       }
       return '<a href="/adm/preferences?action=set_wysiwyg&wysiwyg=on&returnurl='.&Apache::lonnet::escape($ENV{'REQUEST_URI'}).'">'.&mt('Enable WYSIWYG Editor').'</a>';
   }
   
   # ----------------------------------------- Script to activate only some fields
   
   sub htmlareaselectactive {
       my @fields=@_;
       unless (&htmlareabrowser()) { return ''; }
       if (&htmlareablocked()) { return '<br />'.&enablelink(@fields); }
       my $output='<script type="text/javascript" defer="1">'.
    &htmlareaaddbuttons();
       foreach(@fields) {
    $output.="\nHTMLArea.replace('$_',config);";
       }
       $output.="\nwindow.status='Activated Editfields';\n</script><br />".
    &disablelink(@fields);
       return $output;
   }
   
   # --------------------------------------------------------------------- Blocked
   
   sub htmlareablocked {
       unless ($ENV{'environment.wysiwygeditor'} eq 'on') { return 1; }
       return 0;
   }
   
   # ---------------------------------------- Browser capable of running HTMLArea?
   
   sub htmlareabrowser {
       return 1;
   }
   
   ############################################################
   ############################################################
   
   =pod
   
   =item breadcrumbs
   
   Compiles the previously registered breadcrumbs into an series of links.
   FAQ and BUG links will be placed on the left side of the table if they
   are defined for the last registered breadcrumb.  
   Additionally supports a 'component', which will be displayed on the
   right side of the table (without a link).
   A link to help for the component will be included if one is specified.
   
   All inputs can be undef without problems.
   
   Inputs: $color (the background color of the table returned),
           $component (the large text on the right side of the table),
           $component_help
           $function (role to get colors from)
           $domain   (domian of role)
           $menulink (boolean, controls whether to include a link to /adm/menu)
   
   Returns a string containing breadcrumbs for the current page.
   
   =item clear_breadcrumbs
   
   Clears the previously stored breadcrumbs.
   
   =item add_breadcrumb
   
   Pushes a breadcrumb on the stack of crumbs.
   
   input: $breadcrumb, a hash reference.  The keys 'href','title', and 'text'
   are required.  If present the keys 'faq' and 'bug' will be used to provide
   links to the FAQ and bug sites.
   
   returns: nothing    
   
   =cut
   
   ############################################################
   ############################################################
   {
       my @Crumbs;
       
       sub breadcrumbs {
           my ($color,$component,$component_help,$function,$domain,$menulink,
       $helplink) = @_;
           if (! defined($color)) {
               if (! defined($function)) {
                   $function = &Apache::loncommon::get_users_function();
               }
               $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                       $domain);
           }
           #
           my $Str = "\n".
               '<table width="100%" border="0" cellpadding="0" cellspacing="0">'.
               '<tr><td bgcolor="'.$color.'">'.
               '<font size="-1">';
           #
           # Make the faq and bug data cascade
           my $faq = '';
           my $bug = '';
           # The last breadcrumb does not have a link, so handle it separately.
           my $last = pop(@Crumbs);
           #
           # The first one should be the course or a menu link
    if (!defined($menulink)) { $menulink=1; }
           if ($menulink) {
               my $description = 'Menu';
               if (exists($ENV{'request.course.id'}) && 
                   $ENV{'request.course.id'} ne '') {
                   $description = 
                       $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
               }
               unshift(@Crumbs,{
                       href   =>'/adm/menu',
                       title  =>'Go to main menu',
                       target =>'_top',
                       text   =>$description,
                   });
           }
           my $links .= 
               join('-&gt;',
                    map {
                        $faq = $_->{'faq'} if (exists($_->{'faq'}));
                        $bug = $_->{'bug'} if (exists($_->{'bug'}));
                        my $result = '<a href="'.$_->{'href'}.'" ';
                        if (defined($_->{'target'}) && $_->{'target'} ne '') {
                            $result .= 'target="'.$_->{'target'}.'" ';
                        }
                        $result .='title="'.&mt($_->{'title'}).'">'.
                            &mt($_->{'text'}).'</a>';
                        $result;
                        } @Crumbs
                    );
           $links .= '-&gt;' if ($links ne '');
           $links .= '<b>'.&mt($last->{'text'}).'</b>';
           #
           my $icons = '';
           $faq = $last->{'faq'} if (exists($last->{'faq'}));
           $bug = $last->{'bug'} if (exists($last->{'bug'}));
   #        if ($faq ne '') {
   #            $icons .= &Apache::loncommon::help_open_faq($faq);
   #        }
   #        if ($bug ne '') {
   #            $icons .= &Apache::loncommon::help_open_bug($bug);
   #        }
    if ($helplink ne 'nohelp') {
       $icons .= &Apache::loncommon::help_open_menu($color,$component,$component_help,$function,$faq,$bug);
    }
           if ($icons ne '') {
               $Str .= $icons.'&nbsp;';
           }
           #
           $Str .= $links.'</font></td>';
           #
           if (defined($component)) {
               $Str .= '<td align="right" bgcolor="'.$color.'">'.
                   '<font size="+1">'.&mt($component).'</font></td>';
           }
           $Str .= '</tr></table>'."\n";
           #
           # Return the @Crumbs stack to what we started with
           push(@Crumbs,$last);
           shift(@Crumbs);
           #
           return $Str;
       }
   
       sub clear_breadcrumbs {
           undef(@Crumbs);
       }
   
       sub add_breadcrumb {
           push (@Crumbs,@_);
       }
   
   } # End of scope for @Crumbs
   
   ############################################################
   ############################################################
   
   
 1;  1;
   
 __END__  __END__

Removed from v.1.19  
changed lines
  Added in v.1.90


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>