Diff for /loncom/interface/lonhelper.pm between versions 1.127 and 1.161

version 1.127, 2005/10/17 21:17:59 version 1.161, 2007/07/25 23:20:38
Line 81  State tags are also required to have an Line 81  State tags are also required to have an
 human name of the state, and will be displayed as the header on top of   human name of the state, and will be displayed as the header on top of 
 the screen for the user.  the screen for the user.
   
   State tags may also optionally have an attribute "help" which should be
   the filename of a help file, this will add a blue ? to the title.
   
 =head2 Example Helper Skeleton  =head2 Example Helper Skeleton
   
 An example of the tags so far:  An example of the tags so far:
   
  <helper title="Example Helper">   <helper title="Example Helper">
    <state name="START" title="Demonstrating the Example Helper">     <state name="START" title="Demonstrating the Example Helper">
      <!-- notice this is the START state the wizard requires -->       <!-- notice this is the START state the helper requires -->
      </state>       </state>
    <state name="GET_NAME" title="Enter Student Name">     <state name="GET_NAME" title="Enter Student Name">
      </state>       </state>
    </helper>     </helper>
   
 Of course this does nothing. In order for the wizard to do something, it is  Of course this does nothing. In order for the helper to do something, it is
 necessary to put actual elements into the wizard. Documentation for each  necessary to put actual elements into the helper. Documentation for each
 of these elements follows.  of these elements follows.
   
 =head1 Creating a Helper With Code, Not XML  =head1 Creating a Helper With Code, Not XML
   
 In some situations, such as the printing wizard (see lonprintout.pm),   In some situations, such as the printing helper (see lonprintout.pm), 
 writing the helper in XML would be too complicated, because of scope   writing the helper in XML would be too complicated, because of scope 
 issues or the fact that the code actually outweighs the XML. It is  issues or the fact that the code actually outweighs the XML. It is
 possible to create a helper via code, though it is a little odd.  possible to create a helper via code, though it is a little odd.
Line 183  use Apache::File; Line 186  use Apache::File;
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   use Apache::longroup;
   use Apache::lonselstudent;
   use LONCAPA;
   
 # Register all the tags with the helper, so the helper can   # Register all the tags with the helper, so the helper can 
 # push and pop them  # push and pop them
Line 331  sub start_state { Line 337  sub start_state {
     }      }
   
     Apache::lonhelper::state->new($token->[2]{'name'},      Apache::lonhelper::state->new($token->[2]{'name'},
                                   $token->[2]{'title'});                                    $token->[2]{'title'},
     $token->[2]{'help'});
     return '';      return '';
 }  }
   
