Annotation of loncom/interface/lonhtmlcommon.pm, revision 1.14
1.2 www 1: # The LearningOnline Network with CAPA
2: # a pile of common html routines
3: #
1.14 ! albertel 4: # $Id: lonhtmlcommon.pm,v 1.13 2003/02/20 14:34:59 matthew Exp $
1.2 www 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: #
1.10 matthew 28: ######################################################################
29: ######################################################################
30:
31: =pod
32:
33: =head1 NAME
34:
35: Apache::lonhtmlcommon - routines to do common html things
36:
37: =head1 SYNOPSIS
38:
39: Referenced by other mod_perl Apache modules.
40:
41: =head1 INTRODUCTION
42:
43: lonhtmlcommon is a collection of subroutines used to present information
44: in a consistent html format, or provide other functionality related to
45: html.
46:
47: =head2 General Subroutines
48:
49: =over 4
50:
51: =cut
52:
53: ######################################################################
54: ######################################################################
1.2 www 55:
1.1 stredwic 56: package Apache::lonhtmlcommon;
57:
1.10 matthew 58: use Time::Local;
1.1 stredwic 59: use strict;
60:
1.10 matthew 61: ##############################################
62: ##############################################
63:
64: =pod
65:
66: =item &date_setter
67:
68: Inputs
69:
70: =over 4
71:
72: =item $dname
73:
74: The name to prepend to the form elements.
75: The form elements defined will be dname_year, dname_month, dname_day,
76: dname_hour, dname_min, and dname_sec.
77:
78: =item $currentvalue
79:
80: The current setting for this time parameter. A unix format time
81: (time in seconds since the beginning of Jan 1st, 1970, GMT.
82: An undefined value is taken to indicate the value is the current time.
83: Also, to be explicit, a value of 'now' also indicates the current time.
84:
85: =cut
86:
87: ##############################################
88: ##############################################
89: sub date_setter {
90: my ($formname,$dname,$currentvalue) = @_;
91: if (! defined($currentvalue) || $currentvalue eq 'now') {
92: $currentvalue = time;
93: }
94: # other potentially useful values: wkday,yrday,is_daylight_savings
95: my ($sec,$min,$hour,$mday,$month,$year,undef,undef,undef) =
96: localtime($currentvalue);
97: $year += 1900;
98: my $result = "\n<!-- $dname date setting form -->\n";
99: $result .= <<ENDJS;
100: <script language="Javascript">
101: function $dname\_checkday() {
102: var day = document.$formname.$dname\_day.value;
103: var month = document.$formname.$dname\_month.value;
104: var year = document.$formname.$dname\_year.value;
105: var valid = true;
106: if (day < 1) {
107: document.$formname.$dname\_day.value = 1;
108: }
109: if (day > 31) {
110: document.$formname.$dname\_day.value = 31;
111: }
112: if ((month == 1) || (month == 3) || (month == 5) ||
113: (month == 7) || (month == 8) || (month == 10) ||
114: (month == 12)) {
115: if (day > 31) {
116: document.$formname.$dname\_day.value = 31;
117: day = 31;
118: }
119: } else if (month == 2 ) {
120: if ((year % 4 == 0) && (year % 100 != 0)) {
121: if (day > 29) {
122: document.$formname.$dname\_day.value = 29;
123: }
124: } else if (day > 29) {
125: document.$formname.$dname\_day.value = 28;
126: }
127: } else if (day > 30) {
128: document.$formname.$dname\_day.value = 30;
129: }
130: }
131: </script>
132: ENDJS
133: $result .= " <select name=\"$dname\_month\" ".
134: "onChange=\"javascript:$dname\_checkday()\" >\n";
135: my @Months = qw/January February March April May June
136: July August September October November December/;
137: # Pad @Months with a bogus value to make indexing easier
138: unshift(@Months,'If you can read this an error occurred');
139: for(my $m = 1;$m <=$#Months;$m++) {
140: $result .= " <option value=\"$m\" ";
141: $result .= "selected " if ($m-1 == $month);
142: $result .= "> $Months[$m] </option>\n";
143: }
144: $result .= " </select>\n";
145: $result .= " <input type=\"text\" name=\"$dname\_day\" ".
146: "value=\"$mday\" size=\"3\" ".
147: "onChange=\"javascript:$dname\_checkday()\" />\n";
148: $result .= " <input type=\"year\" name=\"$dname\_year\" ".
149: "value=\"$year\" size=\"5\" ".
150: "onChange=\"javascript:$dname\_checkday()\" />\n";
151: $result .= " ";
152: $result .= " <select name=\"$dname\_hour\" >\n";
153: for (my $h = 0;$h<24;$h++) {
154: $result .= " <option value=\"$h\" ";
155: $result .= "selected " if ($hour == $h);
156: $result .= "> ";
157: if ($h == 0) {
158: $result .= "12 am";
159: } elsif($h == 12) {
160: $result .= "12 noon";
161: } elsif($h < 12) {
162: $result .= "$h am";
163: } else {
164: $result .= $h-12 ." pm";
165: }
166: $result .= " </option>\n";
167: }
168: $result .= " </select>\n";
169: $result .= " <input type=\"text\" name=\"$dname\_minute\" ".
170: "value=\"$min\" size=\"3\" /> m\n";
171: $result .= " <input type=\"text\" name=\"$dname\_second\" ".
172: "value=\"$sec\" size=\"3\" /> s\n";
173: $result .= "<!-- end $dname date setting form -->\n";
174: return $result;
175: }
176:
177: ##############################################
178: ##############################################
179:
180: =item &get_date_from_form
181:
182: Inputs:
183:
184: =over 4
185:
186: =item $dname
187:
188: The name passed to &datesetter, which prefixes the form elements.
189:
190: =item $defaulttime
191:
192: The unix time to use as the default in case of poor inputs.
193:
194: =back
195:
196: Returns: Unix time represented in the form.
197:
198: =cut
199:
200: ##############################################
201: ##############################################
202: sub get_date_from_form {
203: my ($dname) = @_;
204: my ($sec,$min,$hour,$day,$month,$year);
205: #
206: if (defined($ENV{'form.'.$dname.'_second'})) {
207: my $tmpsec = $ENV{'form.'.$dname.'_second'};
208: if (($tmpsec =~ /^\d+$/) && ($tmpsec >= 0) && ($tmpsec < 60)) {
209: $sec = $tmpsec;
210: }
211: }
212: if (defined($ENV{'form.'.$dname.'_minute'})) {
213: my $tmpmin = $ENV{'form.'.$dname.'_minute'};
214: if (($tmpmin =~ /^\d+$/) && ($tmpmin >= 0) && ($tmpmin < 60)) {
215: $min = $tmpmin;
216: }
217: }
218: if (defined($ENV{'form.'.$dname.'_hour'})) {
219: my $tmphour = $ENV{'form.'.$dname.'_hour'};
220: if (($tmphour =~ /^\d+$/) && ($tmphour > 0) && ($tmphour < 32)) {
221: $hour = $tmphour;
222: }
223: }
224: if (defined($ENV{'form.'.$dname.'_day'})) {
225: my $tmpday = $ENV{'form.'.$dname.'_day'};
226: if (($tmpday =~ /^\d+$/) && ($tmpday > 0) && ($tmpday < 32)) {
227: $day = $tmpday;
228: }
229: }
230: if (defined($ENV{'form.'.$dname.'_month'})) {
231: my $tmpmonth = $ENV{'form.'.$dname.'_month'};
232: if (($tmpmonth =~ /^\d+$/) && ($tmpmonth > 0) && ($tmpmonth < 13)) {
233: $month = $tmpmonth - 1;
234: }
235: }
236: if (defined($ENV{'form.'.$dname.'_year'})) {
237: my $tmpyear = $ENV{'form.'.$dname.'_year'};
238: if (($tmpyear =~ /^\d+$/) && ($tmpyear > 1900)) {
239: $year = $tmpyear - 1900;
240: }
241: }
242: if (eval(&timelocal($sec,$min,$hour,$day,$month,$year))) {
243: return &timelocal($sec,$min,$hour,$day,$month,$year);
244: } else {
245: return undef;
246: }
247: }
248:
249: ##############################################
250: ##############################################
251:
1.6 stredwic 252: sub AscendOrderOptions {
253: my ($order, $page, $formName)=@_;
254:
255: my $OpSel1 = '';
256: my $OpSel2 = '';
257:
258: if($order eq 'Ascending') {
259: $OpSel1 = ' selected';
260: } else {
261: $OpSel2 = ' selected';
262: }
263:
264: my $Str = '';
265: $Str .= '<select name="'.(($page)?$page:'').'Ascend"';
266: if($formName) {
267: $Str .= ' onchange="document.'.$formName.'.submit()"';
268: }
269: $Str .= '>'."\n";
270: $Str .= '<option'.$OpSel1.'>Ascending</option>'."\n".
271: '<option'.$OpSel2.'>Descending</option>'."\n";
272: $Str .= '</select>'."\n";
273:
274: return $Str;
275: }
276:
1.1 stredwic 277: sub MapOptions {
1.6 stredwic 278: my ($data, $page, $formName)=@_;
1.1 stredwic 279: my $Str = '';
280: $Str .= '<select name="';
1.6 stredwic 281: $Str .= (($page)?$page:'').'Maps"';
282: if($formName) {
283: $Str .= ' onchange="document.'.$formName.'.submit()"';
284: }
285: $Str .= '>'."\n";
1.1 stredwic 286:
287: my $selected = 0;
288: foreach my $sequence (split(':',$data->{'orderedSequences'})) {
289: $Str .= '<option';
1.7 stredwic 290: if($data->{$page.'Maps'} eq $data->{$sequence.':title'}) {
1.1 stredwic 291: $Str .= ' selected';
292: $selected = 1;
293: }
294: $Str .= '>'.$data->{$sequence.':title'}.'</option>'."\n";
295: }
296: $Str .= '<option';
297: if(!$selected) {
298: $Str .= ' selected';
299: }
300: $Str .= '>All Maps</option>'."\n";
1.9 stredwic 301:
302: $Str .= '</select>'."\n";
303:
304: return $Str;
305: }
306:
307: sub ProblemOptions {
308: my ($data, $page, $map, $formName)=@_;
309: my $Str = '';
310: $Str .= '<select name="';
311: $Str .= (($page)?$page:'').'ProblemSelect"';
312: if($formName) {
313: $Str .= ' onchange="document.'.$formName.'.submit()"';
314: }
315: $Str .= '>'."\n";
316:
317: my $selected = 0;
318: foreach my $sequence (split(':',$data->{'orderedSequences'})) {
319: if($data->{$sequence.':title'} eq $map || $map eq 'All Maps') {
320: foreach my $problem (split(':', $data->{$sequence.':problems'})) {
321: $Str .= '<option';
322: if($data->{$page.'ProblemSelect'} eq
323: $data->{$problem.':title'}) {
324: $Str .= ' selected';
325: $selected = 1;
326: }
327: $Str .= '>'.$data->{$problem.':title'}.'</option>'."\n";
328: }
329: }
330: }
331: $Str .= '<option';
332: if(!$selected) {
333: $Str .= ' selected';
334: }
335: $Str .= '>All Problems</option>'."\n";
336:
337: $Str .= '</select>'."\n";
338:
339: return $Str;
340: }
341:
342: sub PartOptions {
343: my ($data, $page, $parts, $formName)=@_;
344: my $Str = '';
345:
346: if(!defined($parts)) {
347: return '';
348: }
349:
350: $Str .= '<select name="';
351: $Str .= (($page)?$page:'').'PartSelect"';
352: if($formName) {
353: $Str .= ' onchange="document.'.$formName.'.submit()"';
354: }
355: $Str .= '>'."\n";
356:
357: my $selected = 0;
358: foreach my $part (@$parts) {
359: $Str .= '<option';
360: if($data->{$page.'PartSelect'} eq $part) {
361: $Str .= ' selected';
362: $selected = 1;
363: }
364: $Str .= '>'.$part.'</option>'."\n";
365: }
366: $Str .= '<option';
367: if(!$selected) {
368: $Str .= ' selected';
369: }
370: $Str .= '>All Parts</option>'."\n";
1.1 stredwic 371:
372: $Str .= '</select>'."\n";
373:
374: return $Str;
375: }
376:
377: sub StudentOptions {
1.4 stredwic 378: my ($cache, $students, $selectedName, $page, $formName)=@_;
1.1 stredwic 379:
380: my $Str = '';
1.4 stredwic 381: $Str .= '<select name="'.(($page)?$page:'').'Student"';
382: if($formName) {
383: $Str .= ' onchange="document.'.$formName.'.submit()"';
384: }
385: $Str .= '>'."\n";
1.1 stredwic 386:
387: my $selected=0;
388:
389: foreach (@$students) {
390: $Str .= '<option';
391: if($selectedName eq $_) {
392: $Str .= ' selected';
393: $selected = 1;
394: }
395: $Str .= '>';
396: $Str .= $cache->{$_.':fullname'};
397: $Str .= '</option>'."\n";
398: }
399:
400: $Str .= '<option';
1.3 stredwic 401: if($selectedName eq 'No Student Selected') {
402: $Str .= ' selected';
403: $selected = 1;
404: }
405: $Str .= '>No Student Selected</option>'."\n";
406:
407: $Str .= '<option';
1.1 stredwic 408: if(!$selected) {
409: $Str .= ' selected';
410: }
1.3 stredwic 411: $Str .= '>All Students</option>'."\n";
1.1 stredwic 412:
413: $Str .= '</select>'."\n";
414:
415: return $Str;
416: }
417:
418: sub StatusOptions {
419: my ($status, $formName)=@_;
420:
421: my $OpSel1 = '';
422: my $OpSel2 = '';
423: my $OpSel3 = '';
424:
425: if($status eq 'Any') { $OpSel3 = ' selected'; }
426: elsif($status eq 'Expired' ) { $OpSel2 = ' selected'; }
427: else { $OpSel1 = ' selected'; }
428:
429: my $Str = '';
430: $Str .= '<select name="Status"';
431: if(defined($formName) && $formName ne '') {
432: $Str .= ' onchange="document.'.$formName.'.submit()"';
433: }
434: $Str .= '>'."\n";
435: $Str .= '<option'.$OpSel1.'>Active</option>'."\n";
436: $Str .= '<option'.$OpSel2.'>Expired</option>'."\n";
437: $Str .= '<option'.$OpSel3.'>Any</option>'."\n";
438: $Str .= '</select>'."\n";
439: }
440:
1.12 matthew 441:
442: ########################################################
443: ########################################################
444:
445: =pod
446:
447: =item &MultipleSectionSelect()
448:
449: Inputs:
450:
451: =over 4
452:
453: =item $sections A references to an array containing the names of all the
454: sections used in a class.
455:
456: =item $selectedSections A reference to an array containing the names of the
457: currently selected sections.
458:
459: =back
460:
461: Returns: a string containing HTML for a multiple select box for
462: selecting sections of a course.
463:
464: The form element name is 'Section'. @$sections is sorted prior to output.
465:
466: =cut
467:
468: ########################################################
469: ########################################################
1.5 stredwic 470: sub MultipleSectionSelect {
471: my ($sections,$selectedSections)=@_;
472:
473: my $Str = '';
1.7 stredwic 474: $Str .= '<select name="Section" multiple="true" size="4">'."\n";
1.5 stredwic 475:
1.11 minaeibi 476: foreach (sort @$sections) {
1.5 stredwic 477: $Str .= '<option';
478: foreach my $selected (@$selectedSections) {
479: if($_ eq $selected) {
480: $Str .= ' selected=""';
481: }
482: }
483: $Str .= '>'.$_.'</option>'."\n";
484: }
485: $Str .= '</select>'."\n";
1.12 matthew 486:
1.5 stredwic 487: return $Str;
488: }
489:
1.12 matthew 490: ########################################################
491: ########################################################
492:
493: =pod
494:
495: =item &Title()
496:
497: Inputs: $pageName a string containing the name of the page to be sent
498: to &Apache::loncommon::bodytag.
499:
500: Returns: string containing being <html> and complete <head> and <title>
501: as well as a <script> to focus the current window and change its width
502: and height to 500. Why? I do not know. If you find out, please update
503: this documentation.
504:
505: =cut
506:
507: ########################################################
508: ########################################################
1.1 stredwic 509: sub Title {
510: my ($pageName)=@_;
511:
512: my $Str = '';
513:
514: $Str .= '<html><head><title>'.$pageName.'</title></head>'."\n";
1.8 www 515: $Str .= &Apache::loncommon::bodytag($pageName)."\n";
1.1 stredwic 516: $Str .= '<script>window.focus(); window.width=500;window.height=500;';
517: $Str .= '</script>'."\n";
518:
519: return $Str;
520: }
521:
1.12 matthew 522: ########################################################
523: ########################################################
524:
1.1 stredwic 525: =pod
526:
1.13 matthew 527: =item &CreateHeadings()
1.1 stredwic 528:
529: This function generates the column headings for the chart.
530:
531: =over 4
532:
1.4 stredwic 533: Inputs: $CacheData, $keyID, $headings, $spacePadding
1.1 stredwic 534:
535: $CacheData: pointer to a hash tied to the cached data database
536:
1.4 stredwic 537: $keyID: a pointer to an array containing the names of the data
1.1 stredwic 538: held in a column and is used as part of a key into $CacheData
539:
540: $headings: The names of the headings for the student information
541:
542: $spacePadding: The spaces to go between columns
543:
544: Output: $Str
545:
546: $Str: A formatted string of the table column headings.
547:
548: =back
549:
550: =cut
551:
1.12 matthew 552: ########################################################
553: ########################################################
1.4 stredwic 554: sub CreateHeadings {
555: my ($data,$keyID,$headings,$displayString,$format)=@_;
1.1 stredwic 556: my $Str='';
1.4 stredwic 557: my $formatting = '';
1.1 stredwic 558:
559: for(my $index=0; $index<(scalar @$headings); $index++) {
1.4 stredwic 560: my $currentHeading=$headings->[$index];
561: if($format eq 'preformatted') {
562: my @dataLength=split(//,$currentHeading);
563: my $length=scalar @dataLength;
564: $formatting = (' 'x
565: ($data->{$keyID->[$index].':columnWidth'}-$length));
566: }
567: my $linkdata=$keyID->[$index];
568:
1.1 stredwic 569: my $tempString = $displayString;
570: $tempString =~ s/LINKDATA/$linkdata/;
1.4 stredwic 571: $tempString =~ s/DISPLAYDATA/$currentHeading/;
572: $tempString =~ s/FORMATTING/$formatting/;
573:
1.1 stredwic 574: $Str .= $tempString;
575: }
576:
577: return $Str;
578: }
579:
1.12 matthew 580: ########################################################
581: ########################################################
582:
1.1 stredwic 583: =pod
584:
585: =item &FormatStudentInformation()
586:
1.10 matthew 587: This function produces a formatted string of the student\'s information:
1.1 stredwic 588: username, domain, section, full name, and PID.
589:
590: =over 4
591:
1.4 stredwic 592: Input: $cache, $name, $keyID, $spacePadding
1.1 stredwic 593:
594: $cache: This is a pointer to a hash that is tied to the cached data
595:
596: $name: The name and domain of the current student in name:domain format
597:
1.4 stredwic 598: $keyID: A pointer to an array holding the names used to
1.1 stredwic 599:
600: remove data from the hash. They represent the name of the data to be removed.
601:
602: $spacePadding: Extra spaces that represent the space between columns
603:
604: Output: $Str
605:
606: $Str: Formatted string.
607:
608: =back
609:
610: =cut
611:
1.12 matthew 612: ########################################################
613: ########################################################
1.1 stredwic 614: sub FormatStudentInformation {
1.4 stredwic 615: my ($data,$name,$keyID,$displayString,$format)=@_;
1.1 stredwic 616: my $Str='';
1.4 stredwic 617: my $currentColumn;
618:
619: for(my $index=0; $index<(scalar @$keyID); $index++) {
620: $currentColumn=$data->{$name.':'.$keyID->[$index]};
1.1 stredwic 621:
1.4 stredwic 622: if($format eq 'preformatted') {
623: my @dataLength=split(//,$currentColumn);
624: my $length=scalar @dataLength;
625: $currentColumn.= (' 'x
626: ($data->{$keyID->[$index].':columnWidth'}-$length));
1.1 stredwic 627: }
628:
1.4 stredwic 629: my $tempString = $displayString;
630: $tempString =~ s/DISPLAYDATA/$currentColumn/;
631:
632: $Str .= $tempString;
1.1 stredwic 633: }
634:
635: return $Str;
1.7 stredwic 636: }
1.12 matthew 637:
638: ########################################################
639: ########################################################
1.7 stredwic 640:
641: # Create progress
642: sub Create_PrgWin {
1.14 ! albertel 643: my ($r, $title, $heading, $number_to_do)=@_;
1.7 stredwic 644: $r->print('<script>'.
645: "popwin=open(\'\',\'popwin\',\'width=400,height=100\');".
1.14 ! albertel 646: "popwin.document.writeln(\'<html><head><title>$title</title></head>".
! 647: "<body bgcolor=\"#88DDFF\">".
1.7 stredwic 648: "<h4>$heading</h4>".
649: "<form name=popremain>".
1.14 ! albertel 650: "<input type=text size=55 name=remaining value=Starting></form>".
1.7 stredwic 651: "</body></html>\');".
652: "popwin.document.close();".
653: "</script>");
654:
1.14 ! albertel 655: my %prog_state;
! 656: $prog_state{'now'}=0;
! 657: $prog_state{'since'}=time;
! 658: $prog_state{'started'}=time;
! 659: $prog_state{'total'}=$number_to_do;
! 660:
1.7 stredwic 661: $r->rflush();
1.14 ! albertel 662: return %prog_state;
1.7 stredwic 663: }
664:
665: # update progress
666: sub Update_PrgWin {
1.14 ! albertel 667: my ($r,$prog_state,$displayString)=@_;
1.7 stredwic 668: $r->print('<script>popwin.document.popremain.remaining.value="'.
669: $displayString.'";</script>');
1.14 ! albertel 670: $$prog_state{'started'}=time;
! 671: $r->rflush();
! 672: }
! 673:
! 674: # increment progress state
! 675: sub Increment_PrgWin {
! 676: my ($r,$prog_state,$extraInfo)=@_;
! 677: $$prog_state{'now'}++;
! 678: $r->print('<script>popwin.document.popremain.remaining.value="'.
! 679: $$prog_state{'now'}.'/'.$$prog_state{'total'}.
! 680: ': '.int((time-$$prog_state{'since'})/
! 681: $$prog_state{'now'}*($$prog_state{'total'}-$$prog_state{'now'})).
! 682: ' secs remaining ('.(time-$$prog_state{'started'}).
! 683: ' seconds for '.$extraInfo.')";'.'</script>');
! 684: $$prog_state{'started'}=time;
! 685: sleep 1;
1.7 stredwic 686: $r->rflush();
687: }
688:
689: # close Progress Line
690: sub Close_PrgWin {
1.14 ! albertel 691: my ($r,$prog_state)=@_;
1.7 stredwic 692: $r->print('<script>popwin.close()</script>'."\n");
1.14 ! albertel 693: undef(%$prog_state);
1.7 stredwic 694: $r->rflush();
1.1 stredwic 695: }
696:
697: 1;
698: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>