[LON-CAPA-cvs] cvs: loncom /interface lonhelper.pm

foxr lon-capa-cvs@mail.lon-capa.org
Fri, 05 May 2006 10:59:52 -0000


This is a MIME encoded message

--foxr1146826792
Content-Type: text/plain

foxr		Fri May  5 06:59:52 2006 EDT

  Modified files:              
    /loncom/interface	lonhelper.pm 
  Log:
  Revamped helper per Felicia's desires..still need some cleanup as follows:
  - Remove dead javascript
  - Restrict the (de)selections of the listboxes to the segment of the form
    they live in.
  - See if we can make the student picker code independent of the helper so
    non helper student pickers can use them..alternatively switch those over
    to helper.
  BUG 3809
  
  
--foxr1146826792
Content-Type: text/plain
Content-Disposition: attachment; filename="foxr-20060505065952.txt"

Index: loncom/interface/lonhelper.pm
diff -u loncom/interface/lonhelper.pm:1.138 loncom/interface/lonhelper.pm:1.139
--- loncom/interface/lonhelper.pm:1.138	Mon Apr 24 19:20:37 2006
+++ loncom/interface/lonhelper.pm	Fri May  5 06:59:51 2006
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # .helper XML handler to implement the LON-CAPA helper
 #
-# $Id: lonhelper.pm,v 1.138 2006/04/24 23:20:37 albertel Exp $
+# $Id: lonhelper.pm,v 1.139 2006/05/05 10:59:51 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -184,6 +184,7 @@
 use Apache::lonlocal;
 use Apache::lonnet;
 
+
 # Register all the tags with the helper, so the helper can 
 # push and pop them
 
@@ -2274,6 +2275,119 @@
 use Apache::lonlocal;
 use Apache::lonnet;
 
+#
+#  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:
+#     $sections    - Set of sections in the course (hash reference).
+#     $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.
+#  Returns:
+#     HTML  text to add to the rendering of the helper.
+#
+sub render_student_list {
+    my ($self,
+	$sections, $students, $formprefix, $defaultusers) = @_;
+
+    my $multiselect = $self->{'multichoice'};
+    my $result = "";
+
+    # 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) {
+	$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\")'".' /></td>';
+	$result .= '<td valign="top"><input type="button" name="'.$formprefix
+	    .'.unselect" value="Unselect"  onClick='.
+	    "'unselectSections(\"$formprefix.chosensections\")' ".' /></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="'.
+	    $self->{'variable'}.".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 (!$self->{'multichoice'} && !$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], "<>&\"'")
+	    ."\" /></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 {
     &Apache::lonhelper::register('Apache::lonhelper::student',
                               ('student'));
@@ -2322,6 +2436,99 @@
         $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 setAllStudents(value) {
+	var i;
+	var ele;
+	for (i =0; i < document.forms.helpform.elements.length; i++) {
+	    ele = document.forms.helpform.elements[i];
+	    if(isStudent(ele)) {
+		ele.checked=value;
+	    }
+	}
+    }
+    function setAllCoursePersonnel(value) {
+	var i;
+	var ele;
+	for (i =0; i < document.forms.helpform.elements.length; i++) {
+	    ele = document.forms.helpform.elements[i];
+	    if(!isStudent(ele)) {
+		ele.checked = value;
+	    }
+	}
+    }
+    function setSection(which, value) {
+	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) {
+		    ele.checked = value;
+		}
+	    }
+	}
+    }
+
+    function setCheckboxes(listbox, 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);
+		    } else if (what == 'All Course Personnel') {
+			setAllCoursePersonnel(value);
+		    } else if (what == 'No Section') {
+			setSection('',value);
+		    } else {
+			setSection(what, value);
+		    }
+		}
+	    }
+	}
+    }
+    function selectSections(listbox) {
+	setCheckboxes(listbox, true);
+
+    }
+    function unselectSections(listbox) {
+	setCheckboxes(listbox, false);
+    }
+    /* ----------------------------- */
+    
     function checkall(value, checkName) {
 	for (i=0; i<document.forms.helpform.elements.length; i++) {
             ele = document.forms.helpform.elements[i];
@@ -2422,9 +2629,9 @@
 </table>
 <br />
 BUTTONS
-    $result .= $buttons;   
+#    $result .= $buttons;   
 
-    }
+}
 
     if (defined $self->{ERROR_MSG}) {
         $result .= '<font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br /><br />';
@@ -2442,8 +2649,28 @@
 	%defaultUsers = map { if ($_) {($_,1) } } @defaultUsers;
 	delete($defaultUsers{''});
     }
