Diff for /loncom/interface/lonhelper.pm between versions 1.120 and 1.147

version 1.120, 2005/10/11 21:27:44 version 1.147, 2006/05/09 22:43:19
Line 184  use Apache::lonxml; Line 184  use Apache::lonxml;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   
   
 # 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 573  sub display { Line 574  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 $browser_searcher_js = 
     my $bodytag = &Apache::loncommon::bodytag($helperTitle,'','');   '<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'>"; }
     $result .= <<HEADER;      $result .= <<HEADER;
         <table border="0" width='100%'><tr><td>          <table border="0" width='100%'><tr><td>
Line 651  HEADER Line 650  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 1072  will be the state transistioned to if th Line 1070  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 1170  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 1275  BUTTONS Line 1285  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";              $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 1316  sub postprocess { Line 1332  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 1559  sub render { Line 1579  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);
       }
   
       &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)\"";
     }      }
     # 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 1661  sub render { Line 1703  sub render {
         $result .= "</select>\n";          $result .= "</select>\n";
     }      }
     if ($self->{'anytime'}) {      if ($self->{'anytime'}) {
     $result.=(<<CHECK);   $result.=(<<CHECK);
 <script type="text/javascript">  <script type="text/javascript">
 // <!--  // <!--
     function updateCheck(form,name,value) {      function updateCheck(form,name,value) {
Line 1671  sub render { Line 1713  sub render {
 // -->  // -->
 </script>  </script>
 CHECK  CHECK
   
  $result.="&nbsp;or&nbsp;<label><input type='checkbox' ";   $result.="&nbsp;or&nbsp;<label><input type='checkbox' ";
  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 1723  sub postprocess { Line 1764  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 2018  BUTTONS Line 2069  BUTTONS
  $mapUrl = $self->{MAP_URL};   $mapUrl = $self->{MAP_URL};
     }      }
   
       my %defaultSymbs;
       if (defined($self->{DEFAULT_VALUE})) {
           my $valueFunc = eval($self->{DEFAULT_VALUE});
           die 'Error in default value code for variable ' . 
               $self->{'variable'} . ', Perl said: ' . $@ if $@;
           my @defaultSymbs = &$valueFunc($helper, $self);
    if (!$multichoice && @defaultSymbs) { # only allowed 1
       @defaultSymbs = ($defaultSymbs[0]);
    }
    %defaultSymbs = map { if ($_) {($_,1) } } @defaultSymbs;
    delete($defaultSymbs{''});
       }
   
     # Create the composite function that renders the column on the nav map      # Create the composite function that renders the column on the nav map
     # have to admit any language that lets me do this can't be all bad      # have to admit any language that lets me do this can't be all bad
Line 2066  BUTTONS Line 2129  BUTTONS
     }      }
   
             $col .= "<td align='center'><input type='$inputType' name='${var}.forminput' ";              $col .= "<td align='center'><input type='$inputType' name='${var}.forminput' ";
             if (!$checked && !$multichoice) {      if (%defaultSymbs) {
                 $col .= "checked='checked' ";   my $symb=$resource->symb();
                 $checked = 1;   if (exists($defaultSymbs{$symb})) {
             }      $col .= "checked='checked' ";
     if ($multichoice) { # all resources start checked; see bug 1174      $checked = 1;
  $col .= "checked='checked' ";   }
  $checked = 1;      } else {
    if (!$checked && !$multichoice) {
       $col .= "checked='checked' ";
       $checked = 1;
    }
    if ($multichoice) { # all resources start checked; see bug 1174
       $col .= "checked='checked' ";
       $checked = 1;
    }
     }      }
             $col .= "value='" . $resource_name  . "' /></td>";              $col .= "value='" . $resource_name  . "' /></td>";
   
Line 2190  selection. Defaults to false. Line 2261  selection. Defaults to false.
 If true, only active students and course personnel will be  If true, only active students and course personnel will be
 shown. Defaults to false.  shown. Defaults to false.
   
   =item * B<emptyallowed>:
   
   If true, the selection of no users is allowed. Defaults to false.
   
 =back  =back
   
 =cut  =cut
Line 2199  no strict; Line 2274  no strict;
 use strict;  use strict;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   #
   #  Utility function used when rendering <student> tags.
   #  This function produces a list references to four
   #  arrays:
   #    (\@course_personel, \@current_members, \@expired_members, \@future_members)
   #  
   # Where:
   #    course_personnel - Each element of this array is itself a reference to an array
   #                      containing information about a member of the course staff.
   #    current_members  - Each element of this array is itself a reference to an
   #                       array that contains information about current students in
   #                       the course.
   #    expired_members  - Each element of this array is itself a reference to an
   #                       array that contains information about students whose 
   #                       status has expired.
   #    future_members   - Each element of this arrya is itself a reference to an
   #                       array that contains information about students who will
   #                       become active at a future date.
   #
   #  Course personnel elements include:
   #       [0]    Last, First of the user.
   #       [1]    Role held by the user.
   #       [2]    Empty.
   #       [3]    Empty
   #       [4]    username:domain of the user.
   #
   #  Student member array elements are:
   #       [0]    Last, First of the user.
   #       [1]    Status of the user one of ("Active", "Future", or "Expired')
   #              depending on which array the user was put in.
   #       [2]    Section the student is in.
   #       [3]    Role of the member (student).
   #       [4]    username:domain of the user.
   #
   sub get_people_in_class {
       my %coursepersonnel = &Apache::lonnet::get_course_adv_roles();
       #
       #  Enumerate the course_personnel.
       #
       my @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 @course_personnel, [join(':', @$person), $person->[0], '', $_];
       }
    }
       }
       #  Students must be split into the three categories:
   
       my @current_members;
       my @future_members;
       my @expired_members;
   
       #   Indices into the coures data elements.
   
       my $section    = &Apache::loncoursedata::CL_SECTION();
       my $fullname   = &Apache::loncoursedata::CL_FULLNAME();
       my $status     = &Apache::loncoursedata::CL_STATUS();
       my $start_date = &Apache::loncoursedata::CL_START();
   
   
       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;
    
   
   
   
       for (@keys) {
   
    if ( $classlist->{$_}->[$status] eq
       'Active') {
       push @current_members, [$_, $classlist->{$_}->[$fullname], 
        $classlist->{$_}->[$section],
        $classlist->{$_}->[$status], 'Student'];
    } else {
       #  Need to figure out if this user is future or
       #  Expired... If the start date is in the future
       #  the user is future...else expired.
       
       my $now = time;
       if ($classlist->{$_}->[$start_date] > $now) {
    push @future_members, [$_, $classlist->{$_}->[$fullname],
    $classlist->{$_}->[$section],
    "Future", "Student"];
       } else {
    push @expired_members, [$_, $classlist->{$_}->[$fullname],
    $classlist->{$_}->[$section],
    "Expired", "Student"];
       }
   
    }
       }
       return (\@course_personnel, 
       \@current_members,
       \@expired_members,
       \@future_members);
   
   }
   
   #
   #  Utility function used when rendering the <student> tag.
   #  This function renders a segment of course personel
   #  Personel are broken up by the helper into past, current and
   #  future...each one gets is own subpage of selection.
   #  This sub renders one of these pages.
   #  Parameters:
   #     $students    - Students in the section. (ref to array of references
   #                    to arrays).
   #     $formprefix  - form path prefix for form element names
   #                    This is used to make each form element
   #                    so that the segments having to do with each
   #                    set of students won't collide.
   #     $defaultusers - reference to a hash containng
   #                     the set of users that should be on or off.
   #     $multiselect  - True if multiselect allowed.
   #     $resultname   - Name of result variable.
   #     $javascript   - If true, the javascript to run this is output
   #                     This should be true for the first call for a page
   #                     and false for all other calls... only matters if
   #                     multiselect is true.
   #  Returns:
   #     HTML  text to add to the rendering of the helper.
   #
   sub render_student_list {
       my ($students, $formprefix, $defaultusers,
    $multiselect, $resultname, $javascript) = @_;
   
       my $result = "";
   
       if ($javascript && $multiselect) {
           $result .= <<SCRIPT;
   <script type="text/javascript">
   // <!--
   
       function findElement(name) {
    var i;
    var ele;
    for(i =0; i < document.forms.helpform.elements.length; i++) {
       ele = document.forms.helpform.elements[i];
       if(ele.name == name) {
    return ele;
       }
    }
    return null;
       }
       function isStudent(element) {
    if(element.value.indexOf(":Student") != -1) {
       return 1;
    }
    return 0;
       }
       function section(element) {
    var i;
    var info;
    if (element.value.indexOf(':') != -1) {
       info = element.value.split(':');
       return info[2];
    } else {
       return "";
    }
       }
       function rightSubForm(element, which) {
    if (element.value.indexOf(which) != -1) {
       return true;
    } else {
       return false;
    }
       }
   
       function setAllStudents(value, which) {
    var i;
    var ele;
    for (i =0; i < document.forms.helpform.elements.length; i++) {
       ele = document.forms.helpform.elements[i];
       if(isStudent(ele) && rightSubForm(ele, which)) {
    ele.checked=value;
       }
    }
       }
       function setAllCoursePersonnel(value, which) {
    var i;
    var ele;
    for (i =0; i < document.forms.helpform.elements.length; i++) {
       ele = document.forms.helpform.elements[i];
       if(!isStudent(ele) && rightSubForm(ele, which)) {
    ele.checked = value;
       }
    }
       }
       function setSection(which, value, subform) {
    var i;
    var ele;
    for (i =0; i < document.forms.helpform.elements.length; i++) {
       ele = document.forms.helpform.elements[i];
       if (ele.value.indexOf(':') != -1) {
    if ((section(ele) == which) && rightSubForm(ele, subform)) {
       ele.checked = value;
    }
       }
    }
       }
   
       function setCheckboxes(listbox, which, value) {
    var k;
    var elem;
    var what;
           elem = findElement(listbox);
    if (elem != null) {
       for (k = 0; k < elem.length; k++) {
    if (elem.options[k].selected) {
       what = elem.options[k].text;
       if (what == 'All Students') {
    setAllStudents(value, which);
       } else if (what == 'All Course Personnel') {
    setAllCoursePersonnel(value, which);
       } else if (what == 'No Section') {
    setSection('',value, which);
       } else {
    setSection(what, value, which);
       }
    }
       }
    }
       }
       function selectSections(listbox, which) {
    setCheckboxes(listbox, which, true);
   
       }
       function unselectSections(listbox, which) {
    setCheckboxes(listbox, which, false);
       }
   
   // -->
   </script>
   SCRIPT
   
       }
   
       # If multiple selections are allowed, we have a listbox
       # at the top which allows quick selections from each section
       # as well as from categories of personnel.
   
       if ($multiselect) {
    #  Make a section hash so we can add sections to the choice:
   
    my %sections;
    for my $student (@$students) {
       my $sect = $student->[2];
       if ($sect ne "") {
    $sections{$sect} = 1;
       }
    }
   
    $result .= '<table><tr><td>';
   
    my $size = scalar(keys(%sections));
    $size += 3; # We have allstudents allpersonel nosection too.
    if ($size > 5) { 
       $size = 5; 
    }
    $result .= '<select multiple name="'.$formprefix
       .'.chosensections" size="'.$size.'">'."\n";
    $result .= '<option name="allstudents">All Students</option>';
    $result .= '<option name="allpersonnel">All Course Personnel</option>';
    $result .= '<option name="nosection">No Section</option>';
    $result .= "\n";
    foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
       $result .= '<option name="'.$sec.'">'.$sec.'</option>'."\n";
    }
    $result .= '</td><td valign="top">';
    $result .= '<input type="button" name="'.$formprefix.'.select" value="Select" onclick='
       ."'selectSections(\"$formprefix.chosensections\", \"$formprefix\")'".' /></td>';
    $result .= '<td valign="top"><input type="button" name="'.$formprefix
       .'.unselect" value="Unselect"  onclick='.
       "'unselectSections(\"$formprefix.chosensections\", \"$formprefix\")' ".' /></td></tr></table>';
       }
   
       #  Now we list the students, but the form element type
       #  will depend on whether or not multiselect is true.
       #  True -> checkboxes.
       #  False -> radiobuttons.
   
       $result .= "<table border=\"2\">\n";
       $result .= '<tr><th></th><th align="center">Name</th>'."\n";
       $result .= '    <th align="center">Section</th>'."\n";
       $result .= '    <th align="center">Status</th>'."\n";
       $result .= '    <th align="center">Role</th>'."\n";
       $result .= '    <th align="center">Username : Domain</th></tr>'."\n";
   
       my $input_type;
       if ($multiselect) {
    $input_type = "checkbox";
       } else {
    $input_type = "radio";
       }
   
       my $checked = 0;
       for my $student (@$students) {
    $result .= '<tr><td><input type="'.$input_type.'"  name="'.
       $resultname.".forminput".'"';
    my $user    = $student->[0];
   
    # Figure out which students are checked by default...
   
    if(%$defaultusers) {
       if (exists ($defaultusers->{$user})) {
    $result .= ' checked ="checked" ';
    $checked = 1;
       }
    } elsif (!$multiselect  && !$checked) {
       $result .= ' checked="checked" ';
       $checked = 1; # First one for radio if no default specified.
    }
    $result .= ' value="'. HTML::Entities::encode($user .          ':'
         .$student->[2] . ':'
         .$student->[1] . ':'
         .$student->[3] . ':'
         .$student->[4] . ":"
         .$formprefix,   "<>&\"'")
       ."\" /></td><td>\n";
    $result .= HTML::Entities::encode($student->[1], '<>&"')
           . '</td><td align="center" >'."\n";
    $result .= HTML::Entities::encode($student->[2], '<>&"')
              . '</td><td align="center">'."\n";
    $result .= HTML::Entities::encode($student->[3], '<>&"')
           . '</td><td align="center">'."\n";
    $result .= HTML::Entities::encode($student->[4], '<>&"')
            . '</td><td align="center">'."\n";
    $result .= HTML::Entities::encode($student->[0], '<>&"')
           . '</td></tr>'."\n";
       }
       $result .=" </table> <br /> <hr />\n";
   
       return $result;
   }
   
 BEGIN {  BEGIN {
     &Apache::lonhelper::register('Apache::lonhelper::student',      &Apache::lonhelper::register('Apache::lonhelper::student',
Line 2225  sub start_student { Line 2651  sub start_student {
     if (defined($token->[2]{'nextstate'})) {      if (defined($token->[2]{'nextstate'})) {
         $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};          $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'};
     }      }
       $paramHash->{'emptyallowed'} = $token->[2]{'emptyallowed'};
           
 }      }    
   
Line 2243  sub render { Line 2670  sub render {
     my $buttons = '';      my $buttons = '';
     my $var = $self->{'variable'};      my $var = $self->{'variable'};
   
     if ($self->{'multichoice'}) {  
         $result = <<SCRIPT;      if (defined $self->{ERROR_MSG}) {
 <script type="text/javascript">          $result .= '<font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br /><br />';
 // <!--  
     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.      my %defaultUsers;
         numSections  = document.forms.helpform.chosensections.length;      if (defined($self->{DEFAULT_VALUE})) {
  desiredState = getDesiredState();          my $valueFunc = eval($self->{DEFAULT_VALUE});
           die 'Error in default value code for variable ' . 
  for (var option = 0; option < numSections; option++) {              $self->{'variable'} . ', Perl said: ' . $@ if $@;
     if(document.forms.helpform.chosensections.options[option].selected) {          my @defaultUsers = &$valueFunc($helper, $self);
  section = document.forms.helpform.chosensections.options[option].text;   if (!$self->{'multichoice'} && @defaultUsers) { # only allowed 1
  if (section == "none") {      @defaultUsers = ($defaultUsers[0]);
     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;  
     }  
  }  
     }  
  }  
             }  
  }   }
    }   %defaultUsers = map { if ($_) {($_,1) } } @defaultUsers;
 // -->   delete($defaultUsers{''});
 </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}) {  
         $result .= '<font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br /><br />';  
     }  
   
     my $choices = [];      my ($course_personnel, 
    $current_members, 
    $expired_members, 
    $future_members) = &get_people_in_class();
   
   
   
     # 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  
     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      #   Current personel
     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 .= &render_student_list( $current_members,
     my $type = 'radio';       "current",
     if ($self->{'multichoice'}) { $type = 'checkbox'; }       \%defaultUsers,
     $result .= "<table cellspacing='2' cellpadding='2' border='0'>\n";       $self->{'multichoice'},
     $result .= "<tr><td></td><td align='center'><b>$name</b></td>".       $self->{'variable'},
         "<td align='center'><b>" . &mt('Section') . "</b></td>" .        1);
  "<td align='center'><b>".&mt('Status')."</b></td>" .   
  "<td align='center'><b>" . &mt("Role") . "</b></td>" .  
  "<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 (!$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 @$expired_members) > 0)) {
     if ($self->{'multichoice'}) {  
  my %sections;  
  for my $key (@keys) {  
     my $section_name = $classlist->{$key}->[$section];  
     if ($section_name ne "") {  
  $sections{$section_name} = 1;  
     }  
  }  
  #  The variable $choice_widget will have the html to make the choice   
  #  selector.  
  my $size=5;  
  if (scalar(keys(%sections)) < 5) {  
     $size=scalar(keys(%sections));  
  }  
  my $choice_widget = '<select multiple name="chosensections" size="'.$size.'">'."\n";  
  foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {  
     $choice_widget .= "<option name=\"$sec\">$sec</option>\n";  
  }  
  $choice_widget .= "<option>none</option></select>\n";  
   
  # Build a table without any borders to contain the section based   # And future.
  # selection:  
   
  my $section_selectors =<<SECTIONSELECT;   $result .= &render_student_list( $future_members,
 <table border="0">   "future",
   <tr valign="top">   \%defaultUsers,
    <td>For Sections:</td><td>$choice_widget</td>   $self->{'multichoice'},
    <td><label><input type="radio" name="personstate" value="Active" checked />   $self->{'variable'},
                Current Students</label></td>   0);
    <td><label><input type="radio" name="personstate" value="All" />   # Past 
                All students</label></td>  
    <td><label><input type="radio" name="personstate" value="Expired" />   $result .= &render_student_list($expired_members,
                Expired Students</label></td>   "past",
   </tr>   \%defaultUsers,
   <tr>   $self->{'multichoice'},
    <td><input type="button" value="Select" onclick="checksections(true);" /></td>   $self->{'variable'},
    <td><input type="button" value="Unselect" onclick="checksections(false);" /></td></tr>   0);
 </table>  
 <br />  
 SECTIONSELECT  
          $result .= $section_selectors;  
     }      }
   
   
   
     return $result;      return $result;
 }  }
   
