Annotation of loncom/interface/lonhtmlcommon.pm, revision 1.18
1.2 www 1: # The LearningOnline Network with CAPA
2: # a pile of common html routines
3: #
1.18 ! matthew 4: # $Id: lonhtmlcommon.pm,v 1.17 2003/03/10 20:21:45 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: ##############################################
1.17 matthew 251:
252: =pod
253:
254: =item &javascript_nothing()
255:
256: Return an appropriate null for the users browser. This is used
257: as the first arguement for window.open calls when you want a blank
258: window that you can then write to.
259:
260: =cut
261:
262: ##############################################
263: ##############################################
264: sub javascript_nothing {
265: # mozilla and other browsers work with "''", but IE on mac does not.
266: my $nothing = "''";
267: my $user_browser;
268: my $user_os;
269: $user_browser = $ENV{'browser.type'} if (exists($ENV{'browser.type'}));
270: $user_os = $ENV{'browser.os'} if (exists($ENV{'browser.os'}));
271: if (! defined($user_browser) || ! defined($user_os)) {
272: (undef,$user_browser,undef,undef,undef,$user_os) =
273: &Apache::loncommon::decode_user_agent();
274: }
275: if ($user_browser eq 'explorer' && $user_os =~ 'mac') {
276: $nothing = "'javascript:void(0);'";
277: }
278: return $nothing;
279: }
280:
281: ##############################################
282: ##############################################
283:
284:
1.10 matthew 285:
1.6 stredwic 286: sub AscendOrderOptions {
287: my ($order, $page, $formName)=@_;
288:
289: my $OpSel1 = '';
290: my $OpSel2 = '';
291:
292: if($order eq 'Ascending') {
293: $OpSel1 = ' selected';
294: } else {
295: $OpSel2 = ' selected';
296: }
297:
298: my $Str = '';
299: $Str .= '<select name="'.(($page)?$page:'').'Ascend"';
300: if($formName) {
301: $Str .= ' onchange="document.'.$formName.'.submit()"';
302: }
303: $Str .= '>'."\n";
304: $Str .= '<option'.$OpSel1.'>Ascending</option>'."\n".
305: '<option'.$OpSel2.'>Descending</option>'."\n";
306: $Str .= '</select>'."\n";
307:
308: return $Str;
309: }
310:
1.1 stredwic 311: sub MapOptions {
1.6 stredwic 312: my ($data, $page, $formName)=@_;
1.1 stredwic 313: my $Str = '';
314: $Str .= '<select name="';
1.6 stredwic 315: $Str .= (($page)?$page:'').'Maps"';
316: if($formName) {
317: $Str .= ' onchange="document.'.$formName.'.submit()"';
318: }
319: $Str .= '>'."\n";
1.1 stredwic 320:
321: my $selected = 0;
322: foreach my $sequence (split(':',$data->{'orderedSequences'})) {
323: $Str .= '<option';
1.7 stredwic 324: if($data->{$page.'Maps'} eq $data->{$sequence.':title'}) {
1.1 stredwic 325: $Str .= ' selected';
326: $selected = 1;
327: }
328: $Str .= '>'.$data->{$sequence.':title'}.'</option>'."\n";
329: }
330: $Str .= '<option';
331: if(!$selected) {
332: $Str .= ' selected';
333: }
334: $Str .= '>All Maps</option>'."\n";
1.9 stredwic 335:
336: $Str .= '</select>'."\n";
337:
338: return $Str;
339: }
340:
341: sub ProblemOptions {
342: my ($data, $page, $map, $formName)=@_;
343: my $Str = '';
344: $Str .= '<select name="';
345: $Str .= (($page)?$page:'').'ProblemSelect"';
346: if($formName) {
347: $Str .= ' onchange="document.'.$formName.'.submit()"';
348: }
349: $Str .= '>'."\n";
350:
351: my $selected = 0;
352: foreach my $sequence (split(':',$data->{'orderedSequences'})) {
353: if($data->{$sequence.':title'} eq $map || $map eq 'All Maps') {
354: foreach my $problem (split(':', $data->{$sequence.':problems'})) {
355: $Str .= '<option';
356: if($data->{$page.'ProblemSelect'} eq
357: $data->{$problem.':title'}) {
358: $Str .= ' selected';
359: $selected = 1;
360: }
361: $Str .= '>'.$data->{$problem.':title'}.'</option>'."\n";
362: }
363: }
364: }
365: $Str .= '<option';
366: if(!$selected) {
367: $Str .= ' selected';
368: }
369: $Str .= '>All Problems</option>'."\n";
370:
371: $Str .= '</select>'."\n";
372:
373: return $Str;
374: }
375:
376: sub PartOptions {
377: my ($data, $page, $parts, $formName)=@_;
378: my $Str = '';
379:
380: if(!defined($parts)) {
381: return '';
382: }
383:
384: $Str .= '<select name="';
385: $Str .= (($page)?$page:'').'PartSelect"';
386: if($formName) {
387: $Str .= ' onchange="document.'.$formName.'.submit()"';
388: }
389: $Str .= '>'."\n";
390:
391: my $selected = 0;
392: foreach my $part (@$parts) {
393: $Str .= '<option';
394: if($data->{$page.'PartSelect'} eq $part) {
395: $Str .= ' selected';
396: $selected = 1;
397: }
398: $Str .= '>'.$part.'</option>'."\n";
399: }
400: $Str .= '<option';
401: if(!$selected) {
402: $Str .= ' selected';
403: }
404: $Str .= '>All Parts</option>'."\n";
1.1 stredwic 405:
406: $Str .= '</select>'."\n";
407:
408: return $Str;
409: }
410:
411: sub StudentOptions {
1.4 stredwic 412: my ($cache, $students, $selectedName, $page, $formName)=@_;
1.1 stredwic 413:
414: my $Str = '';
1.4 stredwic 415: $Str .= '<select name="'.(($page)?$page:'').'Student"';
416: if($formName) {
417: $Str .= ' onchange="document.'.$formName.'.submit()"';
418: }
419: $Str .= '>'."\n";
1.1 stredwic 420:
421: my $selected=0;
422:
423: foreach (@$students) {
424: $Str .= '<option';
425: if($selectedName eq $_) {
426: $Str .= ' selected';
427: $selected = 1;
428: }
429: $Str .= '>';
430: $Str .= $cache->{$_.':fullname'};
431: $Str .= '</option>'."\n";
432: }
433:
434: $Str .= '<option';
1.3 stredwic 435: if($selectedName eq 'No Student Selected') {
436: $Str .= ' selected';
437: $selected = 1;
438: }
439: $Str .= '>No Student Selected</option>'."\n";
440:
441: $Str .= '<option';
1.1 stredwic 442: if(!$selected) {
443: $Str .= ' selected';
444: }
1.3 stredwic 445: $Str .= '>All Students</option>'."\n";
1.1 stredwic 446:
447: $Str .= '</select>'."\n";
448:
449: return $Str;
450: }
451:
452: sub StatusOptions {
453: my ($status, $formName)=@_;
454:
455: my $OpSel1 = '';
456: my $OpSel2 = '';
457: my $OpSel3 = '';
458:
459: if($status eq 'Any') { $OpSel3 = ' selected'; }
460: elsif($status eq 'Expired' ) { $OpSel2 = ' selected'; }
461: else { $OpSel1 = ' selected'; }
462:
463: my $Str = '';
464: $Str .= '<select name="Status"';
465: if(defined($formName) && $formName ne '') {
466: $Str .= ' onchange="document.'.$formName.'.submit()"';
467: }
468: $Str .= '>'."\n";
469: $Str .= '<option'.$OpSel1.'>Active</option>'."\n";
470: $Str .= '<option'.$OpSel2.'>Expired</option>'."\n";
471: $Str .= '<option'.$OpSel3.'>Any</option>'."\n";
472: $Str .= '</select>'."\n";
473: }
474:
1.12 matthew 475:
476: ########################################################
477: ########################################################
478:
479: =pod
480:
481: =item &MultipleSectionSelect()
482:
483: Inputs:
484:
485: =over 4
486:
487: =item $sections A references to an array containing the names of all the
488: sections used in a class.
489:
490: =item $selectedSections A reference to an array containing the names of the
491: currently selected sections.
492:
493: =back
494:
495: Returns: a string containing HTML for a multiple select box for
496: selecting sections of a course.
497:
498: The form element name is 'Section'. @$sections is sorted prior to output.
499:
500: =cut
501:
502: ########################################################
503: ########################################################
1.5 stredwic 504: sub MultipleSectionSelect {
505: my ($sections,$selectedSections)=@_;
506:
507: my $Str = '';
1.7 stredwic 508: $Str .= '<select name="Section" multiple="true" size="4">'."\n";
1.5 stredwic 509:
1.11 minaeibi 510: foreach (sort @$sections) {
1.5 stredwic 511: $Str .= '<option';
512: foreach my $selected (@$selectedSections) {
513: if($_ eq $selected) {
514: $Str .= ' selected=""';
515: }
516: }
517: $Str .= '>'.$_.'</option>'."\n";
518: }
519: $Str .= '</select>'."\n";
1.12 matthew 520:
1.5 stredwic 521: return $Str;
522: }
523:
1.12 matthew 524: ########################################################
525: ########################################################
526:
527: =pod
528:
529: =item &Title()
530:
531: Inputs: $pageName a string containing the name of the page to be sent
532: to &Apache::loncommon::bodytag.
533:
534: Returns: string containing being <html> and complete <head> and <title>
535: as well as a <script> to focus the current window and change its width
536: and height to 500. Why? I do not know. If you find out, please update
537: this documentation.
538:
539: =cut
540:
541: ########################################################
542: ########################################################
1.1 stredwic 543: sub Title {
544: my ($pageName)=@_;
545:
546: my $Str = '';
547:
548: $Str .= '<html><head><title>'.$pageName.'</title></head>'."\n";
1.8 www 549: $Str .= &Apache::loncommon::bodytag($pageName)."\n";
1.1 stredwic 550: $Str .= '<script>window.focus(); window.width=500;window.height=500;';
551: $Str .= '</script>'."\n";
552:
553: return $Str;
554: }
555:
1.12 matthew 556: ########################################################
557: ########################################################
558:
1.1 stredwic 559: =pod
560:
1.13 matthew 561: =item &CreateHeadings()
1.1 stredwic 562:
563: This function generates the column headings for the chart.
564:
565: =over 4
566:
1.4 stredwic 567: Inputs: $CacheData, $keyID, $headings, $spacePadding
1.1 stredwic 568:
569: $CacheData: pointer to a hash tied to the cached data database
570:
1.4 stredwic 571: $keyID: a pointer to an array containing the names of the data
1.1 stredwic 572: held in a column and is used as part of a key into $CacheData
573:
574: $headings: The names of the headings for the student information
575:
576: $spacePadding: The spaces to go between columns
577:
578: Output: $Str
579:
580: $Str: A formatted string of the table column headings.
581:
582: =back
583:
584: =cut
585:
1.12 matthew 586: ########################################################
587: ########################################################
1.4 stredwic 588: sub CreateHeadings {
589: my ($data,$keyID,$headings,$displayString,$format)=@_;
1.1 stredwic 590: my $Str='';
1.4 stredwic 591: my $formatting = '';
1.1 stredwic 592:
593: for(my $index=0; $index<(scalar @$headings); $index++) {
1.4 stredwic 594: my $currentHeading=$headings->[$index];
595: if($format eq 'preformatted') {
596: my @dataLength=split(//,$currentHeading);
597: my $length=scalar @dataLength;
598: $formatting = (' 'x
599: ($data->{$keyID->[$index].':columnWidth'}-$length));
600: }
601: my $linkdata=$keyID->[$index];
602:
1.1 stredwic 603: my $tempString = $displayString;
604: $tempString =~ s/LINKDATA/$linkdata/;
1.4 stredwic 605: $tempString =~ s/DISPLAYDATA/$currentHeading/;
606: $tempString =~ s/FORMATTING/$formatting/;
607:
1.1 stredwic 608: $Str .= $tempString;
609: }
610:
611: return $Str;
612: }
613:
1.12 matthew 614: ########################################################
615: ########################################################
616:
1.1 stredwic 617: =pod
618:
619: =item &FormatStudentInformation()
620:
1.10 matthew 621: This function produces a formatted string of the student\'s information:
1.1 stredwic 622: username, domain, section, full name, and PID.
623:
624: =over 4
625:
1.4 stredwic 626: Input: $cache, $name, $keyID, $spacePadding
1.1 stredwic 627:
628: $cache: This is a pointer to a hash that is tied to the cached data
629:
630: $name: The name and domain of the current student in name:domain format
631:
1.4 stredwic 632: $keyID: A pointer to an array holding the names used to
1.1 stredwic 633:
634: remove data from the hash. They represent the name of the data to be removed.
635:
636: $spacePadding: Extra spaces that represent the space between columns
637:
638: Output: $Str
639:
640: $Str: Formatted string.
641:
642: =back
643:
644: =cut
645:
1.12 matthew 646: ########################################################
647: ########################################################
1.1 stredwic 648: sub FormatStudentInformation {
1.4 stredwic 649: my ($data,$name,$keyID,$displayString,$format)=@_;
1.1 stredwic 650: my $Str='';
1.4 stredwic 651: my $currentColumn;
652:
653: for(my $index=0; $index<(scalar @$keyID); $index++) {
654: $currentColumn=$data->{$name.':'.$keyID->[$index]};
1.1 stredwic 655:
1.4 stredwic 656: if($format eq 'preformatted') {
657: my @dataLength=split(//,$currentColumn);
658: my $length=scalar @dataLength;
659: $currentColumn.= (' 'x
660: ($data->{$keyID->[$index].':columnWidth'}-$length));
1.1 stredwic 661: }
662:
1.4 stredwic 663: my $tempString = $displayString;
664: $tempString =~ s/DISPLAYDATA/$currentColumn/;
665:
666: $Str .= $tempString;
1.1 stredwic 667: }
668:
669: return $Str;
1.7 stredwic 670: }
1.12 matthew 671:
672: ########################################################
673: ########################################################
1.7 stredwic 674:
675: # Create progress
676: sub Create_PrgWin {
1.14 albertel 677: my ($r, $title, $heading, $number_to_do)=@_;
1.7 stredwic 678: $r->print('<script>'.
679: "popwin=open(\'\',\'popwin\',\'width=400,height=100\');".
1.14 albertel 680: "popwin.document.writeln(\'<html><head><title>$title</title></head>".
681: "<body bgcolor=\"#88DDFF\">".
1.7 stredwic 682: "<h4>$heading</h4>".
683: "<form name=popremain>".
1.14 albertel 684: "<input type=text size=55 name=remaining value=Starting></form>".
1.7 stredwic 685: "</body></html>\');".
686: "popwin.document.close();".
687: "</script>");
688:
1.14 albertel 689: my %prog_state;
1.16 albertel 690: $prog_state{'done'}=0;
691: $prog_state{'firststart'}=time;
692: $prog_state{'laststart'}=time;
693: $prog_state{'max'}=$number_to_do;
1.14 albertel 694:
1.7 stredwic 695: $r->rflush();
1.14 albertel 696: return %prog_state;
1.7 stredwic 697: }
698:
699: # update progress
700: sub Update_PrgWin {
1.14 albertel 701: my ($r,$prog_state,$displayString)=@_;
1.7 stredwic 702: $r->print('<script>popwin.document.popremain.remaining.value="'.
703: $displayString.'";</script>');
1.16 albertel 704: $$prog_state{'laststart'}=time;
1.14 albertel 705: $r->rflush();
706: }
707:
708: # increment progress state
709: sub Increment_PrgWin {
710: my ($r,$prog_state,$extraInfo)=@_;
1.16 albertel 711: $$prog_state{'done'}++;
712: my $time_est= (time - $$prog_state{'firststart'})/$$prog_state{'done'} *
713: ($$prog_state{'max'}-$$prog_state{'done'});
714: $time_est = int($time_est);
715: if (int ($time_est/60) > 0) {
716: my $min = int($time_est/60);
717: my $sec = $time_est % 60;
718: $time_est = $min.' minutes';
719: if ($sec > 1) {
720: $time_est.= ', '.$sec.' seconds';
721: } elsif ($sec > 0) {
722: $time_est.= ', '.$sec.' second';
723: }
724: } else {
725: $time_est .= ' seconds';
726: }
727:
1.14 albertel 728: $r->print('<script>popwin.document.popremain.remaining.value="'.
1.16 albertel 729: $$prog_state{'done'}.'/'.$$prog_state{'max'}.
730: ': '.$time_est.' remaining ('.(time-$$prog_state{'laststart'}).
1.14 albertel 731: ' seconds for '.$extraInfo.')";'.'</script>');
1.16 albertel 732: $$prog_state{'laststart'}=time;
1.7 stredwic 733: $r->rflush();
734: }
735:
736: # close Progress Line
737: sub Close_PrgWin {
1.14 albertel 738: my ($r,$prog_state)=@_;
1.7 stredwic 739: $r->print('<script>popwin.close()</script>'."\n");
1.14 albertel 740: undef(%$prog_state);
1.7 stredwic 741: $r->rflush();
1.1 stredwic 742: }
743:
744: 1;
745: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>