Line 361  use Apache::loncommon; Line 368  use Apache::loncommon;
 use Apache::File;  use Apache::File;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   use LONCAPA;
   
 sub new {  sub new {
     my $proto = shift;      my $proto = shift;
Line 466  sub _saveVars { Line 474  sub _saveVars {
 sub _varsInFile {  sub _varsInFile {
     my $self = shift;      my $self = shift;
     my @vars = ();      my @vars = ();
     for my $key (keys %{$self->{VARS}}) {      for my $key (keys(%{$self->{VARS}})) {
         push @vars, &Apache::lonnet::escape($key) . '=' .          push(@vars, &escape($key) . '=' . &escape($self->{VARS}->{$key}));
             &Apache::lonnet::escape($self->{VARS}->{$key});  
     }      }
     return join ('&', @vars);      return join ('&', @vars);
 }  }
Line 483  sub declareVar { Line 490  sub declareVar {
         $self->{VARS}->{$var} = '';          $self->{VARS}->{$var} = '';
     }      }
   
     my $envname = 'form.' . $var . '.forminput';      my $envname = 'form.' . $var . '_forminput';
     if (defined($env{$envname})) {      if (defined($env{$envname})) {
         if (ref($env{$envname})) {          if (ref($env{$envname})) {
             $self->{VARS}->{$var} = join('|||', @{$env{$envname}});              $self->{VARS}->{$var} = join('|||', @{$env{$envname}});
Line 573  sub display { Line 580  sub display {
     }      }
   
     # Phase 4: Display.      # Phase 4: Display.
     my $html=&Apache::lonxml::xmlbegin();  
     my $stateTitle=&mt($state->title());      my $stateTitle=&mt($state->title());
     my $helperTitle = &mt($self->{TITLE});      my $stateHelp=     $state->help();
     my $bodytag = &Apache::loncommon::bodytag($helperTitle,'','');      my $browser_searcher_js = 
    '<script type="text/javascript">'."\n".
    &Apache::loncommon::browser_and_searcher_javascript().
    "\n".'</script>';
   
       $result .= &Apache::loncommon::start_page($self->{TITLE},
         $browser_searcher_js);
       
     my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"');      my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"');
     my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"');      my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"');
     # FIXME: This should be parameterized, not concatenated - Jeremy      # FIXME: This should be parameterized, not concatenated - Jeremy
     my $loncapaHelper = &mt("LON-CAPA Helper:");  
   
     $result .= <<HEADER;  
 $html  
     <head>  
         <title>$loncapaHelper: $helperTitle</title>  
     </head>  
     $bodytag  
 HEADER  
     if (!$state->overrideForm()) { $result.="<form name='helpform' method='POST'>"; }      if (!$state->overrideForm()) { $result.="<form name='helpform' method='POST'>"; }
       if ($stateHelp) {
    $stateHelp = &Apache::loncommon::help_open_topic($stateHelp);
       }
     $result .= <<HEADER;      $result .= <<HEADER;
         <table border="0" width='100%'><tr><td>          <table border="0" width='100%'><tr><td>
         <h2><i>$stateTitle</i></h2>          <h2><i>$stateTitle</i>$stateHelp</h2>
 HEADER  HEADER
   
     $result .= "<table cellpadding='10' width='100%'><tr><td rowspan='2' valign='top'>";      $result .= "<table cellpadding='10' width='100%'><tr><td rowspan='2' valign='top'>";
Line 651  HEADER Line 660  HEADER
             </tr>              </tr>
           </table>            </table>
         </form>          </form>
     </body>  
 </html>  
 FOOTER  FOOTER
   
       $result .= &Apache::loncommon::end_page();
     # Handle writing out the vars to the file      # Handle writing out the vars to the file
     my $file = Apache::File->new('>'.$self->{FILENAME});      my $file = Apache::File->new('>'.$self->{FILENAME});
     print $file $self->_varsInFile();      print $file $self->_varsInFile();
Line 680  sub new { Line 688  sub new {
   
     $self->{NAME} = shift;      $self->{NAME} = shift;
     $self->{TITLE} = shift;      $self->{TITLE} = shift;
       $self->{HELP} = shift;
     $self->{ELEMENTS} = [];      $self->{ELEMENTS} = [];
   
     bless($self, $class);      bless($self, $class);
Line 701  sub title { Line 710  sub title {
     return $self->{TITLE};      return $self->{TITLE};
 }  }
   
   sub help {
       my $self = shift;
       return $self->{HELP};
   }
   
 sub preprocess {  sub preprocess {
     my $self = shift;      my $self = shift;
     for my $element (@{$self->{ELEMENTS}}) {      for my $element (@{$self->{ELEMENTS}}) {
Line 792  the element. How this value is interpret Line 806  the element. How this value is interpret
 the element itself, and possibly the settings the element has (such as   the element itself, and possibly the settings the element has (such as 
 multichoice vs. single choice for <choices> tags).   multichoice vs. single choice for <choices> tags). 
   
 This is also intended for things like the course initialization wizard, where the  This is also intended for things like the course initialization helper, where the
 user is setting various parameters. By correctly grabbing current settings   user is setting various parameters. By correctly grabbing current settings 
 and including them into the helper, it allows the user to come back to the  and including them into the helper, it allows the user to come back to the
 helper later and re-execute it, without needing to worry about overwriting  helper later and re-execute it, without needing to worry about overwriting
Line 1010  sub end_message { Line 1024  sub end_message {
 sub render {  sub render {
     my $self = shift;      my $self = shift;
   
     return &mtn($self->{MESSAGE_TEXT});      return $self->{MESSAGE_TEXT};
 }  }
 # If a NEXTSTATE was given, switch to it  # If a NEXTSTATE was given, switch to it
 sub postprocess {  sub postprocess {
Line 1023  sub postprocess { Line 1037  sub postprocess {
 }  }
 1;  1;
   
   package Apache::lonhelper::helpicon;
   
   =pod
   
   =head1 Elements
   
   =head2 Element: helpiconX<helpicon, helper element>
   
   Helpicon elements add a help icon at the current location.
   Example:
   
      <helpicon file="Help">
        General Help
      </helpicon>
   
   In this example will generate a help icon to the Help.hlp url with a
   description of 'General Help'. The description is not required and if
   left out (Example: <helpicon file="Help" /> only the icon will be
   added.)
   
   =head3 Localization
   
   The description text will be run through the normalize_string function
   and that will be used as a call to &mt.
   
   =cut
   
   no strict;
   @ISA = ("Apache::lonhelper::element");
   use strict;
   use Apache::lonlocal;
   
   BEGIN {
       &Apache::lonhelper::register('Apache::lonhelper::helpicon',
    ('helpicon'));
   }
   
   sub new {
       my $ref = Apache::lonhelper::element->new();
       bless($ref);
   }
   
   # CONSTRUCTION: Construct the message element from the XML
   sub start_helpicon {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
       if ($target ne 'helper') {
           return '';
       }
   
       $paramHash->{HELP_TEXT} = &mtn(&Apache::lonxml::get_all_text('/helpicon',
    $parser));
   
       $paramHash->{HELP_TEXT} =~s/^\s+//;
       $paramHash->{HELP_TEXT} =~s/\s+$//;
   
       if (defined($token->[2]{'file'})) {
           $paramHash->{HELP_FILE} = $token->[2]{'file'};
       }
       return '';
   }
   
   sub end_helpicon {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
       if ($target ne 'helper') {
           return '';
       }
       Apache::lonhelper::helpicon->new();
       return '';
   }
   
   sub render {
       my $self = shift;
   
       my $text;
       if ( $self->{HELP_TEXT} ne '') {
    $text=&mtn($self->{HELP_TEXT});
       }
   
       return &Apache::loncommon::help_open_topic($self->{HELP_FILE},
          $text);
   }
   sub postprocess {
       my $self = shift;
       if (defined($self->{NEXTSTATE})) {
           $helper->changeState($self->{NEXTSTATE});
       }
   
       return 1;
   }
   
   1;
   
   package Apache::lonhelper::skip;
   
   =pod
   
   =head1 Elements
   
   =head2 Element: skipX<skip>
   
   The <skip> tag allows you define conditions under which the current state 
   should be skipped over and define what state to skip to.
   
     <state name="SKIP">
       <skip>
          <clause>
            #some code that decides whether to skip the state or not
          </clause>
          <nextstate>FINISH</nextstate>
       </skip>
       <message nextstate="FINISH">A possibly skipped state</message>
     </state>
   
   =cut
   
   no strict;
   @ISA = ("Apache::lonhelper::element");
   use strict;
   
   BEGIN {
       &Apache::lonhelper::register('Apache::lonhelper::skip',
    ('skip'));
   }
   
   sub new {
       my $ref = Apache::lonhelper::element->new();
       bless($ref);
   }
   
   sub start_skip {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
       if ($target ne 'helper') {
           return '';
       }
       # let <cluase> know what text to skip to
       $paramHash->{SKIPTAG}='/skip';
       return '';
   }
   
   sub end_skip {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
       if ($target ne 'helper') {
           return '';
       }
       Apache::lonhelper::skip->new();
       return '';
   }
   
   sub render {
       my $self = shift;
       return '';
   }
   # If a NEXTSTATE is set, switch to it
   sub preprocess {
       my ($self) = @_;
   
       if (defined($self->{NEXTSTATE})) {
           $helper->changeState($self->{NEXTSTATE});
       }
   
       return 1;
   }
   
   1;
   
 package Apache::lonhelper::choices;  package Apache::lonhelper::choices;
   
 =pod  =pod
Line 1072  will be the state transistioned to if th Line 1255  will be the state transistioned to if th
 the choice is not multichoice. This will override the nextstate  the choice is not multichoice. This will override the nextstate
 passed to the parent C<choices> tag.  passed to the parent C<choices> tag.
   
   <choice> may optionally contain a 'relatedvalue' attribute, which
   if present will cause a text entry to appear to the right of the
   selection.  The value of the relatedvalue attribute is a variable
   into which the text entry will be stored e.g.:
   <choice computer='numberprovided" relatedvalue="num">Type the number in:</choice>
   
   <choice> may contain a relatededefault atribute which, if the
   relatedvalue attribute is present will be the initial value of the input
   box.
   
 =back  =back
   
 To create the choices programmatically, either wrap the choices in   To create the choices programmatically, either wrap the choices in 
Line 1162  sub start_choice { Line 1355  sub start_choice {
     my $computer = $token->[2]{'computer'};      my $computer = $token->[2]{'computer'};
     my $human = &mt(&Apache::lonxml::get_all_text('/choice',      my $human = &mt(&Apache::lonxml::get_all_text('/choice',
                                               $parser));                                                $parser));
     my $nextstate = $token->[2]{'nextstate'};      my $nextstate  = $token->[2]{'nextstate'};
     my $evalFlag = $token->[2]{'eval'};      my $evalFlag   = $token->[2]{'eval'};
       my $relatedVar = $token->[2]{'relatedvalue'}; 
       my $relatedDefault = $token->[2]{'relateddefault'};
     push @{$paramHash->{CHOICES}}, [&mtn($human), $computer, $nextstate,       push @{$paramHash->{CHOICES}}, [&mtn($human), $computer, $nextstate, 
                                     $evalFlag];                                      $evalFlag, $relatedVar, $relatedDefault];
     return '';      return '';
 }  }
   
Line 1193  sub render { Line 1388  sub render {
     function checkall(value, checkName) {      function checkall(value, checkName) {
  for (i=0; i<document.forms.helpform.elements.length; i++) {   for (i=0; i<document.forms.helpform.elements.length; i++) {
             ele = document.forms.helpform.elements[i];              ele = document.forms.helpform.elements[i];
             if (ele.name == checkName + '.forminput') {              if (ele.name == checkName + '_forminput') {
                 document.forms.helpform.elements[i].checked=value;                  document.forms.helpform.elements[i].checked=value;
             }              }
         }          }
Line 1266  BUTTONS Line 1461  BUTTONS
     foreach my $choice (@{$self->{CHOICES}}) {      foreach my $choice (@{$self->{CHOICES}}) {
         my $id = &new_id();          my $id = &new_id();
         $result .= "<tr>\n<td width='20'>&nbsp;</td>\n";          $result .= "<tr>\n<td width='20'>&nbsp;</td>\n";
         $result .= "<td valign='top'><input type='$type' name='$var.forminput'"          $result .= "<td valign='top'><input type='$type' name='${var}_forminput'"
             . " value='" .               . " value='" . 
             HTML::Entities::encode($choice->[1],"<>&\"'")               HTML::Entities::encode($choice->[1],"<>&\"'") 
             . "'";              . "'";
Line 1275  BUTTONS Line 1470  BUTTONS
         }          }
         $result .= qq{id="id$id"};          $result .= qq{id="id$id"};
         my $choiceLabel = $choice->[0];          my $choiceLabel = $choice->[0];
         if ($choice->[4]) {  # if we need to evaluate this choice          if ($choice->[3]) {  # if we need to evaluate this choice
             $choiceLabel = "sub { my $helper = shift; my $state = shift;" .              $choiceLabel = "sub { my $helper = shift; my $state = shift;" .
                 $choiceLabel . "}";                  $choiceLabel . "}";
             $choiceLabel = eval($choiceLabel);              $choiceLabel = eval($choiceLabel);
             $choiceLabel = &$choiceLabel($helper, $self);              $choiceLabel = &$choiceLabel($helper, $self);
         }          }
         $result .= "/></td><td> ".qq{<label for="id$id">}.          $result .= "/></td><td> ".qq{<label for="id$id">}.
             $choiceLabel. "</label></td></tr>\n";              &mtn($choiceLabel). "</label></td>";
    if ($choice->[4]) {
       $result .='<td><input type="text" size="5" name="'
    .$choice->[4].'_forminput" value="'
                   .$choice->[5].'" /></td>';
    }
    $result .= "</tr>\n";
     }      }
     $result .= "</table>\n\n\n";      $result .= "</table>\n\n\n";
     $result .= $buttons;      $result .= $buttons;
Line 1294  BUTTONS Line 1495  BUTTONS
 # given, switch to it  # given, switch to it
 sub postprocess {  sub postprocess {
     my $self = shift;      my $self = shift;
     my $chosenValue = $env{'form.' . $self->{'variable'} . '.forminput'};      my $chosenValue = $env{'form.' . $self->{'variable'} . '_forminput'};
   
     if (!defined($chosenValue) && !$self->{'allowempty'}) {      if (!defined($chosenValue) && !$self->{'allowempty'}) {
         $self->{ERROR_MSG} =           $self->{ERROR_MSG} = 
Line 1316  sub postprocess { Line 1517  sub postprocess {
                 $helper->changeState($choice->[2]);                  $helper->changeState($choice->[2]);
             }              }
         }          }
    if ($choice->[4]) {
       my $varname = $choice->[4];
       $helper->{'VARS'}->{$varname} = $env{'form.'."${varname}_forminput"};
    }
     }      }
     return 1;      return 1;
 }  }
Line 1423  sub render { Line 1628  sub render {
  $checkedChoices{$self->{CHOICES}->[0]->[1]} = 1;   $checkedChoices{$self->{CHOICES}->[0]->[1]} = 1;
     }      }
   
     $result .= "<select name='${var}.forminput'>\n";      $result .= "<select name='${var}_forminput'>\n";
     foreach my $choice (@{$self->{CHOICES}}) {      foreach my $choice (@{$self->{CHOICES}}) {
         $result .= "<option value='" .           $result .= "<option value='" . 
             HTML::Entities::encode($choice->[1],"<>&\"'")               HTML::Entities::encode($choice->[1],"<>&\"'") 
Line 1449  sub render { Line 1654  sub render {
 # given, switch to it  # given, switch to it
 sub postprocess {  sub postprocess {
     my $self = shift;      my $self = shift;
     my $chosenValue = $env{'form.' . $self->{'variable'} . '.forminput'};      my $chosenValue = $env{'form.' . $self->{'variable'} . '_forminput'};
   
     if (!defined($chosenValue) && !$self->{'allowempty'}) {      if (!defined($chosenValue) && !$self->{'allowempty'}) {
         $self->{ERROR_MSG} = "You must choose one or more choices to" .          $self->{ERROR_MSG} = "You must choose one or more choices to" .
Line 1559  sub render { Line 1764  sub render {
     my $time=time;      my $time=time;
     my ($anytime,$onclick);      my ($anytime,$onclick);
   
     if (defined($self->{DEFAULT_VALUE})) {  
       # first check VARS for a valid new value from the user
       # then check DEFAULT_VALUE for a valid default time value
       # otherwise pick now as reasonably good time
   
       if (defined($helper->{VARS}{$var})
    &&  $helper->{VARS}{$var} > 0) {
    $date = localtime($helper->{VARS}{$var});
       } elsif (defined($self->{DEFAULT_VALUE})) {
         my $valueFunc = eval($self->{DEFAULT_VALUE});          my $valueFunc = eval($self->{DEFAULT_VALUE});
         die('Error in default value code for variable ' .           die('Error in default value code for variable ' . 
             $self->{'variable'} . ', Perl said: ' . $@) if $@;              $self->{'variable'} . ', Perl said: ' . $@) if $@;
         $time = &$valueFunc($helper, $self);          $time = &$valueFunc($helper, $self);
  if (lc($time) eq 'anytime') { $time=time; $anytime=1; }   if (lc($time) eq 'anytime') {
       $anytime=1;
       $date = localtime(time);
       $date->min(0);
    } elsif (defined($time) && $time ne 0) {
       $date = localtime($time);
    } else {
       # leave date undefined so it'll default to now
    }
     }      }
   
       if (!defined($date)) {
    $date = localtime(time);
    $date->min(0);
       }
   
     if ($anytime) {      if ($anytime) {
  $onclick = "onclick=\"javascript:updateCheck(this.form,'${var}anytime',false)\"";   $onclick = "onclick=\"javascript:updateCheck(this.form,'${var}anytime',false)\"";
     }      }
     # Default date: The current hour.      # Default date: The current hour.
     $date = localtime($time);  
     $date->min(0);  
   
     if (defined $self->{ERROR_MSG}) {      if (defined $self->{ERROR_MSG}) {
         $result .= '<font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br /><br />';          $result .= '<font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br /><br />';
Line 1675  CHECK Line 1900  CHECK
  if ($anytime) {   if ($anytime) {
     $result.=' checked="checked" '      $result.=' checked="checked" '
  }   }
  $result.="name='${var}anytime'/>".&mt('Anytime').'</label>'   $result.="name='${var}anytime'/>".&mt('Any time').'</label>'
     }      }
     return $result;      return $result;
   
Line 1722  sub postprocess { Line 1947  sub postprocess {
  $helper->{VARS}->{$var} = $chosenDate;   $helper->{VARS}->{$var} = $chosenDate;
     }      }
   
       if (defined($self->{VALIDATOR})) {
    my $validator = eval($self->{VALIDATOR});
    die 'Died during evaluation of validator code; Perl said: ' . $@ if $@;
    my $invalid = &$validator($helper, $state, $self, $self->getValue());
    if ($invalid) {
       $self->{ERROR_MSG} = $invalid;
       return 0;
    }
       }
   
     if (defined($self->{NEXTSTATE})) {      if (defined($self->{NEXTSTATE})) {
         $helper->changeState($self->{NEXTSTATE});          $helper->changeState($self->{NEXTSTATE});
     }      }
Line 1972  sub render { Line 2207  sub render {
     function checkall(value, checkName) {      function checkall(value, checkName) {
  for (i=0; i<document.forms.helpform.elements.length; i++) {   for (i=0; i<document.forms.helpform.elements.length; i++) {
             ele = document.forms.helpform.elements[i];              ele = document.forms.helpform.elements[i];
             if (ele.name == checkName + '.forminput') {              if (ele.name == checkName + '_forminput') {
                 document.forms.helpform.elements[i].checked=value;                  document.forms.helpform.elements[i].checked=value;
             }              }
         }          }
Line 2071  BUTTONS Line 2306  BUTTONS
     }      }
     $col .=       $col .= 
                         "<td align='center'><input type='checkbox' name ='$option_var".                          "<td align='center'><input type='checkbox' name ='$option_var".
  ".forminput' value='".   "_forminput' value='".
  $resource_name . "' $checked /> </td>";   $resource_name . "' $checked /> </td>";
  }   }
     }      }
   
             $col .= "<td align='center'><input type='$inputType' name='${var}.forminput' ";              $col .= "<td align='center'><input type='$inputType' name='${var}_forminput' ";
     if (%defaultSymbs) {      if (%defaultSymbs) {
  my $symb=$resource->symb();   my $symb=$resource->symb();
  if (exists($defaultSymbs{$symb})) {   if (exists($defaultSymbs{$symb})) {
Line 2105  BUTTONS Line 2340  BUTTONS
  my $resource_name =      my $resource_name =   
     &HTML::Entities::encode(&$valueFunc($resource),"<>&\"'");      &HTML::Entities::encode(&$valueFunc($resource),"<>&\"'");
  if ($addparts && (scalar(@{$resource->parts}) > 1)) {   if ($addparts && (scalar(@{$resource->parts}) > 1)) {
     $col .= "<select onclick=\"javascript:updateRadio(this.form,'${var}.forminput','$resource_name');updateHidden(this.form,'$id','${var}');\" name='part_$id.forminput'>\n";      $col .= "<select onclick=\"javascript:updateRadio(this.form,'${var}_forminput','$resource_name');updateHidden(this.form,'$id','${var}');\" name='part_${id}_forminput'>\n";
     $col .= "<option value=\"$part\">All Parts</option>\n";      $col .= "<option value=\"$part\">All Parts</option>\n";
     foreach my $part (@{$resource->parts}) {      foreach my $part (@{$resource->parts}) {
  $col .= "<option value=\"$part\">Part: $part</option>\n";   $col .= "<option value=\"$part\">Part: $part</option>\n";
Line 2127  BUTTONS Line 2362  BUTTONS
  }   }
     }      }
     function updateHidden(form,id,name) {      function updateHidden(form,id,name) {
  var select=form['part_'+id+'.forminput'];   var select=form['part_'+id+'_forminput'];
  var hidden=form[name+'_part.forminput'];   var hidden=form[name+'_part_forminput'];
  var which=select.selectedIndex;   var which=select.selectedIndex;
  hidden.value=select.options[which].value;   hidden.value=select.options[which].value;
     }      }
 // -->  // -->
 </script>  </script>
 <input type="hidden" name="${var}_part.forminput" />  <input type="hidden" name="${var}_part_forminput" />
   
 RADIO  RADIO
     $env{'form.condition'} = !$self->{'toponly'};      $env{'form.condition'} = !$self->{'toponly'};
Line 2267  sub render { Line 2502  sub render {
     my $buttons = '';      my $buttons = '';
     my $var = $self->{'variable'};      my $var = $self->{'variable'};
   
     if ($self->{'multichoice'}) {  
         $result = <<SCRIPT;  
 <script type="text/javascript">  
 // <!--  
     function checkall(value, checkName) {  
  for (i=0; i<document.forms.helpform.elements.length; i++) {  
             ele = document.forms.helpform.elements[i];  
             if (ele.name == checkName + '.forminput') {  
                 document.forms.helpform.elements[i].checked=value;  
             }  
         }  
     }  
     function checksec(value) {  
  for (i=0; i<document.forms.helpform.elements.length; i++) {  
     comp = document.forms.helpform.elements.chksec.value;  
             if (document.forms.helpform.elements[i].value.indexOf(':'+comp+':') != -1) {  
  if (document.forms.helpform.elements[i].value.indexOf(':Active') != -1) {  
     document.forms.helpform.elements[i].checked=value;  
  }  
             }  
         }  
     }  
     function checkactive() {  
  for (i=0; i<document.forms.helpform.elements.length; i++) {  
             if (document.forms.helpform.elements[i].value.indexOf(':Active') != -1) {  
                 document.forms.helpform.elements[i].checked=true;  
             }   
         }  
     }  
     function uncheckexpired() {  
  for (i=0; i<document.forms.helpform.elements.length; i++) {  
             if (document.forms.helpform.elements[i].value.indexOf(':Expired') != -1) {  
                 document.forms.helpform.elements[i].checked=false;  
             }   
         }  
     }  
     function getDesiredState() {     // Return desired person state radio value.  
         numRadio = document.forms.helpform.personstate.length;  
         for (i =0; i < numRadio; i++) {  
     if (document.forms.helpform.personstate[i].checked) {  
                 return document.forms.helpform.personstate[i].value;  
             }  
         }  
         return "";  
     }  
   
     function checksections(value) {    // Check selected sections.  
         numSections  = document.forms.helpform.chosensections.length;  
  desiredState = getDesiredState();  
   
  for (var option = 0; option < numSections; option++) {  
     if(document.forms.helpform.chosensections.options[option].selected) {  
  section = document.forms.helpform.chosensections.options[option].text;  
  if (section == "none") {  
     section ="";  
  }  
  for (i = 0; i < document.forms.helpform.elements.length; i++ ) {  
     if (document.forms.helpform.elements[i].value.indexOf(':') != -1) {  
  info = document.forms.helpform.elements[i].value.split(':');  
  hisSection = info[2];  
  hisState   = info[4];  
  if (desiredState == hisState ||  
     desiredState == "All") {  
     if(hisSection == section ||  
        section =="" ) {  
  document.forms.helpform.elements[i].checked = value;  
     }  
  }  
     }  
  }  
             }  
  }  
    }  
 // -->  
 </script>  
 SCRIPT  
   
         my %lt=&Apache::lonlocal::texthash(  
                     'ocs'  => "Select Only Current Students",  
                     'ues'  => "Unselect Expired Students",  
                     'sas'  => "Select All Students",  
                     'uas'  => "Unselect All Students",  
                     'sfsg' => "Select Current Students for Section/Group",  
     'ufsg' => "Unselect for Section/Group");  
    
         $buttons = <<BUTTONS;  
 <br />  
 <table>  
     
   <tr>  
      <td><input type="button" onclick="checkall(true, '$var')" value="$lt{'sas'}" /></td>  
      <td> <input type="button" onclick="checkall(false, '$var')" value="$lt{'uas'}" /><br /></td>  
   </tr>  
     
 </table>  
 <br />  
 BUTTONS  
     }  
   
     if (defined $self->{ERROR_MSG}) {      if (defined $self->{ERROR_MSG}) {
         $result .= '<font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br /><br />';          $result .= '<font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br /><br />';
Line 2382  BUTTONS Line 2519  BUTTONS
  %defaultUsers = map { if ($_) {($_,1) } } @defaultUsers;   %defaultUsers = map { if ($_) {($_,1) } } @defaultUsers;
  delete($defaultUsers{''});   delete($defaultUsers{''});
     }      }
     my $choices = [];  
   
       my ($course_personnel, 
    $current_members, 
    $expired_members, 
    $future_members) = 
       &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});
   
   
   
     # Load up the non-students, if necessary      # Load up the non-students, if necessary
   
     if ($self->{'coursepersonnel'}) {      if ($self->{'coursepersonnel'}) {
  my %coursepersonnel = Apache::lonnet::get_course_adv_roles();   unshift @$current_members, (@$course_personnel);
  for (sort keys %coursepersonnel) {  
     for my $role (split /,/, $coursepersonnel{$_}) {  
  # extract the names so we can sort them  
  my @people;  
   
  for (split /,/, $role) {  
     push @people, [split /:/, $role];  
  }  
   
  @people = sort { $a->[0] cmp $b->[0] } @people;  
   
  for my $person (@people) {  
     push @$choices, [join(':', @$person), $person->[0], '', $_];  
  }  
     }  
  }  
     }      }
   
     # Constants  
     my $section = Apache::loncoursedata::CL_SECTION();  
     my $fullname = Apache::loncoursedata::CL_FULLNAME();  
     my $status = Apache::loncoursedata::CL_STATUS();  
   
     # Load up the students      #   Current personel
     my $classlist = &Apache::loncoursedata::get_classlist();  
     my @keys = keys %{$classlist};  
     # Sort by: Section, name  
     @keys = sort {  
         if ($classlist->{$a}->[$section] ne $classlist->{$b}->[$section]) {  
             return $classlist->{$a}->[$section] cmp $classlist->{$b}->[$section];  
         }  
         return $classlist->{$a}->[$fullname] cmp $classlist->{$b}->[$fullname];  
     } @keys;  
   
     # username, fullname, section, type  
     for (@keys) {  
  # Filter out inactive students if we've set "activeonly"  
  if (!$self->{'activeonly'} || $classlist->{$_}->[$status] eq  
     'Active') {  
     push @$choices, [$_, $classlist->{$_}->[$fullname],   
      $classlist->{$_}->[$section],  
      $classlist->{$_}->[$status], 'Student'];  
  }  
     }  
   
     my $name = $self->{'coursepersonnel'} ? &mt('Name') : &mt('Student Name');      $result .= '<h4>'.&mt('Select Currently Enrolled Students and Active Course Personnel').'</h4>';
     my $type = 'radio';      $result .= &Apache::lonselstudent::render_student_list( $current_members,
     if ($self->{'multichoice'}) { $type = 'checkbox'; }      "helpform",
     $result .= "<table cellspacing='2' cellpadding='2' border='0'>\n";      "current", 
     $result .= "<tr><td></td><td align='center'><b>$name</b></td>".      \%defaultUsers,
         "<td align='center'><b>" . &mt('Section') . "</b></td>" .       $self->{'multichoice'},
  "<td align='center'><b>".&mt('Status')."</b></td>" .       $self->{'variable'},
  "<td align='center'><b>" . &mt("Role") . "</b></td>" .      1);
  "<td align='center'><b>".&mt('Username').":".&mt('Domain')."</b></td></tr>";  
   
     my $checked = 0;  
     for my $choice (@$choices) {  
         $result .= "<tr><td><input type='$type' name='" .  
             $self->{'variable'} . '.forminput' . "'";  
               
  if (%defaultUsers) {  
     my $user=$choice->[0];  
     if (exists($defaultUsers{$user})) {  
  $result .= " checked='checked' ";  
  $checked = 1;  
     }  
  } elsif (!$self->{'multichoice'} && !$checked) {  
             $result .= " checked='checked' ";  
             $checked = 1;  
         }  
         $result .=  
             " value='" . HTML::Entities::encode($choice->[0] . ':'   
  .$choice->[2] . ':'   
  .$choice->[1] . ':'   
  .$choice->[3], "<>&\"'")  
             . "' /></td><td>"  
             . HTML::Entities::encode($choice->[1],'<>&"')  
             . "</td><td align='center'>"   
             . HTML::Entities::encode($choice->[2],'<>&"')  
             . "</td>\n<td>"   
     . HTML::Entities::encode($choice->[3],'<>&"')  
             . "</td>\n<td>"   
     . HTML::Entities::encode($choice->[4],'<>&"')  
             . "</td>\n<td>"   
     . HTML::Entities::encode($choice->[0],'<>&"')  
     . "</td></tr>\n";  
     }  
   
     $result .= "</table>\n\n";      # If activeonly is not set then we can also give the expired students:
     $result .= $buttons;     
     #      #
     #  now add the fancy section choice... first enumerate the sections:      if (!$self->{'activeonly'} && ((scalar(@$future_members)) > 0)) {
     if ($self->{'multichoice'}) {  
  my %sections;   # And future.
  for my $key (@keys) {  
     my $section_name = $classlist->{$key}->[$section];   $result .= '<h4>'.&mt('Select Future Enrolled Students and Future Course Personnel').'</h4>';
     if ($section_name ne "") {         
  $sections{$section_name} = 1;   $result .= &Apache::lonselstudent::render_student_list( $future_members,
     }   "helpform",
  }   "future",
  #  The variable $choice_widget will have the html to make the choice    \%defaultUsers,
  #  selector.   $self->{'multichoice'},
  my $size=5;   $self->{'variable'},
  if (scalar(keys(%sections)) < 5) {   0);
     $size=scalar(keys(%sections));      }
  }      if (!$self->{'activeonly'} && ((scalar(@$expired_members)) > 0)) {
  my $choice_widget = '<select multiple name="chosensections" size="'.$size.'">'."\n";   # Past 
  foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {  
     $choice_widget .= "<option name=\"$sec\">$sec</option>\n";   $result .= '<h4>'.&mt('Select Previously Enrolled Students and Inactive Course Personnel').'</h4>';
  }   $result .= &Apache::lonselstudent::render_student_list($expired_members,
  $choice_widget .= "<option>none</option></select>\n";         "helpform",
          "past",
  # Build a table without any borders to contain the section based         \%defaultUsers,
  # selection:         $self->{'multichoice'},
          $self->{'variable'},
  my $section_selectors =<<SECTIONSELECT;         0);
 <table border="0">  
   <tr valign="top">  
    <td>For Sections:</td><td>$choice_widget</td>  
    <td><label><input type="radio" name="personstate" value="Active" checked />  
                Current Students</label></td>  
    <td><label><input type="radio" name="personstate" value="All" />  
                All students</label></td>  
    <td><label><input type="radio" name="personstate" value="Expired" />  
                Expired Students</label></td>  
   </tr>  
   <tr>  
    <td><input type="button" value="Select" onclick="checksections(true);" /></td>  
    <td><input type="button" value="Unselect" onclick="checksections(false);" /></td></tr>  
 </table>  
 <br />  
 SECTIONSELECT  
          $result .= $section_selectors;  
     }      }
   
   
   
     return $result;      return $result;
 }  }
   
 sub postprocess {  sub postprocess {
     my $self = shift;      my $self = shift;
   
     my $result = $env{'form.' . $self->{'variable'} . '.forminput'};      my $result = $env{'form.' . $self->{'variable'} . '_forminput'};
     if (!$result && !$self->{'emptyallowed'}) {      if (!$result && !$self->{'emptyallowed'}) {
  if ($self->{'coursepersonnel'}) {   if ($self->{'coursepersonnel'}) {
     $self->{ERROR_MSG} =       $self->{ERROR_MSG} = 
Line 2712  sub render { Line 2770  sub render {
     function checkall(value, checkName) {      function checkall(value, checkName) {
  for (i=0; i<document.forms.helpform.elements.length; i++) {   for (i=0; i<document.forms.helpform.elements.length; i++) {
             ele = document.forms.helpform.elements[i];              ele = document.forms.helpform.elements[i];
             if (ele.name == checkName + '.forminput') {              if (ele.name == checkName + '_forminput') {
                 document.forms.helpform.elements[i].checked=value;                  document.forms.helpform.elements[i].checked=value;
             }              }
         }          }
Line 2829  BUTTONS Line 2887  BUTTONS
             my $id = &new_id();              my $id = &new_id();
             $result .= '<tr><td align="right"' . " bgcolor='$color'>" .              $result .= '<tr><td align="right"' . " bgcolor='$color'>" .
                 "<input $onclick type='$type' name='" . $var                  "<input $onclick type='$type' name='" . $var
             . ".forminput' ".qq{id="$id"}." value='" . HTML::Entities::encode($fileName,"<>&\"'").              . "_forminput' ".qq{id="$id"}." value='" . HTML::Entities::encode($fileName,"<>&\"'").
                 "'";                  "'";
             if (!$self->{'multichoice'} && $choices == 0) {              if (!$self->{'multichoice'} && $choices == 0) {
                 $result .= ' checked="checked"';                  $result .= ' checked="checked"';
Line 2890  sub fileState { Line 2948  sub fileState {
   
 sub postprocess {  sub postprocess {
     my $self = shift;      my $self = shift;
     my $result = $env{'form.' . $self->{'variable'} . '.forminput'};      my $result = $env{'form.' . $self->{'variable'} . '_forminput'};
     if (!$result) {      if (!$result) {
         $self->{ERROR_MSG} = 'You must choose at least one file '.          $self->{ERROR_MSG} = 'You must choose at least one file '.
             'to continue.';              'to continue.';
Line 2915  package Apache::lonhelper::section; Line 2973  package Apache::lonhelper::section;
 <section> allows the user to choose one or more sections from the current  <section> allows the user to choose one or more sections from the current
 course.  course.
   
 It takes the standard attributes "variable", "multichoice", and  It takes the standard attributes "variable", "multichoice",
 "nextstate", meaning what they do for most other elements.  "allowempty" and "nextstate", meaning what they do for most other
   elements.
   
   also takes a boolean 'onlysections' whcih will restrict this to only
   have sections and not include groups
   
 =cut  =cut
   
Line 2946  sub start_section { Line 3008  sub start_section {
     $paramHash->{'variable'} = $token->[2]{'variable'};      $paramHash->{'variable'} = $token->[2]{'variable'};
     $helper->declareVar($paramHash->{'variable'});      $helper->declareVar($paramHash->{'variable'});
     $paramHash->{'multichoice'} = $token->[2]{'multichoice'};      $paramHash->{'multichoice'} = $token->[2]{'multichoice'};
       $paramHash->{'allowempty'} = $token->[2]{'allowempty'};
     if (defined($token->[2]{'nextstate'})) {      if (defined($token->[2]{'nextstate'})) {
         $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};          $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};
     }      }
Line 2955  sub start_section { Line 3018  sub start_section {
   
     my $section = Apache::loncoursedata::CL_SECTION();      my $section = Apache::loncoursedata::CL_SECTION();
     my $classlist = Apache::loncoursedata::get_classlist();      my $classlist = Apache::loncoursedata::get_classlist();
     foreach (keys %$classlist) {      foreach my $user (keys(%$classlist)) {
         my $sectionName = $classlist->{$_}->[$section];          my $section_name = $classlist->{$user}[$section];
         if (!$sectionName) {          if (!$section_name) {
             $choices{"No section assigned"} = "";              $choices{"No section assigned"} = "";
         } else {          } else {
             $choices{$sectionName} = $sectionName;              $choices{$section_name} = $section_name;
         }          }
     }       } 
         
     for my $sectionName (sort(keys(%choices))) {      if (exists($choices{"No section assigned"})) {
            push(@{$paramHash->{CHOICES}}, 
         push @{$paramHash->{CHOICES}}, [$sectionName, $sectionName];       ['No section assigned','No section assigned']);
    delete($choices{"No section assigned"});
       }
       for my $section_name (sort {lc($a) cmp lc($b) } (keys(%choices))) {
    push @{$paramHash->{CHOICES}}, [$section_name, $section_name];
       }
       return if ($token->[2]{'onlysections'});
   
       # add in groups to the end of the list
       my %curr_groups = &Apache::longroup::coursegroups();
       foreach my $group_name (sort(keys(%curr_groups))) {
    push(@{$paramHash->{CHOICES}}, [$group_name, $group_name]);
     }      }
 }      }    
   
Line 2980  sub end_section { Line 3054  sub end_section {
 }      }    
 1;  1;
   
   package Apache::lonhelper::group;
   
   =pod
    
   =head2 Element: groupX<group, helper element>
    
   <group> allows the user to choose one or more groups from the current course.
   
   It takes the standard attributes "variable", "multichoice",
    "allowempty" and "nextstate", meaning what they do for most other
    elements.
   
   =cut
   
   no strict;
   @ISA = ("Apache::lonhelper::choices");
   use strict;
   
   BEGIN {
       &Apache::lonhelper::register('Apache::lonhelper::group',
                                    ('group'));
   }
   
   sub new {
       my $ref = Apache::lonhelper::choices->new();
       bless($ref);
   }
    
   sub start_group {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
    
       if ($target ne 'helper') {
           return '';
       }
   
       $paramHash->{CHOICES} = [];
   
       $paramHash->{'variable'} = $token->[2]{'variable'};
       $helper->declareVar($paramHash->{'variable'});
       $paramHash->{'multichoice'} = $token->[2]{'multichoice'};
       $paramHash->{'allowempty'} = $token->[2]{'allowempty'};
       if (defined($token->[2]{'nextstate'})) {
           $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};
       }
   
       # Populate the CHOICES element
       my %choices;
   
       my %curr_groups = &Apache::longroup::coursegroups();
       foreach my $group_name (sort {lc($a) cmp lc($b)} (keys(%curr_groups))) {
    push(@{$paramHash->{CHOICES}}, [$group_name, $group_name]);
       }
   }
   
   sub end_group {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
       if ($target ne 'helper') {
           return '';
       }
       Apache::lonhelper::group->new();
   }
   1;
   
 package Apache::lonhelper::string;  package Apache::lonhelper::string;
   
 =pod  =pod
Line 3046  sub render { Line 3184  sub render {
         $result .= '<p><font color="#FF0000">' . $self->{ERROR_MSG} . '</font></p>';          $result .= '<p><font color="#FF0000">' . $self->{ERROR_MSG} . '</font></p>';
     }      }
   
     $result .= '<input type="string" name="' . $self->{'variable'} . '.forminput"';      $result .= '<input type="string" name="' . $self->{'variable'} . '_forminput"';
   
     if (defined($self->{'size'})) {      if (defined($self->{'size'})) {
         $result .= ' size="' . $self->{'size'} . '"';          $result .= ' size="' . $self->{'size'} . '"';
Line 3073  sub postprocess { Line 3211  sub postprocess {
   
     if (defined($self->{VALIDATOR})) {      if (defined($self->{VALIDATOR})) {
  my $validator = eval($self->{VALIDATOR});   my $validator = eval($self->{VALIDATOR});
  die 'Died during evaluation of evaulation code; Perl said: ' . $@ if $@;   die 'Died during evaluation of validator code; Perl said: ' . $@ if $@;
  my $invalid = &$validator($helper, $state, $self, $self->getValue());   my $invalid = &$validator($helper, $state, $self, $self->getValue());
  if ($invalid) {   if ($invalid) {
     $self->{ERROR_MSG} = $invalid;      $self->{ERROR_MSG} = $invalid;
Line 3179  sub start_clause { Line 3317  sub start_clause {
     die 'Error in clause of condition, Perl said: ' . $@ if $@;      die 'Error in clause of condition, Perl said: ' . $@ if $@;
     if (!&$clause($helper, $paramHash)) {      if (!&$clause($helper, $paramHash)) {
         # Discard all text until the /condition.          # Discard all text until the /condition.
         &Apache::lonxml::get_all_text('/condition', $parser);   my $end_tag = $paramHash->{SKIPTAG} || '/condition';
           &Apache::lonxml::get_all_text($end_tag, $parser);
     }      }
 }  }
   
Line 3384  sub overrideForm { Line 3523  sub overrideForm {
   
 package Apache::lonhelper::parmwizfinal;  package Apache::lonhelper::parmwizfinal;
   
 # This is the final state for the parmwizard. It is not generally useful,  # This is the final state for the parm helper. It is not generally useful,
 # so it is not perldoc'ed. It does its own processing.  # so it is not perldoc'ed. It does its own processing.
 # It is represented with <parmwizfinal />, and  # It is represented with <parmwizfinal />, and
 # should later be moved to lonparmset.pm .  # should later be moved to lonparmset.pm .
Line 3452  sub render { Line 3591  sub render {
     if ($vars->{GRANULARITY} eq 'whole_course') {      if ($vars->{GRANULARITY} eq 'whole_course') {
         $resourceString .= '<li>'.&mt('for <b>all resources in the course</b>').'</li>';          $resourceString .= '<li>'.&mt('for <b>all resources in the course</b>').'</li>';
  if ($vars->{TARGETS} eq 'course') {   if ($vars->{TARGETS} eq 'course') {
     $level = 11; # general course, see lonparmset.pm perldoc      $level = 14; # general course, see lonparmset.pm perldoc
  } elsif ($vars->{TARGETS} eq 'section') {   } elsif ($vars->{TARGETS} eq 'section') {
       $level = 9;
    } elsif ($vars->{TARGETS} eq 'group') {
     $level = 6;      $level = 6;
  } else {   } else {
     $level = 3;      $level = 3;
Line 3468  sub render { Line 3609  sub render {
         $symb = $res->symb();          $symb = $res->symb();
         $resourceString .= '<li>'.&mt('for the map named [_1]',"<b>$title</b>").'</li>';          $resourceString .= '<li>'.&mt('for the map named [_1]',"<b>$title</b>").'</li>';
  if ($vars->{TARGETS} eq 'course') {   if ($vars->{TARGETS} eq 'course') {
     $level = 10; # general course, see lonparmset.pm perldoc      $level = 13; # general course, see lonparmset.pm perldoc
  } elsif ($vars->{TARGETS} eq 'section') {   } elsif ($vars->{TARGETS} eq 'section') {
       $level = 8;
    } elsif ($vars->{TARGETS} eq 'group') {
     $level = 5;      $level = 5;
  } else {   } else {
     $level = 2;      $level = 2;
Line 3485  sub render { Line 3628  sub render {
         my $title = $res->compTitle();          my $title = $res->compTitle();
         $resourceString .= '<li>'.&mt('for the resource named [_1] part [_2]',"<b>$title</b>","<b>$part</b>").'</li>';          $resourceString .= '<li>'.&mt('for the resource named [_1] part [_2]',"<b>$title</b>","<b>$part</b>").'</li>';
  if ($vars->{TARGETS} eq 'course') {   if ($vars->{TARGETS} eq 'course') {
     $level = 7; # general course, see lonparmset.pm perldoc      $level = 10; # general course, see lonparmset.pm perldoc
  } elsif ($vars->{TARGETS} eq 'section') {   } elsif ($vars->{TARGETS} eq 'section') {
       $level = 7;
    } elsif ($vars->{TARGETS} eq 'group') {
     $level = 4;      $level = 4;
  } else {   } else {
     $level = 1;      $level = 1;
Line 3566  sub render { Line 3711  sub render {
         $result .= '<li>'.&mt('for section [_1]',"<b>$section</b>").'</li>';          $result .= '<li>'.&mt('for section [_1]',"<b>$section</b>").'</li>';
  $result .= "<input type='hidden' name='csec' value='" .   $result .= "<input type='hidden' name='csec' value='" .
             HTML::Entities::encode($section,"'<>&\"") . "' />\n";              HTML::Entities::encode($section,"'<>&\"") . "' />\n";
       } elsif ($vars->{TARGETS} eq 'group') {
           my $group = $vars->{GROUP_NAME};
           $result .= '<li>'.&mt('for group [_1]',"<b>$group</b>").'</li>';
           $result .= "<input type='hidden' name='cgroup' value='" .
               HTML::Entities::encode($group,"'<>&\"") . "' />\n";
     } else {      } else {
         # FIXME: This is probably wasteful! Store the name!          # FIXME: This is probably wasteful! Store the name!
         my $classlist = Apache::loncoursedata::get_classlist();          my $classlist = Apache::loncoursedata::get_classlist();

Removed from v.1.127  
changed lines
  Added in v.1.161


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