-    my $choices = [];
-    my $expired_students = [];	# Will hold expired students.
+
+
+
+    # my $choices = [];
+
+    #
+    #  We need to parcel out the personel in to three arrays:
+    #   $current_members[] - Contains those whose roles are currently active.
+    #   $expired_members[] - Contains those whose roles have expired.
+    #   $future_members[]  - Contains those whose roles will become active in the
+    #                        future.
+    #
+    # Constants
+    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 $current_members = [];
+    my $expired_members = [];
+    my $future_members  = [];
+
 
     # Load up the non-students, if necessary
     if ($self->{'coursepersonnel'}) {
@@ -2460,16 +2687,12 @@
 		@people = sort { $a->[0] cmp $b->[0] } @people;
 		
 		for my $person (@people) {
-		    push @$choices, [join(':', @$person), $person->[0], '', $_];
+		    push @$current_members, [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();
@@ -2481,164 +2704,91 @@
         }
         return $classlist->{$a}->[$fullname] cmp $classlist->{$b}->[$fullname];
     } @keys;
-    #
-    #  now add the fancy section choice... first enumerate the sections:
-    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
-	# selection:
 
-	my $section_selectors =<<SECTIONSELECT;
-<table border="0">
-  <tr valign="top">
-   <td>For Sections:</td><td>$choice_widget</td>
-   <td><label><input type="radio" name="personstate" value="Active" checked />
-               Current Students</label></td>
-   <td><label><input type="radio" name="personstate" value="All" />
-               All students</label></td>
-   <td><label><input type="radio" name="personstate" value="Expired" />
-               Expired Students</label></td>
-  </tr>
-  <tr>
-   <td><input type="button" value="Select" onclick="checksections(true);" /></td>
-   <td><input type="button" value="Unselect" onclick="checksections(false);" /></td></tr>
-</table>
-<br />
-SECTIONSELECT
-         $result .= $section_selectors;
-    }
 
-    # username, fullname, section, type
     for (@keys) {
 
-	# We split the active students into the choices array and
-        # inactive ones into expired_students so that we can put them in 2 separate
-	# tables.
-
 	if ( $classlist->{$_}->[$status] eq
 	    'Active') {
-	    push @$choices, [$_, $classlist->{$_}->[$fullname], 
+	    push @$current_members, [$_, $classlist->{$_}->[$fullname], 
 			     $classlist->{$_}->[$section],
 			     $classlist->{$_}->[$status], 'Student'];
 	} else {
-	    push @$expired_students, [$_, $classlist->{$_}->[$fullname], 
-				      $classlist->{$_}->[$section],
-				      $classlist->{$_}->[$status], 'Student'];
+	    #  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"];
+	    }
+
 	}
     }
 
-    my $name = $self->{'coursepersonnel'} ? &mt('Name') : &mt('Student Name');
-    my $type = 'radio';
-    if ($self->{'multichoice'}) { $type = 'checkbox'; }
-    $result .= "<table cellspacing='2' cellpadding='2' border='0'>\n";
-    $result .= "<tr><td></td><td align='center'><b>$name</b></td>".
-        "<td align='center'><b>" . &mt('Section') . "</b></td>" . 
-	"<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;
+    # Create a list of the sections that can be used to create the section 
+    # selection list boxes:
     #
