Diff for /loncom/interface/lonhelper.pm between versions 1.153 and 1.180.2.1

version 1.153, 2006/05/30 21:48:00 version 1.180.2.1, 2010/08/14 20:19:42
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 185  use Apache::lonlocal; Line 188  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::longroup;  use Apache::longroup;
 use Apache::lonselstudent;  use Apache::lonselstudent;
 use lib '/home/httpd/lib/perl/';  
   
 use LONCAPA;  use LONCAPA;
   
 # Register all the tags with the helper, so the helper can   # Register all the tags with the helper, so the helper can 
Line 335  sub start_state { Line 339  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 365  use Apache::loncommon; Line 370  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 470  sub _saveVars { Line 476  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 487  sub declareVar { Line 492  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 526  sub process { Line 531  sub process {
     # Phase 1: Post processing for state of previous screen (which is actually      # Phase 1: Post processing for state of previous screen (which is actually
     # the "current state" in terms of the helper variables), if it wasn't the       # the "current state" in terms of the helper variables), if it wasn't the 
     # beginning state.      # beginning state.
     if ($self->{STATE} ne "START" || $env{"form.SUBMIT"} eq &mt("Next ->")) {      if ($self->{STATE} ne "START" || $env{"form.SUBMIT"} eq &mt("Next")) {
  my $prevState = $self->{STATES}{$self->{STATE}};   my $prevState = $self->{STATES}{$self->{STATE}};
         $prevState->postprocess();          $prevState->postprocess();
     }      }
Line 578  sub display { Line 583  sub display {
   
     # Phase 4: Display.      # Phase 4: Display.
     my $stateTitle=&mt($state->title());      my $stateTitle=&mt($state->title());
       my $stateHelp=     $state->help();
     my $browser_searcher_js =       my $browser_searcher_js = 
  '<script type="text/javascript">'."\n".   '<script type="text/javascript">'."\n".
  &Apache::loncommon::browser_and_searcher_javascript().   &Apache::loncommon::browser_and_searcher_javascript().
  "\n".'</script>';   "\n".'</script>';
   
     $result .= &Apache::loncommon::start_page($self->{TITLE},      # Breadcrumbs
       $browser_searcher_js);      my $brcrum = [{'href' => '',
                          'text' => 'Helper'}];
     my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"');      # FIXME: Dynamically add context sensitive breadcrumbs
     my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"');      #        depending on the caller,
     # FIXME: This should be parameterized, not concatenated - Jeremy      #        e.g. printing, parametrization, etc.
       # FIXME: Add breadcrumbs to reflect current helper state
   
       $result .= &Apache::loncommon::start_page($self->{TITLE},
                                                 $browser_searcher_js,
                                                 {'bread_crumbs' => $brcrum,});
   
     if (!$state->overrideForm()) { $result.="<form name='helpform' method='POST'>"; }      my $previous = HTML::Entities::encode(&mt("Back"), '<>&"');
     $result .= <<HEADER;      my $next = HTML::Entities::encode(&mt("Next"), '<>&"');
         <table border="0" width='100%'><tr><td>      # FIXME: This should be parameterized, not concatenated - Jeremy
         <h2><i>$stateTitle</i></h2>  
 HEADER  
   
     $result .= "<table cellpadding='10' width='100%'><tr><td rowspan='2' valign='top'>";  
   
     if (!$state->overrideForm()) {      if (!$state->overrideForm()) { $result.='<form name="helpform" method="post">'; }
         $result .= $self->_saveVars();      if ($stateHelp) {
           $stateHelp = &Apache::loncommon::help_open_topic($stateHelp);
     }      }
     $result .= $state->render();  
   
     $result .= "</td><td valign='top' align='right'>";  
   
     # Warning: Copy and pasted from below, because it's too much trouble to       # Prepare buttons
     # turn this into a subroutine      my $buttons;
     if (!$state->overrideForm()) {      if (!$state->overrideForm()) {
         if ($self->{STATE} ne $self->{START_STATE}) {          if ($self->{STATE} ne $self->{START_STATE}) {
             #$result .= '<input name="SUBMIT" type="submit" value="&lt;- Previous" />&nbsp;&nbsp;';              #$result .= '<input name="SUBMIT" type="submit" value="&lt;- Previous" />&nbsp;&nbsp;';
         }          }
           $buttons = '<p>'; # '<fieldset>';
         if ($self->{DONE}) {          if ($self->{DONE}) {
             my $returnPage = $self->{RETURN_PAGE};              my $returnPage = $self->{RETURN_PAGE};
             $result .= "<a href=\"$returnPage\">" . &mt("End Helper") . "</a>";              $buttons .= '<a href="'.$returnPage.'">'.&mt('End Helper').'</a>';
         }          }
         else {          else {
             $result .= '<nobr><input name="back" type="button" ';              $buttons .= '<span class="LC_nobreak">'
             $result .= 'value="' . $previous . '" onclick="history.go(-1)" /> ';                         .'<input name="back" type="button" '
             $result .= '<input name="SUBMIT" type="submit" value="' . $next . '" /></nobr>';                         .'value="'.$previous.'" onclick="history.go(-1)" /> '
                          .'<input name="SUBMIT" type="submit" value="'.$next.'" />'
                          .'</span>';
         }          }
       $buttons .= '</p>'; # '</fieldset>';
     }      }
   
     $result .= "</td></tr><tr><td valign='bottom' align='right'>";  
   
     # Warning: Copy and pasted from above, because it's too much trouble to   
     # turn this into a subroutine      $result .= '<h2>'.$stateTitle.$stateHelp.'</h2>';
   
   #   $result .= '<div>';
   
       # Top buttons
       $result .= $buttons;
   
       # Main content of current helper screen
     if (!$state->overrideForm()) {      if (!$state->overrideForm()) {
         if ($self->{STATE} ne $self->{START_STATE}) {          $result .= $self->_saveVars();
             #$result .= '<input name="SUBMIT" type="submit" value="&lt;- Previous" />&nbsp;&nbsp;';  
         }  
         if ($self->{DONE}) {  
             my $returnPage = $self->{RETURN_PAGE};  
             $result .= "<a href=\"$returnPage\">" . &mt('End Helper') . "</a>";  
         }  
         else {  
             $result .= '<nobr><input name="back" type="button" ';  
             $result .= 'value="' . $previous . '" onclick="history.go(-1)" /> ';  
             $result .= '<input name="SUBMIT" type="submit" value="' . $next . '" /></nobr>';  
         }  
     }      }
       $result .= $state->render();
   
       # Bottom buttons
       $result .= $buttons;
   
   
     #foreach my $key (keys %{$self->{VARS}}) {      #foreach my $key (keys %{$self->{VARS}}) {
     #    $result .= "|$key| -> " . $self->{VARS}->{$key} . "<br />";      #    $result .= "|$key| -> " . $self->{VARS}->{$key} . "<br />";
     #}      #}
   
     $result .= "</td></tr></table>";  #   $result .= '</div>';
   
     $result .= <<FOOTER;      $result .= <<FOOTER;
               </td>  
             </tr>  
           </table>  
         </form>          </form>
 FOOTER  FOOTER
   
Line 681  sub new { Line 687  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 702  sub title { Line 709  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 793  the element. How this value is interpret Line 805  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 995  sub start_message { Line 1007  sub start_message {
     if (defined($token->[2]{'nextstate'})) {      if (defined($token->[2]{'nextstate'})) {
         $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};          $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};
     }      }
       if (defined($token->[2]{'type'})) {
           $paramHash->{TYPE} = $token->[2]{'type'};
       }
     return '';      return '';
 }  }
   
Line 1010  sub end_message { Line 1025  sub end_message {
   
 sub render {  sub render {
     my $self = shift;      my $self = shift;
       
     return &mtn($self->{MESSAGE_TEXT});      if ($self->{TYPE} =~ /^\s*warning\s*$/i) {
    $self->{MESSAGE_TEXT} = 
        '<span class="LC_warning">'. $self->{MESSAGE_TEXT}.'</span>';
       }
       if ($self->{TYPE} =~ /^\s*error\s*$/i) {
    $self->{MESSAGE_TEXT} = 
        '<span class="LC_error">'. $self->{MESSAGE_TEXT}.'</span>';
       }
       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 1024  sub postprocess { Line 1047  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 1206  sub render { Line 1398  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 1279  BUTTONS Line 1471  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 1295  BUTTONS Line 1487  BUTTONS
             $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>";      $choiceLabel. "</label></td>";
  if ($choice->[4]) {   if ($choice->[4]) {
     $result .='<td><input type="text" size="5" name="'      $result .='<td><input type="text" size="5" name="'
  .$choice->[4].'.forminput" value="'   .$choice->[4].'_forminput" value="'
                 .$choice->[5].'" /></td>';                  .$choice->[5].'" /></td>';
  }   }
  $result .= "</tr>\n";   $result .= "</tr>\n";
Line 1313  BUTTONS Line 1505  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 1321  sub postprocess { Line 1514  sub postprocess {
         return 0;          return 0;
     }      }
   
   
   
     if (ref($chosenValue)) {      if (ref($chosenValue)) {
         $helper->{VARS}->{$self->{'variable'}} = join('|||', @$chosenValue);          $helper->{VARS}->{$self->{'variable'}} = join('|||', @$chosenValue);
     }      }
Line 1337  sub postprocess { Line 1532  sub postprocess {
         }          }
  if ($choice->[4]) {   if ($choice->[4]) {
     my $varname = $choice->[4];      my $varname = $choice->[4];
     $helper->{'VARS'}->{$varname} = $env{'form.'."$varname.forminput"};      $helper->{'VARS'}->{$varname} = $env{'form.'."${varname}_forminput"};
  }   }
     }      }
     return 1;      return 1;
Line 1446  sub render { Line 1641  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 1472  sub render { Line 1667  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 1532  no strict; Line 1727  no strict;
 use strict;  use strict;
 use Apache::lonlocal; # A localization nightmare  use Apache::lonlocal; # A localization nightmare
 use Apache::lonnet;  use Apache::lonnet;
 use Time::localtime;  use DateTime;
   
 BEGIN {  BEGIN {
     &Apache::lonhelper::register('Apache::lonhelper::date',      &Apache::lonhelper::register('Apache::lonhelper::date',
Line 1582  sub render { Line 1777  sub render {
     my $time=time;      my $time=time;
     my ($anytime,$onclick);      my ($anytime,$onclick);
   
   
     # first check VARS for a valid new value from the user      # first check VARS for a valid new value from the user
     # then check DEFAULT_VALUE for a valid default time value      # then check DEFAULT_VALUE for a valid default time value
     # otherwise pick now as reasonably good time      # otherwise pick now as reasonably good time
   
     if (defined($helper->{VARS}{$var})      if (defined($helper->{VARS}{$var})
  &&  $helper->{VARS}{$var} > 0) {   &&  $helper->{VARS}{$var} > 0) {
  $date = localtime($helper->{VARS}{$var});          $date = &get_date_object($helper->{VARS}{$var}); 
     } elsif (defined($self->{DEFAULT_VALUE})) {      } 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 ' . 
Line 1597  sub render { Line 1791  sub render {
         $time = &$valueFunc($helper, $self);          $time = &$valueFunc($helper, $self);
  if (lc($time) eq 'anytime') {   if (lc($time) eq 'anytime') {
     $anytime=1;      $anytime=1;
     $date = localtime(time);      $date = &get_date_object(time);
     $date->min(0);      $date->min(0);
  } elsif (defined($time) && $time ne 0) {   } elsif (defined($time) && $time ne 0) {
     $date = localtime($time);      $date = &get_date_object($time);
  } else {   } else {
     # leave date undefined so it'll default to now      # leave date undefined so it'll default to now
  }   }
     }      }
   
     if (!defined($date)) {      if (!defined($date)) {
  $date = localtime(time);   $date = &get_date_object(time);
  $date->min(0);   $date->min(0);
     }      }
   
     &Apache::lonnet::logthis("date mode ");  
   
     if ($anytime) {      if ($anytime) {
  $onclick = "onclick=\"javascript:updateCheck(this.form,'${var}anytime',false)\"";   $onclick = "onclick=\"javascript:updateCheck(this.form,'${var}anytime',false)\"";
     }      }
Line 1626  sub render { Line 1818  sub render {
     my $i;      my $i;
     $result .= "<select $onclick name='${var}month'>\n";      $result .= "<select $onclick name='${var}month'>\n";
     for ($i = 0; $i < 12; $i++) {      for ($i = 0; $i < 12; $i++) {
         if ($i == $date->mon) {          if (($i + 1) == $date->mon) {
             $result .= "<option value='$i' selected='selected'>";              $result .= "<option value='$i' selected='selected'>";
         } else {          } else {
             $result .= "<option value='$i'>";              $result .= "<option value='$i'>";
         }          }
         $result .= &mt($months[$i]) . "</option>\n";          $result .= &mt($months[$i])."</option>\n";
     }      }
     $result .= "</select>\n";      $result .= "</select>\n";
   
Line 1650  sub render { Line 1842  sub render {
     # Year      # Year
     $result .= "<select $onclick name='${var}year'>\n";      $result .= "<select $onclick name='${var}year'>\n";
     for ($i = 2000; $i < 2030; $i++) { # update this after 64-bit dates      for ($i = 2000; $i < 2030; $i++) { # update this after 64-bit dates
         if ($date->year + 1900 == $i) {          if ($date->year == $i) {
             $result .= "<option selected='selected'>";              $result .= "<option selected='selected'>";
         } else {          } else {
             $result .= "<option>";              $result .= "<option>";
Line 1705  sub render { Line 1897  sub render {
         }          }
         $result .= "</select>\n";          $result .= "</select>\n";
     }      }
       $result  .= ' '.$date->time_zone_short_name().' ';
     if ($self->{'anytime'}) {      if ($self->{'anytime'}) {
  $result.=(<<CHECK);   $result.=(<<CHECK);
 <script type="text/javascript">  <script type="text/javascript">
Line 1732  sub postprocess { Line 1925  sub postprocess {
     if ($env{'form.' . $var . 'anytime'}) {      if ($env{'form.' . $var . 'anytime'}) {
  $helper->{VARS}->{$var} = undef;   $helper->{VARS}->{$var} = undef;
     } else {      } else {
  my $month = $env{'form.' . $var . 'month'};    my $month = $env{'form.' . $var . 'month'};
           $month ++;
  my $day = $env{'form.' . $var . 'day'};    my $day = $env{'form.' . $var . 'day'}; 
  my $year = $env{'form.' . $var . 'year'};    my $year = $env{'form.' . $var . 'year'}; 
  my $min = 0;    my $min = 0; 
Line 1742  sub postprocess { Line 1936  sub postprocess {
     $hour = $env{'form.' . $var . 'hour'};      $hour = $env{'form.' . $var . 'hour'};
  }   }
   
  my $chosenDate;   my ($chosenDate,$checkDate);
  eval {$chosenDate = Time::Local::timelocal(0, $min, $hour, $day, $month, $year);};          my $timezone = &Apache::lonlocal::gettimezone();
           my $dt;
    eval {
                  $dt = DateTime->new( year   => $year,
                                       month  => $month,
                                       day    => $day,
                                       hour   => $hour,
                                       minute => $min,
                                       second => 0,
                                       time_zone => $timezone,
                                );
           };
   
  my $error = $@;   my $error = $@;
           if (!$error) {
               $chosenDate  = $dt->epoch;
               $checkDate = &get_date_object($chosenDate);
           }
   
  # Check to make sure that the date was not automatically co-erced into a    # Check to make sure that the date was not automatically co-erced into a 
  # valid date, as we want to flag that as an error   # valid date, as we want to flag that as an error
  # This happens for "Feb. 31", for instance, which is coerced to March 2 or   # This happens for "Feb. 31", for instance, which is coerced to March 2 or
  # 3, depending on if it's a leap year   # 3, depending on if it's a leap year
  my $checkDate = localtime($chosenDate);  
   
  if ($error || $checkDate->mon != $month || $checkDate->mday != $day ||   if ($error || $checkDate->mon != $month || $checkDate->mday != $day ||
     $checkDate->year + 1900 != $year) {      $checkDate->year != $year) {
     unless (Apache::lonlocal::current_language()== ~/^en/) {      unless (Apache::lonlocal::current_language()== ~/^en/) {
  $self->{ERROR_MSG} = &mt("Invalid date entry");   $self->{ERROR_MSG} = &mt("Invalid date entry");
  return 0;   return 0;
     }      }
     # LOCALIZATION FIXME: Needs to be parameterized      # LOCALIZATION FIXME: Needs to be parameterized
     $self->{ERROR_MSG} = "Can't use " . $months[$month] . " $day, $year as a "      $self->{ERROR_MSG} = "Can't use ".$months[$env{'form.'.$var.'month'}].                                 " $day, $year as a ".
  . "date because it doesn't exist. Please enter a valid date.";                   "date because it doesn't exist. Please enter a valid date.";
   
     return 0;      return 0;
  }   }
Line 1783  sub postprocess { Line 1992  sub postprocess {
   
     return 1;      return 1;
 }  }
   
   sub get_date_object {
       my ($epoch) = @_;
       my $dt = DateTime->from_epoch(epoch => $epoch)
                        ->set_time_zone(&Apache::lonlocal::gettimezone());
       my $lang = Apache::lonlocal::current_language();
       if ($lang ne '') {
           eval {
               $dt->set_locale($lang);
           };
       }
       return $dt;
   }
   
 1;  1;
   
 package Apache::lonhelper::resource;  package Apache::lonhelper::resource;
Line 1809  folders that have all of their contained Line 2032  folders that have all of their contained
 be filtered out. The 'addstatus' attribute, if true, will add the icon  be filtered out. The 'addstatus' attribute, if true, will add the icon
 and long status display columns to the display. The 'addparts'  and long status display columns to the display. The 'addparts'
 attribute will add in a part selector beside problems that have more  attribute will add in a part selector beside problems that have more
 than 1 part.  than 1 part. The 'includecourse' attribute if true, will include
   the toplevel default.sequence in the results.
   
 =head3 SUB-TAGS  =head3 SUB-TAGS
   
Line 1842  than 1 part. Line 2066  than 1 part.
   evaluated with "sub { my $helper = shift; my $state = shift;" and    evaluated with "sub { my $helper = shift; my $state = shift;" and
   "}", with the return value used as the mapurl.    "}", with the return value used as the mapurl.
   
   =item * <option />: Allows you to add optional elements to the
     resource chooser currently these can be a checkbox, or a text entry
     or hidden (see the 'type' attribute below).
     the following attributes are supported by this tag:
   
   =over 4
   
   =item * type=control-type : determines the type of control displayed.
     This can be one of the following types: 'checkbox' provides a true/false
     checkbox.  'text' provides a text entry control. 'hidden' provides a
     hidden form element that returns the name of the resource for each
     element of the text box.
   
   =item * text=header-text : provides column header text for the option.
     
   =item * variable=helpervar : provides a helper variable to contain the
     value of the input control for each resource.  In general, the result
     will be a set of values separated by |||  for the checkbox the value between
     the |||'s will either be empty, if the box is not checked, or the resource
     name if checked.  For the text entry, the values will be the text in the
     text box.  This could be empty.  Hidden elements unconditionally provide
     the resource name for each row of the chooser and allow you to therefore
     correlate text entries to their resources.
     The helper variable can be initialized by the user code to pre-load values
     into the controls:
   
   =over 4
   
     
   =item * Preloading checkboxes : Set the helper variable to the value you
      would have gotten from the control if it had been manually set as desired.
   
   =item * Preloading text entries : Set the helper variable to triple pipe
      separated values where each value is of the form resource-name=value
   
   =item * Preloading hidden fields : These cannot be pre-loaded and will always
     be pipe separated resource names.
   
   =back
   
   
   =back
   
 =back  =back
   
 =cut  =cut
Line 1882  sub start_resource { Line 2149  sub start_resource {
  $helper->declareVar($paramHash->{'variable'}.'_part');   $helper->declareVar($paramHash->{'variable'}.'_part');
     }      }
     $paramHash->{'closeallpages'} = $token->[2]{'closeallpages'};      $paramHash->{'closeallpages'} = $token->[2]{'closeallpages'};
       $paramHash->{'include_top_level_map'} = $token->[2]{'includecourse'};
     return '';      return '';
 }  }
   
Line 1970  sub start_option { Line 2238  sub start_option {
     if (!defined($paramHash->{OPTION_TEXTS})) {      if (!defined($paramHash->{OPTION_TEXTS})) {
  $paramHash->{OPTION_TEXTS} = [ ];   $paramHash->{OPTION_TEXTS} = [ ];
  $paramHash->{OPTION_VARS}  = [ ];   $paramHash->{OPTION_VARS}  = [ ];
    $paramHash->{OPTION_TYPES} = [ ];
   
     }      }
       #  We can have an attribute: type which can have the
       #  values: "checkbox" or "text" which defaults to 
       #           checkbox allowing us to change the type of input
       #           for the option:
       #
       my $input_widget_type = 'checkbox';
       if(defined($token->[2]{'type'})) {
    my $widget_type  = $token->[2]{'type'};
    if ($widget_type eq 'text') {          # only accept legal alternatives
       $input_widget_type = $widget_type; # Illegals are checks.
    } elsif ($widget_type eq 'hidden') {
       $input_widget_type = $widget_type;
    }
       }
   
     # OPTION_TEXTS is a list of the text attribute      # OPTION_TEXTS is a list of the text attribute
     #               values used to create column headings.      #               values used to create column headings.
     # OPTION_VARS is a list of the variable names, used to create the checkbox      # OPTION_VARS is a list of the variable names, used to create the checkbox
     #             inputs.      #             inputs.
       # OPTION_TYPES is a list of the option types:
       #
     #  We're ok with empty elements. as place holders      #  We're ok with empty elements. as place holders
     # Although the 'variable' element should really exist.      # Although the 'variable' element should really exist.
     #      #
   
   
     my $option_texts  = $paramHash->{OPTION_TEXTS};      my $option_texts  = $paramHash->{OPTION_TEXTS};
     my $option_vars   = $paramHash->{OPTION_VARS};      my $option_vars   = $paramHash->{OPTION_VARS};
       my $option_types   = $paramHash->{OPTION_TYPES};
     push(@$option_texts,  $token->[2]{'text'});      push(@$option_texts,  $token->[2]{'text'});
     push(@$option_vars,   $token->[2]{'variable'});      push(@$option_vars,   $token->[2]{'variable'});
       push(@$option_types,   $input_widget_type);
   
   
     #  Need to create and declare the option variables as well to make them      #  Need to create and declare the option variables as well to make them
     # persistent.      # persistent.
Line 2027  sub render { Line 2317  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 2059  BUTTONS Line 2349  BUTTONS
     my $multichoice    = $self->{'multichoice'};      my $multichoice    = $self->{'multichoice'};
     my $option_vars    = $self->{OPTION_VARS};      my $option_vars    = $self->{OPTION_VARS};
     my $option_texts   = $self->{OPTION_TEXTS};      my $option_texts   = $self->{OPTION_TEXTS};
       my $option_types   = $self->{OPTION_TYPES};
     my $addparts       = $self->{'addparts'};      my $addparts       = $self->{'addparts'};
     my $headings_done  = 0;      my $headings_done  = 0;
   
Line 2117  BUTTONS Line 2408  BUTTONS
     my $resource_name =         my $resource_name =   
                    HTML::Entities::encode($raw_name,"<>&\"'");                     HTML::Entities::encode($raw_name,"<>&\"'");
     if($option_vars) {      if($option_vars) {
    my $option_num = 0;
  foreach my $option_var (@$option_vars) {   foreach my $option_var (@$option_vars) {
       my $option_type = $option_types->[$option_num];
       $option_num++;
     my $var_value = "\|\|\|" . $helper->{VARS}->{$option_var} .       my $var_value = "\|\|\|" . $helper->{VARS}->{$option_var} . 
  "\|\|\|";   "\|\|\|";
     my $checked ="";      my $checked ="";
     if($var_value =~ /\Q|||$raw_name|||\E/) {      if($var_value =~ /\Q|||$raw_name|||\E/) {
  $checked = "checked='checked'";   $checked = "checked='checked'";
     }      }
     $col .=       if ($option_type eq 'text') {
                         "<td align='center'><input type='checkbox' name ='$option_var".   #
  ".forminput' value='".   # For text's the variable value is a ||| separated set of
  $resource_name . "' $checked /> </td>";   # resource_name=value 
    #
    my @values = split(/\|\|\|/, $helper->{VARS}->{$option_var});
   
    # Normal practice would be to toss this in a hash but 
    # the only thing that saves is the compare in the loop
    # below and for all but one case we'll break out of the loop
    # before it completes.
   
    my $text_value = '';    # In case there's no match.
    foreach my $value (@values) {
       my ($res, $skip) = split(/=/, $value);
       if($res eq $resource_name) {
    $text_value = $skip;
    last;
       }
    }
    # TODO: add an attribute to <option> that allows the
    #       programmer to set the width of the tex entry box.
   
    $col .=
       "<td align='center'><input type='text' name ='$option_var".
       "_forminput' value='".$text_value."' size='5' /> </td>";
       } elsif ($option_type eq 'hidden') {
     $col .= "<td align='center'><input type='hidden' name ='$option_var".
       "_forminput' value='".
       $resource_name . "'/> </td>";
       } else {
    $col .= 
       "<td align='center'><input type=$option_type name ='$option_var".
       "_forminput' value='".
       $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 2160  BUTTONS Line 2486  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 2182  BUTTONS Line 2508  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 2207  RADIO Line 2533  RADIO
                                        'resource_no_folder_link' => 1,                                         'resource_no_folder_link' => 1,
        'closeAllPages' => $self->{'closeallpages'},         'closeAllPages' => $self->{'closeallpages'},
                                        'suppressEmptySequences' => $self->{'suppressEmptySequences'},                                         'suppressEmptySequences' => $self->{'suppressEmptySequences'},
          'include_top_level_map' => $self->{'include_top_level_map'},
                                        'iterator_map' => $mapUrl }                                         'iterator_map' => $mapUrl }
                                        );                                         );
   
Line 2222  sub postprocess { Line 2549  sub postprocess {
         $self->{ERROR_MSG} = 'You must choose at least one resource to continue.';          $self->{ERROR_MSG} = 'You must choose at least one resource to continue.';
         return 0;          return 0;
     }      }
       # For each of the attached options.  If it's env var is undefined, set it to
       # an empty string instead.. an undef'd env var means no choices selected.
       #
   
       my $option_vars = $self->{OPTION_VARS};
       if ($option_vars) {
    foreach my $var (@$option_vars) {
       my $env_name = "form.".$var."_forminput";
       if (!defined($env{$env_name})) {
    $env{$env_name} = '';
    $helper->{VARS}->{$var} = '';
       }
    }
       }
   
   
     if (defined($self->{NEXTSTATE})) {      if (defined($self->{NEXTSTATE})) {
         $helper->changeState($self->{NEXTSTATE});          $helper->changeState($self->{NEXTSTATE});
Line 2358  sub render { Line 2700  sub render {
   
     #   Current personel      #   Current personel
   
       $result .= '<h4>'.&mt('Select Currently Enrolled Students and Active Course Personnel').'</h4>';
     $result .= &Apache::lonselstudent::render_student_list( $current_members,      $result .= &Apache::lonselstudent::render_student_list( $current_members,
     "helpform",      "helpform",
     "current",       "current", 
Line 2369  sub render { Line 2712  sub render {
   
     # If activeonly is not set then we can also give the expired students:      # If activeonly is not set then we can also give the expired students:
     #      #
     if (!$self->{'activeonly'} && ((scalar @$expired_members) > 0)) {      if (!$self->{'activeonly'} && ((scalar(@$future_members)) > 0)) {
   
  # And future.   # And future.
   
    $result .= '<h4>'.&mt('Select Future Enrolled Students and Future Course Personnel').'</h4>';
          
  $result .= &Apache::lonselstudent::render_student_list( $future_members,   $result .= &Apache::lonselstudent::render_student_list( $future_members,
  "helpform",   "helpform",
  "future",   "future",
Line 2380  sub render { Line 2725  sub render {
  $self->{'multichoice'},   $self->{'multichoice'},
  $self->{'variable'},   $self->{'variable'},
  0);   0);
       }
       if (!$self->{'activeonly'} && ((scalar(@$expired_members)) > 0)) {
  # Past    # Past 
   
    $result .= '<h4>'.&mt('Select Previously Enrolled Students and Inactive Course Personnel').'</h4>';
  $result .= &Apache::lonselstudent::render_student_list($expired_members,   $result .= &Apache::lonselstudent::render_student_list($expired_members,
        "helpform",         "helpform",
        "past",         "past",
Line 2399  sub render { Line 2747  sub render {
 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 2584  sub render { Line 2932  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 2632  BUTTONS Line 2980  BUTTONS
     &Apache::loncacc::constructaccess($subdir,      &Apache::loncacc::constructaccess($subdir,
      $Apache::lonnet::perlvar{'lonDefDomain'});       $Apache::lonnet::perlvar{'lonDefDomain'});
  $metadir='/res/'.$domain.'/'.$user.'/'.$2;   $metadir='/res/'.$domain.'/'.$user.'/'.$2;
         @fileList = &Apache::lonnet::dirlist($subdir, $domain, $user, '');          @fileList = &Apache::lonnet::dirlist($subdir,$domain,$user,undef,undef,'/');
     } elsif ($subdir =~ m|^~([^/]+)/(.*)$|) {      } elsif ($subdir =~ m|^~([^/]+)/(.*)$|) {
  $subdir='/home/'.$1.'/public_html/'.$2;   $subdir='/home/'.$1.'/public_html/'.$2;
  my ($user,$domain)=    my ($user,$domain)= 
     &Apache::loncacc::constructaccess($subdir,      &Apache::loncacc::constructaccess($subdir,
      $Apache::lonnet::perlvar{'lonDefDomain'});       $Apache::lonnet::perlvar{'lonDefDomain'});
  $metadir='/res/'.$domain.'/'.$user.'/'.$2;   $metadir='/res/'.$domain.'/'.$user.'/'.$2;
         @fileList = &Apache::lonnet::dirlist($subdir, $domain, $user, '');          @fileList = &Apache::lonnet::dirlist($subdir,$domain,$user,undef,undef,'/');
     } else {      } else {
         # local library server resource space          # local library server resource space
         @fileList = &Apache::lonnet::dirlist($subdir, $env{'user.domain'}, $env{'user.name'}, '');          @fileList = &Apache::lonnet::dirlist($subdir,$env{'user.domain'},$env{'user.name'},undef,undef,'/');
     }      }
   
     # Sort the fileList into order      # Sort the fileList into order
Line 2701  BUTTONS Line 3049  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 2762  sub fileState { Line 3110  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 2941  package Apache::lonhelper::string; Line 3289  package Apache::lonhelper::string;
 string elements provide a string entry field for the user. string elements  string elements provide a string entry field for the user. string elements
 take the usual 'variable' and 'nextstate' parameters. string elements  take the usual 'variable' and 'nextstate' parameters. string elements
 also pass through 'maxlength' and 'size' attributes to the input tag.  also pass through 'maxlength' and 'size' attributes to the input tag.
   Since you could have multiple strings in a helper state, each with its own
   validator, all but the last string should have
   noproceed='1' so that _all_ validators are evaluated before the next
   state can be reached.
   
 string honors the defaultvalue tag, if given.  string honors the defaultvalue tag, if given.
   
Line 2960  BEGIN { Line 3312  BEGIN {
   
 sub new {  sub new {
     my $ref = Apache::lonhelper::element->new();      my $ref = Apache::lonhelper::element->new();
       $ref->{'PROCEED'} = 1;      # By default postprocess goes to next state.
     bless($ref);      bless($ref);
 }  }
   
Line 2976  sub start_string { Line 3329  sub start_string {
     $paramHash->{'nextstate'} = $token->[2]{'nextstate'};      $paramHash->{'nextstate'} = $token->[2]{'nextstate'};
     $paramHash->{'maxlength'} = $token->[2]{'maxlength'};      $paramHash->{'maxlength'} = $token->[2]{'maxlength'};
     $paramHash->{'size'} = $token->[2]{'size'};      $paramHash->{'size'} = $token->[2]{'size'};
   
     return '';      return '';
 }  }
   
 sub end_string {  sub end_string {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
   
     if ($target ne 'helper') {      if ($target ne 'helper') {
         return '';          return '';
     }      }
     Apache::lonhelper::string->new();      my $state = Apache::lonhelper::string->new();
   
   
       if(&Apache::lonxml::get_param('noproceed', $parstack, $safeeval, undef, 1)) {
    $state->noproceed();
       }
   
      
   
     return '';      return '';
 }  }
   
   sub noproceed() {
       my $self = shift;
       $self->{PROCEED}  = 0;
   }
   
 sub render {  sub render {
     my $self = shift;      my $self = shift;
     my $result = '';      my $result = '';
Line 2998  sub render { Line 3364  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 3033  sub postprocess { Line 3399  sub postprocess {
  }   }
     }      }
   
     if (defined($self->{'nextstate'})) {      if (defined($self->{'nextstate'}) && $self->{PROCEED}) {
         $helper->changeState($self->{'nextstate'});          $helper->changeState($self->{'nextstate'});
     }      }
   
Line 3131  sub start_clause { Line 3497  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 3190  snippets and collecting the results. Fin Line 3557  snippets and collecting the results. Fin
 helper, going to a provided page.  helper, going to a provided page.
   
 If the parameter "restartCourse" is true, this will override the buttons and  If the parameter "restartCourse" is true, this will override the buttons and
 will make a "Finish Helper" button that will re-initialize the course for them,  will make a Save button (Finish Helper) that will re-initialize the course for them,
 which is useful for the Course Initialization helper so the users never see  which is useful for the Course Initialization helper so the users never see
 the old values taking effect.  the old values taking effect.
   
Line 3297  sub render { Line 3664  sub render {
   
     my $actionURL = $self->{EXIT_PAGE};      my $actionURL = $self->{EXIT_PAGE};
     my $targetURL = '';      my $targetURL = '';
     my $finish=&mt('Finish');   my $finish=&mt('Save');
     if ($self->{'restartCourse'}) {      if ($self->{'restartCourse'}) {
  $actionURL = '/adm/roles';   $actionURL = '/adm/roles';
  $targetURL = '/adm/menu';   $targetURL = '/adm/menu';
Line 3309  sub render { Line 3676  sub render {
  if ($env{'course.'.$env{'request.course.id'}.'.clonedfrom'}) {   if ($env{'course.'.$env{'request.course.id'}.'.clonedfrom'}) {
     $targetURL = '/adm/parmset?overview=1';      $targetURL = '/adm/parmset?overview=1';
  }   }
  my $finish=&mt('Finish Course Initialization');  
     }      }
     my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"');      my $previous = HTML::Entities::encode(&mt("Back"), '<>&"');
     my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"');      my $next = HTML::Entities::encode(&mt("Next"), '<>&"');
     my $target = " target='loncapaclient'";      my $target = " target='loncapaclient'";
     if (($env{'browser.interface'} eq 'textual') ||      if ($env{'environment.remote'} eq 'off') {  $target='';  }
         ($env{'environment.remote'} eq 'off')) {  $target='';  }      $result .= "<p>\n" .
     $result .= "<center>\n" .  
  "<form action='".$actionURL."' method='post' $target>\n" .   "<form action='".$actionURL."' method='post' $target>\n" .
  "<input type='button' onclick='history.go(-1)' value='$previous' />" .   "<input type='button' onclick='history.go(-1)' value='$previous' />" .
  "<input type='hidden' name='orgurl' value='$targetURL' />" .   "<input type='hidden' name='orgurl' value='$targetURL' />" .
  "<input type='hidden' name='selectrole' value='1' />\n" .   "<input type='hidden' name='selectrole' value='1' />\n" .
  "<input type='hidden' name='" . $env{'request.role'} .    "<input type='hidden' name='" . $env{'request.role'} . 
  "' value='1' />\n<input type='submit' value='" . $finish . "' />\n" .   "' value='1' />\n<input type='submit' value='" . $finish . "' />\n" .
  "</form></center>";   "</form></p>\n";
   
     return $result;      return $result;
 }  }
Line 3336  sub overrideForm { Line 3701  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 3402  sub render { Line 3767  sub render {
           
     # Print the granularity, depending on the action      # Print the granularity, depending on the action
     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 [_1]all resources in the course[_2]','<b>','</b>').'</li>';
  if ($vars->{TARGETS} eq 'course') {   if ($vars->{TARGETS} eq 'course') {
     $level = 14; # general course, see lonparmset.pm perldoc      $level = 14; # general course, see lonparmset.pm perldoc
  } elsif ($vars->{TARGETS} eq 'section') {   } elsif ($vars->{TARGETS} eq 'section') {
Line 3417  sub render { Line 3782  sub render {
         $paramlevel = 'general';          $paramlevel = 'general';
     } elsif ($vars->{GRANULARITY} eq 'map') {      } elsif ($vars->{GRANULARITY} eq 'map') {
         my $navmap = Apache::lonnavmaps::navmap->new();          my $navmap = Apache::lonnavmaps::navmap->new();
         my $res = $navmap->getByMapPc($vars->{RESOURCE_ID});          if (defined($navmap)) {
         my $title = $res->compTitle();               my $res = $navmap->getByMapPc($vars->{RESOURCE_ID});
         $symb = $res->symb();               my $title = $res->compTitle();
         $resourceString .= '<li>'.&mt('for the map named [_1]',"<b>$title</b>").'</li>';               $symb = $res->symb();
                $resourceString .= '<li>'.&mt('for the map named [_1]',"<b>$title</b>").'</li>';
           } else {
               $resourceString .= '<li>'.&mt('for the map ID [_1] (name unavailable)','<b>'.$vars->{RESOURCE_ID}.'</b>').'</li>';
               &Apache::lonnet::logthis('Retrieval of map title failed in lonhelper.pm - could not create navmap object for course.');
   
           }
  if ($vars->{TARGETS} eq 'course') {   if ($vars->{TARGETS} eq 'course') {
     $level = 13; # general course, see lonparmset.pm perldoc      $level = 13; # general course, see lonparmset.pm perldoc
  } elsif ($vars->{TARGETS} eq 'section') {   } elsif ($vars->{TARGETS} eq 'section') {
Line 3433  sub render { Line 3804  sub render {
         $affectedResourceId = $vars->{RESOURCE_ID};          $affectedResourceId = $vars->{RESOURCE_ID};
         $paramlevel = 'map';          $paramlevel = 'map';
     } else {      } else {
         my $navmap = Apache::lonnavmaps::navmap->new();  
         my $res = $navmap->getById($vars->{RESOURCE_ID});  
         my $part = $vars->{RESOURCE_ID_part};          my $part = $vars->{RESOURCE_ID_part};
  if ($part ne 'All Parts' && $part) { $parm_name=~s/^0/$part/; } else { $part=&mt('All Parts'); }   if ($part ne 'All Parts' && $part) { $parm_name=~s/^0/$part/; } else { $part=&mt('All Parts'); }
         $symb = $res->symb();          my $navmap = Apache::lonnavmaps::navmap->new();
         my $title = $res->compTitle();          if (defined($navmap)) {
         $resourceString .= '<li>'.&mt('for the resource named [_1] part [_2]',"<b>$title</b>","<b>$part</b>").'</li>';              my $res = $navmap->getById($vars->{RESOURCE_ID});
               $symb = $res->symb();
               my $title = $res->compTitle();
               $resourceString .= '<li>'.&mt('for the resource named [_1], part [_2]',"<b>$title</b>","<b>$part</b>").'</li>';
           } else {
               $resourceString .= '<li>'.&mt('for the resource ID [_1] (name unavailable), part [_2]','<b>'.$vars->{RESOURCE_ID}.'</b>',"<b>$part</b>").'</li>';
               &Apache::lonnet::logthis('Retrieval of resource title failed in lonhelper.pm - could not create navmap object for course.');
           }
  if ($vars->{TARGETS} eq 'course') {   if ($vars->{TARGETS} eq 'course') {
     $level = 10; # general course, see lonparmset.pm perldoc      $level = 10; # general course, see lonparmset.pm perldoc
  } elsif ($vars->{TARGETS} eq 'section') {   } elsif ($vars->{TARGETS} eq 'section') {
Line 3453  sub render { Line 3829  sub render {
         $paramlevel = 'full';          $paramlevel = 'full';
     }      }
   
     my $result = "<form name='helpform' method='POST' action='/adm/parmset#$affectedResourceId&$parm_name&$level'>\n";      my $result = "<form name='helpform' method='post' action='/adm/parmset#$affectedResourceId&$parm_name&$level'>\n";
     $result .= "<input type='hidden' name='action' value='settable' />\n";      $result .= "<input type='hidden' name='action' value='settable' />\n";
     $result .= "<input type='hidden' name='dis' value='helper' />\n";      $result .= "<input type='hidden' name='dis' value='helper' />\n";
     $result .= "<input type='hidden' name='pscat' value='".      $result .= "<input type='hidden' name='pscat' value='".
Line 3470  sub render { Line 3846  sub render {
     $result .= "<input type='hidden' name='psprt' value='".      $result .= "<input type='hidden' name='psprt' value='".
  HTML::Entities::encode($part,"'<>&\"") . "' />\n";   HTML::Entities::encode($part,"'<>&\"") . "' />\n";
   
     $result .= '<p>'.&mt('Confirm that this information is correct, then click &quot;Finish Helper&quot; to complete setting the parameter.').'<ul>';      $result .= '<p class="LC_info">'
                 .&mt('Confirm that this information is correct, then click &quot;Save&quot; to complete setting the parameter.')
                 .'</p>'
                 .'<ul>';
           
     # Print the type of manipulation:      # Print the type of manipulation:
     my $extra;      my $extra;
Line 3518  sub render { Line 3897  sub render {
           
     # Print targets      # Print targets
     if ($vars->{TARGETS} eq 'course') {      if ($vars->{TARGETS} eq 'course') {
         $result .= '<li>'.&mt('for <b>all students in course</b>').'</li>';          $result .= '<li>'.&mt('for [_1]all students in course[_2]','<b>','</b>').'</li>';
     } elsif ($vars->{TARGETS} eq 'section') {      } elsif ($vars->{TARGETS} eq 'section') {
         my $section = $vars->{SECTION_NAME};          my $section = $vars->{SECTION_NAME};
         $result .= '<li>'.&mt('for section [_1]',"<b>$section</b>").'</li>';          $result .= '<li>'.&mt('for section [_1]',"<b>$section</b>").'</li>';
Line 3543  sub render { Line 3922  sub render {
   
     # Print value      # Print value
     if ($vars->{ACTION_TYPE} ne 'tries' && $vars->{ACTION_TYPE} ne 'weight') {      if ($vars->{ACTION_TYPE} ne 'tries' && $vars->{ACTION_TYPE} ne 'weight') {
  $result .= '<li>'.&mt('to [_1] ([_2])',"<b>".ctime($vars->{PARM_DATE})."</b>",Apache::lonnavmaps::timeToHumanString($vars->{PARM_DATE}))."</li>\n";          my $showdate = &Apache::lonlocal::locallocaltime($vars->{PARM_DATE});
    $result .= '<li>'.&mt('to [_1] ([_2])',"<b>".$showdate."</b>",Apache::lonnavmaps::timeToHumanString($vars->{PARM_DATE}))."</li>\n";
     }      }
   
    $result .= '</ul>';
     
   # FIXME: Make previous button working
   #        Found to be dysfunctional when used to change the selected student
   #   my $previous = HTML::Entities::encode(&mt("Back"), '<>&"');
       my $buttons .= '<p><span class="LC_nobreak">'
   #                 .'<input name="back" type="button"'
   #                 .' value="'.$previous.'" onclick="history.go(-1)" />'
                     .' <input type="submit" value="'.&mt('Save').'" />' # Finish Helper
                     .'</span></p>'."\n";
   
     # print pres_marker      # print pres_marker
     $result .= "\n<input type='hidden' name='pres_marker'" .      $result .= "\n<input type='hidden' name='pres_marker'" .
         " value='$affectedResourceId&$parm_name&$level' />\n";          " value='$affectedResourceId&$parm_name&$level' />\n";
Line 3555  sub render { Line 3946  sub render {
     $result .= "\n<input type='hidden' value='$symb' name='pssymb' />";      $result .= "\n<input type='hidden' value='$symb' name='pssymb' />";
     $result .= "\n<input type='hidden' value='$paramlevel' name='parmlev' />";      $result .= "\n<input type='hidden' value='$paramlevel' name='parmlev' />";
   
     $result .= "<br /><br /><center><input type='submit' value='".&mt('Finish Helper')."' /></center></form>\n";      $result .= $buttons;
   
     return $result;      return $result;
 }  }

Removed from v.1.153  
changed lines
  Added in v.1.180.2.1


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