Annotation of loncom/interface/lonselstudent.pm, revision 1.16

1.1       foxr        1: # The LearningOnline Network with CAPA
                      2: # lonselstudent.pm : Reusable subs for student selection.
                      3: #
1.16    ! raeburn     4: # $Id: lonselstudent.pm,v 1.15 2015/08/16 00:21:21 raeburn Exp $
1.1       foxr        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;
1.10      albertel   31: use     Apache::lonlocal;
                     32: use     Apache::loncoursedata();
                     33: use     HTML::Entities();
1.1       foxr       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)
1.7       foxr       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: #
1.1       foxr       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.
1.15      raeburn    64: #       [2]    Section associated with role.
1.1       foxr       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 {
1.15      raeburn    77:     my ($section_restriction,$personnel_section) = @_;
                     78:     my %coursepersonnel = &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
                     79:     my $crstype = &Apache::loncommon::course_type();
1.1       foxr       80:     #
                     81:     #  Enumerate the course_personnel.
                     82:     #
                     83:     my @course_personnel;
1.15      raeburn    84:     foreach my $key (sort(keys(%coursepersonnel))) {
                     85:         my ($role,$section) = split(/:/,$key);
1.5       albertel   86: 	# extract the names so we can sort them
1.15      raeburn    87:         next if (($personnel_section ne '') && ($personnel_section ne $section)); 
1.5       albertel   88: 	my @people;
1.15      raeburn    89:         
                     90: 	foreach my $person (split(/,/, $coursepersonnel{$key})) {
1.5       albertel   91: 	    my ($uname,$domain) = split(/:/, $person);
                     92: 	    push(@people, [&Apache::loncommon::plainname($uname,$domain),
                     93: 			   $uname,$domain]);
                     94: 	}
                     95: 	@people = sort { $a->[0] cmp $b->[0] } (@people);
1.1       foxr       96: 	    
1.15      raeburn    97: 	foreach my $person (@people) {
1.5       albertel   98: 	    push(@course_personnel, [join(':', $person->[1],$person->[2]), 
1.15      raeburn    99: 				     $person->[0], $section, 'Active',
                    100:                                      &Apache::lonnet::plaintext($role)]);
1.1       foxr      101: 	}
                    102:     }
                    103:     #  Students must be split into the three categories:
                    104: 
                    105:     my @current_members;
                    106:     my @future_members;
                    107:     my @expired_members;
                    108: 
                    109:     #   Indices into the coures data elements.
                    110: 
                    111:     my $section    = &Apache::loncoursedata::CL_SECTION();
                    112:     my $fullname   = &Apache::loncoursedata::CL_FULLNAME();
                    113:     my $status     = &Apache::loncoursedata::CL_STATUS();
                    114:     my $start_date = &Apache::loncoursedata::CL_START();
                    115: 
                    116: 
                    117:     my $classlist = &Apache::loncoursedata::get_classlist();
1.4       albertel  118:     my @keys = keys(%{$classlist});
1.11      albertel  119:     # Sort by: fullname, username
1.1       foxr      120:     @keys = sort {
1.8       albertel  121: 	lc($classlist->{$a}[$fullname]) cmp lc($classlist->{$b}[$fullname]) ||
                    122: 	lc($a) cmp lc($b)
1.4       albertel  123:     } (@keys);
1.1       foxr      124:  
                    125: 
                    126: 
                    127: 
1.6       albertel  128:     for my $user (@keys) {
1.7       foxr      129: 	if (!$section_restriction || 
                    130: 	    ($section_restriction eq $classlist->{$user}->[$section])) {
1.1       foxr      131: 	    
1.7       foxr      132: 	    if ( $classlist->{$user}->[$status] eq
                    133: 		 'Active') {
                    134: 		push(@current_members, [$user, $classlist->{$user}->[$fullname], 
1.6       albertel  135: 					$classlist->{$user}->[$section],
1.7       foxr      136: 					$classlist->{$user}->[$status], 'Student']);
1.1       foxr      137: 	    } else {
1.7       foxr      138: 		#  Need to figure out if this user is future or
                    139: 		#  Expired... If the start date is in the future
                    140: 		#  the user is future...else expired.
                    141: 		
                    142: 		my $now = time;
                    143: 		if ($classlist->{$user}->[$start_date] > $now) {
                    144: 		    push(@future_members, [$user, $classlist->{$user}->[$fullname],
                    145: 					   $classlist->{$user}->[$section],
                    146: 					   "Future", "Student"]);
                    147: 		} else {
                    148: 		    push(@expired_members, [$user,
                    149: 					    $classlist->{$user}->[$fullname],
                    150: 					    $classlist->{$user}->[$section],
                    151: 					    "Expired", "Student"]);
                    152: 		}
                    153: 		
1.1       foxr      154: 	    }
                    155: 	}
                    156:     }
                    157:     return (\@course_personnel, 
                    158: 	    \@current_members,
                    159: 	    \@expired_members,
                    160: 	    \@future_members);
                    161: 
                    162: }
                    163: 
                    164: #
                    165: #  Utility function used when rendering the <student> tag.
                    166: #  This function renders a segment of course personel
                    167: #  Personel are broken up by the helper into past, current and
                    168: #  future...each one gets is own subpage of selection.
                    169: #  This sub renders one of these pages.
                    170: #  Parameters:
                    171: #     $students    - Students in the section. (ref to array of references
                    172: #                    to arrays).