-    # Give the active students and staff:
-    #
-    for my $choice (@$choices) {
-        $result .= "<tr><td><input type='$type' name='" .
-            $self->{'variable'} . '.forminput' . "'";
-            
-	if (%defaultUsers) {
-	    my $user=$choice->[0];
-	    if (exists($defaultUsers{$user})) {
-		$result .= " checked='checked' ";
-		$checked = 1;
-	    }
-	} elsif (!$self->{'multichoice'} && !$checked) {
-            $result .= " checked='checked' ";
-            $checked = 1;
-        }
-        $result .=
-            " value='" . HTML::Entities::encode($choice->[0] . ':' 
-						.$choice->[2] . ':' 
-						.$choice->[1] . ':' 
-						.$choice->[3], "<>&\"'")
-            . "' /></td><td>"
-            . HTML::Entities::encode($choice->[1],'<>&"')
-            . "</td><td align='center'>" 
-            . HTML::Entities::encode($choice->[2],'<>&"')
-            . "</td>\n<td>" 
-	    . HTML::Entities::encode($choice->[3],'<>&"')
-            . "</td>\n<td>" 
-	    . HTML::Entities::encode($choice->[4],'<>&"')
-            . "</td>\n<td>" 
-	    . HTML::Entities::encode($choice->[0],'<>&"')
-	    . "</td></tr>\n";
+    my %sections;
+    for my $key (@keys) {
+	my $section_name = $classlist->{$key}->[$section];
+	if ($section_name ne "") {
+	    $sections{$section_name} = 1;
+	}
     }
-    $result .= "</table>\n\n";
+
+
+    if ($self->{'multichoice'}) {
+
+	#  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 $result = '<select multiple name="chosensections" size="'.$size.'">'."\n";
+	foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
+	    $result .= "<option name=\"$sec\">$sec</option>\n";
+	}
+	$result .= "<option>none</option></select>\n";
+
+
+    }
+
+    #   Current personel
+
+    $result .= $self->render_student_list(\%sections,
+					  $current_members,
+					  "current",
+					  \%defaultUsers);
+
 
     # If activeonly is not set then we can also give the expired students:
     #
-    if (!$self->{'activeonly'} && ((scalar @$expired_students) > 0)) {
-	$result .= "<p>Inactive students: </p>\n";
-	$result .= <<INACTIVEBUTTONS;
-	   <table>
-              <tr>
-                 <td><input type="button" value="Select expired" onclick="checkexpired();" /> </td>
-		 <td><input type="button" value="Unselect expired" onclick="uncheckexpired();" /></td>
-              </tr>
-           </table>
-INACTIVEBUTTONS
-	$result .= "<table>\n";
-
-	for my $choice (@$expired_students) {
-        $result .= "<tr><td><input type='$type' name='" .
-            $self->{'variable'} . '.forminput' . "'";
-            
-	if (%defaultUsers) {
-	    my $user=$choice->[0];
-	    if (exists($defaultUsers{$user})) {
-		$result .= " checked='checked' ";
-		$checked = 1;
-	    }
-	} elsif (!$self->{'multichoice'} && !$checked) {
-            $result .= " checked='checked' ";
-            $checked = 1;
-        }
-        $result .=
-            " value='" . HTML::Entities::encode($choice->[0] . ':' 
-						.$choice->[2] . ':' 
-						.$choice->[1] . ':' 
-						.$choice->[3], "<>&\"'")
-            . "' /></td><td>"
-            . HTML::Entities::encode($choice->[1],'<>&"')
-            . "</td><td align='center'>" 
-            . HTML::Entities::encode($choice->[2],'<>&"')
-            . "</td>\n<td>" 
-	    . HTML::Entities::encode($choice->[3],'<>&"')
-            . "</td>\n<td>" 
-	    . HTML::Entities::encode($choice->[4],'<>&"')
-            . "</td>\n<td>" 
-	    . HTML::Entities::encode($choice->[0],'<>&"')
-	    . "</td></tr>\n";	    
-	}
-	$result .= "</table>\n";
-	
+    if (!$self->{'activeonly'} && ((scalar @$expired_members) > 0)) {
+
+	# Past 
+
+	$result .= $self->render_student_list(\%sections,
+					      $expired_members,
+					      "past",
+					      \%defaultUsers);
+
+	# And future.
+
+	$result .= $self->render_student_list(\%sections,
+					      $future_members,
+					      "future",
+					      \%defaultUsers);
     }
 
 

--foxr1146826792--