Line 2486  sub postprocess { Line 2744  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->{'emptyallowed'}) {
         $self->{ERROR_MSG} =    if ($self->{'coursepersonnel'}) {
     &mt('You must choose at least one student to continue.');      $self->{ERROR_MSG} = 
    &mt('You must choose at least one user to continue.');
    } else {
       $self->{ERROR_MSG} = 
    &mt('You must choose at least one student to continue.');
    }
         return 0;          return 0;
     }      }
   
Line 2868  package Apache::lonhelper::section; Line 3131  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 2899  sub start_section { Line 3166  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 2908  sub start_section { Line 3176  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::loncommon::coursegroups();
       foreach my $group_name (sort(keys(%curr_groups))) {
    push(@{$paramHash->{CHOICES}}, [$group_name, $group_name]);
     }      }
 }      }    
   
Line 2933  sub end_section { Line 3212  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::loncommon::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 3026  sub postprocess { Line 3369  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 3314  sub render { Line 3657  sub render {
     }      }
     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 ->"), '<>&"');
       my $target = " target='loncapaclient'";
       if (($env{'browser.interface'} eq 'textual') ||
           ($env{'environment.remote'} eq 'off')) {  $target='';  }
     $result .= "<center>\n" .      $result .= "<center>\n" .
  "<form action='".$actionURL."' method='post' target='loncapaclient'>\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" .
Line 3516  sub render { Line 3862  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.120  
changed lines
  Added in v.1.147


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