1.2       foxr      173: #     $formname    - Name of the form in which this stuff gets rendered.
1.1       foxr      174: #     $formprefix  - form path prefix for form element names
                    175: #                    This is used to make each form element
                    176: #                    so that the segments having to do with each
                    177: #                    set of students won't collide.
                    178: #     $defaultusers - reference to a hash containng
                    179: #                     the set of users that should be on or off.
                    180: #     $multiselect  - True if multiselect allowed.
                    181: #     $resultname   - Name of result variable.
                    182: #     $javascript   - If true, the javascript to run this is output
                    183: #                     This should be true for the first call for a page
                    184: #                     and false for all other calls... only matters if
                    185: #                     multiselect is true.
1.13      raeburn   186: #     $context      - If email, do not include <br /><hr /> tags at the end
1.15      raeburn   187: #                     of the data table.
1.1       foxr      188: #  Returns:
                    189: #     HTML  text to add to the rendering of the helper.
                    190: #
                    191: sub render_student_list {
1.2       foxr      192:     my ($students, $formname, $formprefix, $defaultusers,
1.13      raeburn   193: 	$multiselect, $resultname, $javascript, $context) = @_;
1.1       foxr      194: 
                    195:     my $result = "";
                    196: 
1.8       albertel  197:     # no students so no output
                    198:     return if (!@$students);
                    199: 
1.1       foxr      200:     if ($javascript && $multiselect) {
                    201:         $result .= <<SCRIPT;
                    202: <script type="text/javascript">
                    203: // <!--
                    204: 
1.14      raeburn   205:     function findElement(name,formname) {
1.1       foxr      206: 	var i;
                    207: 	var ele;
1.14      raeburn   208: 	for(i =0; i < formname.elements.length; i++) {
                    209: 	    ele = formname.elements[i];
1.1       foxr      210: 	    if(ele.name == name) {
                    211: 		return ele;
                    212: 	    }
                    213: 	}
                    214: 	return null;
                    215:     }
                    216:     function isStudent(element) {
                    217: 	if(element.value.indexOf(":Student") != -1) {
                    218: 	    return 1;
                    219: 	}
                    220: 	return 0;
                    221:     }
                    222:     function section(element) {
                    223: 	var i;
                    224: 	var info;
                    225: 	if (element.value.indexOf(':') != -1) {
                    226: 	    info = element.value.split(':');
                    227: 	    return info[2];
                    228: 	} else {
                    229: 	    return "";
                    230: 	}
                    231:     }
                    232:     function rightSubForm(element, which) {
                    233: 	if (element.value.indexOf(which) != -1) {
                    234: 	    return true;
                    235: 	} else {
                    236: 	    return false;
                    237: 	}
                    238:     }
                    239: 
1.14      raeburn   240:     function setAllStudents(value, which, formname) {
1.1       foxr      241: 	var i;
                    242: 	var ele;
1.14      raeburn   243: 	for (i =0; i < formname.elements.length; i++) {
                    244: 	    ele = formname.elements[i];
1.1       foxr      245: 	    if(isStudent(ele) && rightSubForm(ele, which)) {
                    246: 		ele.checked=value;
                    247: 	    }
                    248: 	}
                    249:     }
1.14      raeburn   250:     function setAllCoursePersonnel(value, which, formname) {
1.1       foxr      251: 	var i;
                    252: 	var ele;
1.14      raeburn   253: 	for (i =0; i < formname.elements.length; i++) {
                    254: 	    ele = formname.elements[i];
1.1       foxr      255: 	    if(!isStudent(ele) && rightSubForm(ele, which)) {
                    256: 		ele.checked = value;
                    257: 	    }
                    258: 	}
                    259:     }
1.14      raeburn   260:     function setSection(which, value, subform, formname) {
1.1       foxr      261: 	var i;
                    262: 	var ele;
1.14      raeburn   263: 	for (i =0; i < formname.elements.length; i++) {
                    264: 	    ele = formname.elements[i];
1.1       foxr      265: 	    if (ele.value.indexOf(':') != -1) {
                    266: 		if ((section(ele) == which) && rightSubForm(ele, subform)) {
                    267: 		    ele.checked = value;
                    268: 		}
                    269: 	    }
                    270: 	}
                    271:     }
                    272: 
1.14      raeburn   273:     function setCheckboxes(listbox, which, value, formname) {
1.1       foxr      274: 	var k;
                    275: 	var elem;
                    276: 	var what;
1.14      raeburn   277:         elem = findElement(listbox, formname);
1.1       foxr      278: 	if (elem != null) {
                    279: 	    for (k = 0; k < elem.length; k++) {
                    280: 		if (elem.options[k].selected) {
1.10      albertel  281: 		    what = elem.options[k].value;
                    282: 		    if (what == 'allstudents') {
1.14      raeburn   283: 			setAllStudents(value, which, formname);
1.10      albertel  284: 		    } else if (what == 'allpersonnel') {
1.14      raeburn   285: 			setAllCoursePersonnel(value, which, formname);
1.10      albertel  286: 		    } else if (what == 'nosection') {
1.14      raeburn   287: 			setSection('',value, which, formname);
1.1       foxr      288: 		    } else {
1.14      raeburn   289: 			setSection(what, value, which, formname);
1.1       foxr      290: 		    }
                    291: 		}
                    292: 	    }
                    293: 	}
                    294:     }
1.14      raeburn   295:     function selectSections(listbox, which, formname) {
                    296: 	setCheckboxes(listbox, which, true, formname);
1.1       foxr      297: 
                    298:     }
1.14      raeburn   299:     function unselectSections(listbox, which, formname) {
                    300: 	setCheckboxes(listbox, which, false, formname);
1.1       foxr      301:     }
                    302: 
                    303: // -->
                    304: </script>
                    305: SCRIPT
                    306: 
                    307:     }
                    308: 
                    309:     # If multiple selections are allowed, we have a listbox
                    310:     # at the top which allows quick selections from each section
                    311:     # as well as from categories of personnel.
                    312: 
                    313:     if ($multiselect) {
                    314: 	#  Make a section hash so we can add sections to the choice:
                    315: 
                    316: 	my %sections;
                    317: 	for my $student (@$students) {
                    318: 	    my $sect = $student->[2];
                    319: 	    if ($sect ne "") {
                    320: 		$sections{$sect} = 1;
                    321: 	    }
                    322: 	}
                    323: 
                    324: 	$result .= '<table><tr><td>';
                    325: 
                    326: 	my $size = scalar(keys(%sections));
                    327: 	$size += 3;		# We have allstudents allpersonel nosection too.
                    328: 	if ($size > 5) { 
                    329: 	    $size = 5; 
                    330: 	}
1.14      raeburn   331: 	$result .= '<select multiple="multiple" name="'.$formprefix
1.1       foxr      332: 	    .'.chosensections" size="'.$size.'">'."\n";
1.10      albertel  333: 	$result .= '<option value="allstudents">'.&mt('All Students').'</option>';
                    334: 	$result .= '<option value="allpersonnel">'.&mt('All Course Personnel').'</option>';
                    335: 	$result .= '<option value="nosection">'.&mt('No Section').'</option>';
1.1       foxr      336: 	$result .= "\n";
                    337: 	foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
1.16    ! raeburn   338: 	    $result .= '<option value="'.$sec.'">'.$sec.'</option>'."\n";
1.1       foxr      339: 	}
1.13      raeburn   340: 	$result .= '</select></td><td valign="top">';
1.12      bisitz    341: 	$result .= '<input type="button" name="'.$formprefix.'.select" value="'.&mt('Select').'" onclick='
1.14      raeburn   342: 	    ."'selectSections(\"$formprefix.chosensections\", \"$formprefix\", document.forms.$formname)'".' /></td>';
1.1       foxr      343: 	$result .= '<td valign="top"><input type="button" name="'.$formprefix
1.10      albertel  344: 	    .'.unselect" value="'.&mt('Unselect').'"  onclick='.
1.14      raeburn   345: 	    "'unselectSections(\"$formprefix.chosensections\", \"$formprefix\", document.forms.$formname)' ".' /></td></tr></table>';
1.1       foxr      346:     }
                    347: 
                    348:     #  Now we list the students, but the form element type
                    349:     #  will depend on whether or not multiselect is true.
                    350:     #  True -> checkboxes.
                    351:     #  False -> radiobuttons.
                    352: 
