Annotation of loncom/interface/lonselstudent.pm, revision 1.17
1.1 foxr 1: # The LearningOnline Network with CAPA
2: # lonselstudent.pm : Reusable subs for student selection.
3: #
1.17 ! raeburn 4: # $Id: lonselstudent.pm,v 1.16 2016/10/22 01:53:27 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));
1.17 ! raeburn 327: if ($context eq 'accesstimes') {
! 328: $size += 2;
! 329: } else {
! 330: $size += 3; # We have allstudents allpersonel nosection too.
! 331: }
! 332: if ($size > 5) {
1.1 foxr 333: $size = 5;
334: }
1.14 raeburn 335: $result .= '<select multiple="multiple" name="'.$formprefix
1.1 foxr 336: .'.chosensections" size="'.$size.'">'."\n";
1.10 albertel 337: $result .= '<option value="allstudents">'.&mt('All Students').'</option>';
1.17 ! raeburn 338: unless ($context eq 'accesstimes') {
! 339: $result .= '<option value="allpersonnel">'.&mt('All Course Personnel').'</option>';
! 340: }
1.10 albertel 341: $result .= '<option value="nosection">'.&mt('No Section').'</option>';
1.1 foxr 342: $result .= "\n";
343: foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
1.16 raeburn 344: $result .= '<option value="'.$sec.'">'.$sec.'</option>'."\n";
1.1 foxr 345: }
1.13 raeburn 346: $result .= '</select></td><td valign="top">';
1.12 bisitz 347: $result .= '<input type="button" name="'.$formprefix.'.select" value="'.&mt('Select').'" onclick='
1.14 raeburn 348: ."'selectSections(\"$formprefix.chosensections\", \"$formprefix\", document.forms.$formname)'".' /></td>';
1.1 foxr 349: $result .= '<td valign="top"><input type="button" name="'.$formprefix
1.10 albertel 350: .'.unselect" value="'.&mt('Unselect').'" onclick='.
1.14 raeburn 351: "'unselectSections(\"$formprefix.chosensections\", \"$formprefix\", document.forms.$formname)' ".' /></td></tr></table>';
1.1 foxr 352: }
353:
354: # Now we list the students, but the form element type
355: # will depend on whether or not multiselect is true.
356: # True -> checkboxes.
357: # False -> radiobuttons.
358:
1.3 albertel 359: $result .= &Apache::loncommon::start_data_table();
360: $result .= &Apache::loncommon::start_data_table_header_row();
1.10 albertel 361: $result .= '<th></th><th>'.&mt('Name').'</th>'."\n";
362: $result .= ' <th>'.&mt('Section').'</th>'."\n";
363: $result .= ' <th>'.&mt('Status').'</th>'."\n";
364: $result .= ' <th>'.&mt('Role').'</th>'."\n";
365: $result .= ' <th>'.&mt('Username : Domain').'</th>'."\n";
1.3 albertel 366: $result .= &Apache::loncommon::end_data_table_header_row();
1.1 foxr 367:
368: my $input_type;
369: if ($multiselect) {
370: $input_type = "checkbox";
371: } else {
372: $input_type = "radio";
373: }
374:
375: my $checked = 0;
376: for my $student (@$students) {
1.3 albertel 377: $result .= &Apache::loncommon::start_data_table_row().
378: '<td><input type="'.$input_type.'" name="'.
1.9 raeburn 379: $resultname."_forminput".'"';
1.1 foxr 380: my $user = $student->[0];
381:
382: # Figure out which students are checked by default...
383:
1.4 albertel 384: if (%$defaultusers) {
1.1 foxr 385: if (exists ($defaultusers->{$user})) {
386: $result .= ' checked ="checked" ';
387: $checked = 1;
388: }
389: } elsif (!$multiselect && !$checked) {
390: $result .= ' checked="checked" ';
391: $checked = 1; # First one for radio if no default specified.
392: }
1.4 albertel 393: $result .= ' value="'.&HTML::Entities::encode($user . ':'
394: .$student->[2] . ':'
1.1 foxr 395: .$student->[1] . ':'
396: .$student->[3] . ':'
397: .$student->[4] . ":"
398: .$formprefix, "<>&\"'")
399: ."\" /></td><td>\n";
1.4 albertel 400: $result .= &HTML::Entities::encode($student->[1], '<>&"')
1.1 foxr 401: . '</td><td align="center" >'."\n";
1.4 albertel 402: $result .= &HTML::Entities::encode($student->[2], '<>&"')
1.1 foxr 403: . '</td><td align="center">'."\n";
1.4 albertel 404: $result .= &HTML::Entities::encode($student->[3], '<>&"')
1.1 foxr 405: . '</td><td align="center">'."\n";
1.4 albertel 406: $result .= &HTML::Entities::encode($student->[4], '<>&"')
1.1 foxr 407: . '</td><td align="center">'."\n";
1.4 albertel 408: $result .= &HTML::Entities::encode($student->[0], '<>&"')
1.3 albertel 409: . '</td>'.&Apache::loncommon::end_data_table_row().
410: "\n";
1.1 foxr 411: }
1.13 raeburn 412: $result .= &Apache::loncommon::end_data_table();
413: if ($context ne 'email') {
414: $result .= "<br /> <hr />\n";
415: }
1.1 foxr 416:
417: return $result;
418: }
419:
420: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>