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

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

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