1.3       albertel  353:     $result .= &Apache::loncommon::start_data_table();
                    354:     $result .= &Apache::loncommon::start_data_table_header_row();
1.10      albertel  355:     $result .= '<th></th><th>'.&mt('Name').'</th>'."\n";
                    356:     $result .= '    <th>'.&mt('Section').'</th>'."\n";
                    357:     $result .= '    <th>'.&mt('Status').'</th>'."\n";
                    358:     $result .= '    <th>'.&mt('Role').'</th>'."\n";
                    359:     $result .= '    <th>'.&mt('Username : Domain').'</th>'."\n";
1.3       albertel  360:     $result .= &Apache::loncommon::end_data_table_header_row();
1.1       foxr      361: 
                    362:     my $input_type;
                    363:     if ($multiselect) {
                    364: 	$input_type = "checkbox";
                    365:     } else {
                    366: 	$input_type = "radio";
                    367:     }
                    368: 
                    369:     my $checked = 0;
                    370:     for my $student (@$students) {
1.3       albertel  371: 	$result .= &Apache::loncommon::start_data_table_row().
                    372: 	    '<td><input type="'.$input_type.'"  name="'.
1.9       raeburn   373: 	    $resultname."_forminput".'"';
1.1       foxr      374: 	my $user    = $student->[0];
                    375: 
                    376: 	# Figure out which students are checked by default...
                    377: 	
1.4       albertel  378: 	if (%$defaultusers) {
1.1       foxr      379: 	    if (exists ($defaultusers->{$user})) {
                    380: 		$result .= ' checked ="checked" ';
                    381: 		$checked = 1;
                    382: 	    }
                    383: 	} elsif (!$multiselect  && !$checked) {
                    384: 	    $result .= ' checked="checked" ';
                    385: 	    $checked = 1;	# First one for radio if no default specified.
                    386: 	}
1.4       albertel  387: 	$result .= ' value="'.&HTML::Entities::encode($user .          ':'
                    388: 				 		      .$student->[2] . ':'
1.1       foxr      389: 						      .$student->[1] . ':'
                    390: 						      .$student->[3] . ':'
                    391: 						      .$student->[4] . ":"
                    392: 						      .$formprefix,   "<>&\"'")
                    393: 	    ."\" /></td><td>\n";
1.4       albertel  394: 	$result .= &HTML::Entities::encode($student->[1], '<>&"')
1.1       foxr      395: 	        . '</td><td align="center" >'."\n";
1.4       albertel  396: 	$result .= &HTML::Entities::encode($student->[2], '<>&"')
1.1       foxr      397:    	        . '</td><td align="center">'."\n";
1.4       albertel  398: 	$result .= &HTML::Entities::encode($student->[3], '<>&"')
1.1       foxr      399: 	        . '</td><td align="center">'."\n";
1.4       albertel  400: 	$result .= &HTML::Entities::encode($student->[4], '<>&"')
1.1       foxr      401:   	        . '</td><td align="center">'."\n";
1.4       albertel  402: 	$result .= &HTML::Entities::encode($student->[0], '<>&"')
1.3       albertel  403: 	        . '</td>'.&Apache::loncommon::end_data_table_row().
                    404: 		"\n";
1.1       foxr      405:     }
1.13      raeburn   406:     $result .= &Apache::loncommon::end_data_table();
                    407:     if ($context ne 'email') {
                    408: 	$result .= "<br /> <hr />\n";
                    409:     }
1.1       foxr      410: 
                    411:     return $result;
                    412: }
                    413: 
                    414: 1;

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