File:  [LON-CAPA] / loncom / interface / lonselstudent.pm
Revision 1.14: download - view: text, annotated - select for diffs
Thu Jan 15 18:23:27 2009 UTC (15 years, 3 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, bz6209-base, bz6209, bz5969, bz2851, PRINT_INCOMPLETE_base, PRINT_INCOMPLETE, HEAD, GCI_3, GCI_2, GCI_1, BZ5971-printing-apage, BZ5434-fox, BZ4492-merge, BZ4492-feature_horizontal_radioresponse
- Pass form object along as an additional argument to the following javascript functions:
setAllStudents(), setAllCoursePersonnel(), setSection(), setCheckboxes(), findElement()

can now support cases (e.g., in lonmsgdisplay.pm) where selections for active, previous and future users occur in different forms, but the <script> block containing these functions is only sent once (e.g., for active form), but is used in all three cases (three different forms).
- xhtml multiple="multiple"

    1: # The LearningOnline Network with CAPA
    2: # lonselstudent.pm : Reusable subs for student selection.
    3: #
    4: # $Id: lonselstudent.pm,v 1.14 2009/01/15 18:23:27 raeburn Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: 
   29: package Apache::lonselstudent;
   30: use     Apache::lonnet;
   31: use     Apache::lonlocal;
   32: use     Apache::loncoursedata();
   33: use     HTML::Entities();
   34: 
   35: #
   36: #  Utility function used when rendering <student> tags.
   37: #  This function produces a list references to four
   38: #  arrays:
   39: #    (\@course_personel, \@current_members, \@expired_members, \@future_members)
   40: #
   41: #
   42: # Parameters;
   43: #
   44: #  restrict           - Optional.. if present and defined should be a section name.
   45: #                       The *_members arrays will then only contain people
   46: #                       in that section
   47: #
   48: # Where:
   49: #    course_personnel - Each element of this array is itself a reference to an array
   50: #                      containing information about a member of the course staff.
   51: #    current_members  - Each element of this array is itself a reference to an
   52: #                       array that contains information about current students in
   53: #                       the course.
   54: #    expired_members  - Each element of this array is itself a reference to an
   55: #                       array that contains information about students whose 
   56: #                       status has expired.
   57: #    future_members   - Each element of this arrya is itself a reference to an
   58: #                       array that contains information about students who will
   59: #                       become active at a future date.
   60: #
   61: #  Course personnel elements include:
   62: #       [0]    Last, First of the user.
   63: #       [1]    Role held by the user.
   64: #       [2]    Empty.
   65: #       [3]    Empty
   66: #       [4]    username:domain of the user.
   67: #
   68: #  Student member array elements are:
   69: #       [0]    Last, First of the user.
   70: #       [1]    Status of the user one of ("Active", "Future", or "Expired')
   71: #              depending on which array the user was put in.
   72: #       [2]    Section the student is in.
   73: #       [3]    Role of the member (student).
   74: #       [4]    username:domain of the user.
   75: #
   76: sub get_people_in_class {
   77:     my ($section_restriction) = @_;
   78:     my %coursepersonnel = &Apache::lonnet::get_course_adv_roles();
   79:     #
   80:     #  Enumerate the course_personnel.
   81:     #
   82:     my @course_personnel;
   83:     for my $role (sort(keys(%coursepersonnel))) {
   84: 	# extract the names so we can sort them
   85: 	my @people;
   86: 	for my $person (split(/,/, $coursepersonnel{$role})) {
   87: 	    my ($uname,$domain) = split(/:/, $person);
   88: 	    push(@people, [&Apache::loncommon::plainname($uname,$domain),
   89: 			   $uname,$domain]);
   90: 	}
   91: 	@people = sort { $a->[0] cmp $b->[0] } (@people);
   92: 	    
   93: 	for my $person (@people) {
   94: 	    push(@course_personnel, [join(':', $person->[1],$person->[2]), 
   95: 				     $person->[0], '', '', $role]);
   96: 	}
   97:     }
   98:     #  Students must be split into the three categories:
   99: 
  100:     my @current_members;
  101:     my @future_members;
  102:     my @expired_members;
  103: 
  104:     #   Indices into the coures data elements.
  105: 
  106:     my $section    = &Apache::loncoursedata::CL_SECTION();
  107:     my $fullname   = &Apache::loncoursedata::CL_FULLNAME();
  108:     my $status     = &Apache::loncoursedata::CL_STATUS();
  109:     my $start_date = &Apache::loncoursedata::CL_START();
  110: 
  111: 
  112:     my $classlist = &Apache::loncoursedata::get_classlist();
  113:     my @keys = keys(%{$classlist});
  114:     # Sort by: fullname, username
  115:     @keys = sort {
  116: 	lc($classlist->{$a}[$fullname]) cmp lc($classlist->{$b}[$fullname]) ||
  117: 	lc($a) cmp lc($b)
  118:     } (@keys);
  119:  
  120: 
  121: 
  122: 
  123:     for my $user (@keys) {
  124: 	if (!$section_restriction || 
  125: 	    ($section_restriction eq $classlist->{$user}->[$section])) {
  126: 	    
  127: 	    if ( $classlist->{$user}->[$status] eq
  128: 		 'Active') {
  129: 		push(@current_members, [$user, $classlist->{$user}->[$fullname], 
  130: 					$classlist->{$user}->[$section],
  131: 					$classlist->{$user}->[$status], 'Student']);
  132: 	    } else {
  133: 		#  Need to figure out if this user is future or
  134: 		#  Expired... If the start date is in the future
  135: 		#  the user is future...else expired.
  136: 		
  137: 		my $now = time;
  138: 		if ($classlist->{$user}->[$start_date] > $now) {
  139: 		    push(@future_members, [$user, $classlist->{$user}->[$fullname],
  140: 					   $classlist->{$user}->[$section],
  141: 					   "Future", "Student"]);
  142: 		} else {
  143: 		    push(@expired_members, [$user,
  144: 					    $classlist->{$user}->[$fullname],
  145: 					    $classlist->{$user}->[$section],
  146: 					    "Expired", "Student"]);
  147: 		}
  148: 		
  149: 	    }
  150: 	}
  151:     }
  152:     return (\@course_personnel, 
  153: 	    \@current_members,
  154: 	    \@expired_members,
  155: 	    \@future_members);
  156: 
  157: }
  158: 
  159: #
  160: #  Utility function used when rendering the <student> tag.
  161: #  This function renders a segment of course personel
  162: #  Personel are broken up by the helper into past, current and
  163: #  future...each one gets is own subpage of selection.
  164: #  This sub renders one of these pages.
  165: #  Parameters:
  166: #     $students    - Students in the section. (ref to array of references
  167: #                    to arrays).
  168: #     $formname    - Name of the form in which this stuff gets rendered.
  169: #     $formprefix  - form path prefix for form element names
  170: #                    This is used to make each form element
  171: #                    so that the segments having to do with each
  172: #                    set of students won't collide.
  173: #     $defaultusers - reference to a hash containng
  174: #                     the set of users that should be on or off.
  175: #     $multiselect  - True if multiselect allowed.
  176: #     $resultname   - Name of result variable.
  177: #     $javascript   - If true, the javascript to run this is output
  178: #                     This should be true for the first call for a page
  179: #                     and false for all other calls... only matters if
  180: #                     multiselect is true.
  181: #     $context      - If email, do not include <br /><hr /> tags at the end
  182: #                     of the data table. 
  183: #  Returns:
  184: #     HTML  text to add to the rendering of the helper.
  185: #
  186: sub render_student_list {
  187:     my ($students, $formname, $formprefix, $defaultusers,
  188: 	$multiselect, $resultname, $javascript, $context) = @_;
  189: 
  190:     my $result = "";
  191: 
  192:     # no students so no output
  193:     return if (!@$students);
  194: 
  195:     if ($javascript && $multiselect) {
  196:         $result .= <<SCRIPT;
  197: <script type="text/javascript">
  198: // <!--
  199: 
  200:     function findElement(name,formname) {
  201: 	var i;
  202: 	var ele;
  203: 	for(i =0; i < formname.elements.length; i++) {
  204: 	    ele = formname.elements[i];
  205: 	    if(ele.name == name) {
  206: 		return ele;
  207: 	    }
  208: 	}
  209: 	return null;
  210:     }
  211:     function isStudent(element) {
  212: 	if(element.value.indexOf(":Student") != -1) {
  213: 	    return 1;
  214: 	}
  215: 	return 0;
  216:     }
  217:     function section(element) {
  218: 	var i;
  219: 	var info;
  220: 	if (element.value.indexOf(':') != -1) {
  221: 	    info = element.value.split(':');
  222: 	    return info[2];
  223: 	} else {
  224: 	    return "";
  225: 	}
  226:     }
  227:     function rightSubForm(element, which) {
  228: 	if (element.value.indexOf(which) != -1) {
  229: 	    return true;
  230: 	} else {
  231: 	    return false;
  232: 	}
  233:     }
  234: 
  235:     function setAllStudents(value, which, formname) {
  236: 	var i;
  237: 	var ele;
  238: 	for (i =0; i < formname.elements.length; i++) {
  239: 	    ele = formname.elements[i];
  240: 	    if(isStudent(ele) && rightSubForm(ele, which)) {
  241: 		ele.checked=value;
  242: 	    }
  243: 	}
  244:     }
  245:     function setAllCoursePersonnel(value, which, formname) {
  246: 	var i;
  247: 	var ele;
  248: 	for (i =0; i < formname.elements.length; i++) {
  249: 	    ele = formname.elements[i];
  250: 	    if(!isStudent(ele) && rightSubForm(ele, which)) {
  251: 		ele.checked = value;
  252: 	    }
  253: 	}
  254:     }
  255:     function setSection(which, value, subform, formname) {
  256: 	var i;
  257: 	var ele;
  258: 	for (i =0; i < formname.elements.length; i++) {
  259: 	    ele = formname.elements[i];
  260: 	    if (ele.value.indexOf(':') != -1) {
  261: 		if ((section(ele) == which) && rightSubForm(ele, subform)) {
  262: 		    ele.checked = value;
  263: 		}
  264: 	    }
  265: 	}
  266:     }
  267: 
  268:     function setCheckboxes(listbox, which, value, formname) {
  269: 	var k;
  270: 	var elem;
  271: 	var what;
  272:         elem = findElement(listbox, formname);
  273: 	if (elem != null) {
  274: 	    for (k = 0; k < elem.length; k++) {
  275: 		if (elem.options[k].selected) {
  276: 		    what = elem.options[k].value;
  277: 		    if (what == 'allstudents') {
  278: 			setAllStudents(value, which, formname);
  279: 		    } else if (what == 'allpersonnel') {
  280: 			setAllCoursePersonnel(value, which, formname);
  281: 		    } else if (what == 'nosection') {
  282: 			setSection('',value, which, formname);
  283: 		    } else {
  284: 			setSection(what, value, which, formname);
  285: 		    }
  286: 		}
  287: 	    }
  288: 	}
  289:     }
  290:     function selectSections(listbox, which, formname) {
  291: 	setCheckboxes(listbox, which, true, formname);
  292: 
  293:     }
  294:     function unselectSections(listbox, which, formname) {
  295: 	setCheckboxes(listbox, which, false, formname);
  296:     }
  297: 
  298: // -->
  299: </script>
  300: SCRIPT
  301: 
  302:     }
  303: 
  304:     # If multiple selections are allowed, we have a listbox
  305:     # at the top which allows quick selections from each section
  306:     # as well as from categories of personnel.
  307: 
  308:     if ($multiselect) {
  309: 	#  Make a section hash so we can add sections to the choice:
  310: 
  311: 	my %sections;
  312: 	for my $student (@$students) {
  313: 	    my $sect = $student->[2];
  314: 	    if ($sect ne "") {
  315: 		$sections{$sect} = 1;
  316: 	    }
  317: 	}
  318: 
  319: 	$result .= '<table><tr><td>';
  320: 
  321: 	my $size = scalar(keys(%sections));
  322: 	$size += 3;		# We have allstudents allpersonel nosection too.
  323: 	if ($size > 5) { 
  324: 	    $size = 5; 
  325: 	}
  326: 	$result .= '<select multiple="multiple" name="'.$formprefix
  327: 	    .'.chosensections" size="'.$size.'">'."\n";
  328: 	$result .= '<option value="allstudents">'.&mt('All Students').'</option>';
  329: 	$result .= '<option value="allpersonnel">'.&mt('All Course Personnel').'</option>';
  330: 	$result .= '<option value="nosection">'.&mt('No Section').'</option>';
  331: 	$result .= "\n";
  332: 	foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
  333: 	    $result .= '<option name="'.$sec.'">'.$sec.'</option>'."\n";
  334: 	}
  335: 	$result .= '</select></td><td valign="top">';
  336: 	$result .= '<input type="button" name="'.$formprefix.'.select" value="'.&mt('Select').'" onclick='
  337: 	    ."'selectSections(\"$formprefix.chosensections\", \"$formprefix\", document.forms.$formname)'".' /></td>';
  338: 	$result .= '<td valign="top"><input type="button" name="'.$formprefix
  339: 	    .'.unselect" value="'.&mt('Unselect').'"  onclick='.
  340: 	    "'unselectSections(\"$formprefix.chosensections\", \"$formprefix\", document.forms.$formname)' ".' /></td></tr></table>';
  341:     }
  342: 
  343:     #  Now we list the students, but the form element type
  344:     #  will depend on whether or not multiselect is true.
  345:     #  True -> checkboxes.
  346:     #  False -> radiobuttons.
  347: 
  348:     $result .= &Apache::loncommon::start_data_table();
  349:     $result .= &Apache::loncommon::start_data_table_header_row();
  350:     $result .= '<th></th><th>'.&mt('Name').'</th>'."\n";
  351:     $result .= '    <th>'.&mt('Section').'</th>'."\n";
  352:     $result .= '    <th>'.&mt('Status').'</th>'."\n";
  353:     $result .= '    <th>'.&mt('Role').'</th>'."\n";
  354:     $result .= '    <th>'.&mt('Username : Domain').'</th>'."\n";
  355:     $result .= &Apache::loncommon::end_data_table_header_row();
  356: 
  357:     my $input_type;
  358:     if ($multiselect) {
  359: 	$input_type = "checkbox";
  360:     } else {
  361: 	$input_type = "radio";
  362:     }
  363: 
  364:     my $checked = 0;
  365:     for my $student (@$students) {
  366: 	$result .= &Apache::loncommon::start_data_table_row().
  367: 	    '<td><input type="'.$input_type.'"  name="'.
  368: 	    $resultname."_forminput".'"';
  369: 	my $user    = $student->[0];
  370: 
  371: 	# Figure out which students are checked by default...
  372: 	
  373: 	if (%$defaultusers) {
  374: 	    if (exists ($defaultusers->{$user})) {
  375: 		$result .= ' checked ="checked" ';
  376: 		$checked = 1;
  377: 	    }
  378: 	} elsif (!$multiselect  && !$checked) {
  379: 	    $result .= ' checked="checked" ';
  380: 	    $checked = 1;	# First one for radio if no default specified.
  381: 	}
  382: 	$result .= ' value="'.&HTML::Entities::encode($user .          ':'
  383: 				 		      .$student->[2] . ':'
  384: 						      .$student->[1] . ':'
  385: 						      .$student->[3] . ':'
  386: 						      .$student->[4] . ":"
  387: 						      .$formprefix,   "<>&\"'")
  388: 	    ."\" /></td><td>\n";
  389: 	$result .= &HTML::Entities::encode($student->[1], '<>&"')
  390: 	        . '</td><td align="center" >'."\n";
  391: 	$result .= &HTML::Entities::encode($student->[2], '<>&"')
  392:    	        . '</td><td align="center">'."\n";
  393: 	$result .= &HTML::Entities::encode($student->[3], '<>&"')
  394: 	        . '</td><td align="center">'."\n";
  395: 	$result .= &HTML::Entities::encode($student->[4], '<>&"')
  396:   	        . '</td><td align="center">'."\n";
  397: 	$result .= &HTML::Entities::encode($student->[0], '<>&"')
  398: 	        . '</td>'.&Apache::loncommon::end_data_table_row().
  399: 		"\n";
  400:     }
  401:     $result .= &Apache::loncommon::end_data_table();
  402:     if ($context ne 'email') {
  403: 	$result .= "<br /> <hr />\n";
  404:     }
  405: 
  406:     return $result;
  407: }
  408: 
  409: 1;

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