File:
[LON-CAPA] /
loncom /
interface /
lonrequestcourse.pm
Revision
1.2:
download - view:
text,
annotated -
select for diffs
Tue Aug 4 20:15:50 2009 UTC (15 years, 1 month ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD
- Add infrastructure to support stepping backwards or forwards across multiple pages in the course request form.
- For official courses, if auto-enrollment available in course's domain:
- Cross-listing of multiple course sections added to enrollment page
- Auto-adds and Auto-drops can be enabled.
- Course personnel page uses pop-up window containing lonpickuser.pm to search for users.
Saving my work.
1: # The LearningOnline Network
2: # Request a course
3: #
4: # $Id: lonrequestcourse.pm,v 1.2 2009/08/04 20:15:50 raeburn Exp $
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:
30: =head1 NAME
31:
32: Apache::lonrequestcourse.pm
33:
34: =head1 SYNOPSIS
35:
36: Allows users to request creation of new courses.
37:
38: This is part of the LearningOnline Network with CAPA project
39: described at http://www.lon-capa.org.
40:
41: =head1 SUBROUTINES
42:
43: =over
44:
45: =item handler()
46:
47: =back
48:
49: =cut
50:
51: package Apache::lonrequestcourse;
52:
53: use strict;
54: use Apache::Constants qw(:common :http);
55: use Apache::lonnet;
56: use Apache::loncommon;
57: use Apache::lonlocal;
58: use LONCAPA;
59:
60: sub handler {
61: my ($r) = @_;
62: if ($r->header_only) {
63: &Apache::loncommon::content_type($r,'text/html');
64: $r->send_http_header;
65: return OK;
66: }
67: &Apache::loncommon::content_type($r,'text/html');
68: $r->send_http_header;
69:
70: &Apache::lonhtmlcommon::clear_breadcrumbs();
71: my $dom = &get_course_dom();
72: my $action = $env{'form.action'};
73: my $state = $env{'form.state'};
74:
75: my %stored;
76: my $jscript;
77: if ((defined($state)) && (defined($action))) {
78: my %elements = &form_elements($dom);
79: if (($action eq 'view') && ($state ne 'crstype')) {
80: if (defined($env{'form.request_id'})) {
81: %stored = &retrieve_settings($dom,$env{'form.request_id'});
82: }
83: }
84: my $elementsref = {};
85: if (ref($elements{$action}) eq 'HASH') {
86: if (ref($elements{$action}{$state}) eq 'HASH') {
87: $elementsref = $elements{$action}{$state};
88: }
89: }
90: $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored);
91: }
92:
93: if ($state eq 'personnel') {
94: $jscript .= "\n".&Apache::loncommon::userbrowser_javascript();
95: }
96:
97: my $loaditems = &onload_action($action,$state);
98:
99: my %states;
100: $states{'view'} = ['pick_request','details','review','process'];
101: $states{'log'} = ['filter','display'];
102: $states{'new'} = ['courseinfo','enrollment','personnel','review','process'];
103: if (($action eq 'new') && ($env{'form.crstype'} eq 'official')) {
104: unless ($env{'form.state'} eq 'crstype') {
105: unshift (@{$states{'new'}},'codepick');
106: }
107: }
108:
109: foreach my $key (keys(%states)) {
110: if (ref($states{$key}) eq 'ARRAY') {
111: unshift (@{$states{$key}},'crstype');
112: }
113: }
114:
115: my $page = 0;
116: if (defined($action)) {
117: my $done = 0;
118: my $i=0;
119: if (ref($states{$action}) eq 'ARRAY') {
120: while ($i<@{$states{$action}} && !$done) {
121: if ($states{$action}[$i] eq $state) {
122: $page = $i;
123: $done = 1;
124: }
125: $i++;
126: }
127: }
128: }
129:
130: my %can_request;
131: my $canreq = &check_can_request($dom,\%can_request);
132: if ($action eq 'new') {
133: if ($canreq) {
134: if ($state eq 'crstype') {
135: &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems);
136: } else {
137: &request_administration($r,$action,$state,$page,\%states,$dom,$jscript,
138: $loaditems);
139: }
140: } else {
141: $r->print(&header('Course Requests').
142: '<div class="LC_warning">'.
143: &mt('You do not have privileges to request creation of courses.').
144: '</div>'.&Apache::loncommon::end_page());
145: }
146: } elsif ($action eq 'view') {
147: &print_request_status($jscript,$loaditems);
148: } elsif ($action eq 'log') {
149: &print_request_logs($jscript,$loaditems);
150: } else {
151: &print_main_menu($r,\%can_request,\%states,$dom,$jscript);
152: }
153: return OK;
154: }
155:
156: sub header {
157: my ($bodytitle,$jscript,$loaditems,$jsextra) = @_;
158: if ($jscript) {
159: $jscript = '<script type="text/javascript">'.
160: $jscript.'</script>'."\n";
161: }
162: if ($loaditems) {
163: $loaditems = {'add_entries' => $loaditems,};
164: }
165: return &Apache::loncommon::start_page($bodytitle,$jscript.$jsextra,$loaditems);
166: }
167:
168: sub form_elements {
169: my ($dom) = @_;
170: my %elements =
171: (
172: new => {
173: crstype => {
174: crstype => 'selectbox',
175: action => 'selectbox',
176: },
177: courseinfo => {
178: cdescr => 'text',
179: clonecourse => 'text',
180: clonedomain => 'selectbox',
181: datemode => 'radio',
182: dateshift => 'text',
183: },
184: enrollment => {
185: startaccess_month => 'selectbox',
186: startaccess_hour => 'selectbox',
187: endaccess_month => 'selectbox',
188: endaccess_hour => 'selectbox',
189: startaccess_day => 'text',
190: startaccess_year => 'text',
191: startaccess_minute => 'text',
192: startaccess_second => 'text',
193: endaccess_day => 'text',
194: endaccess_year => 'text',
195: endaccess_minute => 'text',
196: endaccess_second => 'text',
197: no_end_date => 'checkbox',
198: },
199: personnel => {
200: persontotal => 'hidden',
201: addperson => 'checkbox',
202: },
203: },
204: view => {
205: crstype => {
206: crstype => 'selectbox',
207: action => 'selectbox',
208: },
209: },
210: );
211: my (@codetitles,%cat_titles,%cat_order,@code_order,$lastitem);
212: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
213: \%cat_order,\@code_order);
214: my $numtitles = scalar(@codetitles);
215: if ($numtitles) {
216: my %extras;
217: $lastitem = pop(@codetitles);
218: $extras{'instcode_'.$lastitem} = 'text';
219: foreach my $item (@codetitles) {
220: $extras{'instcode_'.$item} = 'selectbox';
221: }
222: $elements{'new'}{'codepick'} = \%extras;
223: }
224: if (&Apache::lonnet::auto_run('',$dom)) {
225: my %extras = (
226: sectotal => 'hidden',
227: startenroll_month => 'selectbox',
228: startenroll_hour => 'selectbox',
229: endenroll_month => 'selectbox',
230: endenroll_hour => 'selectbox',
231: startenroll_day => 'text',
232: startenroll_year => 'text',
233: startenroll_minute => 'text',
234: startenroll_second => 'text',
235: endenroll_day => 'text',
236: endenroll_year => 'text',
237: endenroll_minute => 'text',
238: endenroll_second => 'text',
239: crosslisttotal => 'hidden',
240: addcrosslist => 'checkbox',
241: autoadds => 'radio',
242: autodrops => 'radio',
243: );
244: if ($env{'form.sectotal'} > 0) {
245: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
246: $extras{'sec_'.$i} = 'checkbox',
247: $extras{'secnum_'.$i} = 'text',
248: $extras{'loncapasec_'.$i} = 'checkbox',
249: }
250: }
251: my $crosslisttotal = $env{'form.crosslisttotal'};
252: if (!defined($crosslisttotal)) {
253: $crosslisttotal = 1;
254: }
255: if ($crosslisttotal > 0) {
256: for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) {
257: if ($numtitles) {
258: $extras{'crosslist_'.$i.'_'.$lastitem} = 'text';
259: }
260: if (@codetitles > 0) {
261: foreach my $item (@codetitles) {
262: $extras{'crosslist_'.$i.'_'.$item} = 'selectbox';
263: }
264: }
265: $extras{'crosslist_'.$i} = 'checkbox';
266: $extras{'crosslist_'.$i.'_instsec'} = 'text',
267: $extras{'crosslist_'.$i.'_lcsec'} = 'text',
268: }
269: }
270: my %mergedhash = (%{$elements{'new'}{'enrollment'}},%extras);
271: %{$elements{'new'}{'enrollment'}} = %mergedhash;
272: }
273: my %people;
274: my $persontotal = $env{'form.persontotal'};
275: if (!defined($persontotal)) {
276: $persontotal = 1;
277: }
278: for (my $i=0; $i<$persontotal; $i++) {
279: $people{'person_'.$i.'_uname'} = 'text',
280: $people{'person_'.$i.'_dom'} = 'selectbox',
281: $people{'person_'.$i.'_hidedom'} = 'hidden',
282: $people{'person_'.$i.'_first'} = 'text',
283: $people{'person_'.$i.'_last'} = 'text',
284: $people{'person_'.$i.'_email'} = 'text',
285: $people{'person_'.$i.'_role'} = 'selectbox',
286: $people{'person_'.$i.'_sec'} = 'selectbox',
287: $people{'person_'.$i.'_newsec'} = 'text',
288: $people{'person_'.$i.'_sections'} = 'hidden',
289: }
290: my %personnelhash = (%{$elements{'new'}{'personnel'}},%people);
291: %{$elements{'new'}{'personnel'}} = %personnelhash;
292: return %elements;
293: }
294:
295: sub onload_action {
296: my ($action,$state) = @_;
297: my %loaditems;
298: if (($action eq 'new') || ($action eq 'view')) {
299: $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)';
300: }
301: return \%loaditems;
302: }
303:
304: sub check_can_request {
305: my ($dom,$can_request) = @_;
306: my $canreq = 0;
307: if (ref($can_request) eq 'HASH') {
308: foreach my $type ('official','unofficial','community') {
309: if (&Apache::lonnet::usertools_access($env{'user.name'},
310: $env{'user.domain'},
311: $type,undef,'requestcourses')) {
312: $canreq ++;
313: if ($dom eq $env{'user.domain'}) {
314: $can_request->{$type} = 1;
315: }
316: }
317: if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
318: my @curr = split(',',$env{'environment.reqcrsotherdom.'.$type});
319: if (@curr > 0) {
320: $canreq ++;
321: unless ($dom eq $env{'user.domain'}) {
322: if (grep(/^\Q$dom\E$/,@curr)) {
323: $can_request->{$type} = 1;
324: }
325: }
326: }
327: }
328: }
329: }
330: return $canreq;
331: }
332:
333: sub print_main_menu {
334: my ($r,$can_request,$states,$dom,$jscript,$loaditems) = @_;
335: my $onchange;
336: unless ($env{'form.interface'} eq 'textual') {
337: $onchange = 1;
338: }
339:
340: my $nextstate_setter = "\n";
341: if (ref($states) eq 'HASH') {
342: foreach my $key (keys(%{$states})) {
343: if (ref($states->{$key}) eq 'ARRAY') {
344: $nextstate_setter .=
345: " if (actionchoice == '$key') {
346: nextstate = '".$states->{$key}[1]."';
347: }
348: ";
349: }
350: }
351: }
352:
353: my $js = <<"END";
354:
355: function nextPage(formname) {
356: var crschoice = document.requestcrs.crstype.value;
357: var actionchoice = document.requestcrs.action.value;
358: if (check_can_request(crschoice,actionchoice) == true) {
359: if ((actionchoice == 'new') && (crschoice == 'official')) {
360: nextstate = 'codepick';
361: } else {
362: $nextstate_setter
363: }
364: formname.state.value= nextstate;
365: formname.submit();
366: }
367: return;
368: }
369:
370: function check_can_request(crschoice,actionchoice) {
371: var official = '';
372: var unofficial = '';
373: var community = '';
374: END
375:
376: foreach my $item (keys(%{$can_request})) {
377: $js .= "
378: $item = 1;
379: ";
380: }
381: my %lt = &Apache::lonlocal::texthash(
382: official => 'You are not permitted to request creation of an official course in this domain.',
383: unofficial => 'You are not permitted to request creation of an unofficial course in this domain.',
384: community => 'You are not permitted to request creation of a community this domain.',
385: all => 'You must choose a specific course type when making a new course request.\\nAll types is not allowed.',
386: );
387: $js .= <<END;
388: if (crschoice == 'official') {
389: if (official != 1) {
390: alert("$lt{'official'}");
391: return false;
392: }
393: } else {
394: if (crschoice == 'unofficial') {
395: if (unofficial != 1) {
396: alert("$lt{'unofficial'}");
397: return false;
398: }
399: } else {
400: if (crschoice == 'community') {
401: if (community != 1) {
402: alert("$lt{'community'}");
403: return false;
404: }
405: } else {
406: if (actionchoice == 'new') {
407: alert("$lt{'all'}");
408: return false;
409: }
410: }
411: }
412: }
413: return true;
414: }
415:
416: END
417:
418: $r->print(&header('Course Requests',$js.$jscript,$loaditems).
419: '<p><div>'.
420: '<form name="domforcourse" method="post" action="/adm/requestcourse">'.
421: &Apache::lonhtmlcommon::start_pick_box().
422: &Apache::lonhtmlcommon::row_title('Domain').
423: &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange));
424: if (!$onchange) {
425: $r->print(' <input type="submit" name="godom" value="'.
426: &mt('Change').'" />');
427: }
428: $r->print(&Apache::lonhtmlcommon::row_closure(1).
429: &Apache::lonhtmlcommon::end_pick_box().'</form></div>');
430:
431: my $formname = 'requestcrs';
432: my $nexttext = &mt('Next');
433: $r->print('<div><form name="'.$formname.'" method="post" action="/adm/requestcourse">'.
434: &Apache::lonhtmlcommon::start_pick_box().
435: &Apache::lonhtmlcommon::row_title('Action').'
436: <input type="hidden" name="showdom" value="'.$dom.'" />
437: <select size="1" name="action" >
438: <option value="new">'.&mt('New request').'</option>
439: <option value="view">'.&mt('View/Modify/Cancel pending requests').'</option>
440: <option value="log">'.&mt('View request history').'</option>
441: </select>'.
442: &Apache::lonhtmlcommon::row_closure().
443: &Apache::lonhtmlcommon::row_title('Course Type').'
444: <select size="1" name="crstype">
445: <option value="any">'.&mt('All types').'</option>
446: <option value="official" selected="selected">'.&mt('Official course').'</option>
447: <option value="unofficial">'.&mt('Unofficial course').'</option>
448: <option value="community">'.&mt('Community').'</option>
449: </select>
450: <input type="hidden" name="state" value="crstype" />'.
451: &Apache::lonhtmlcommon::row_closure(1).
452: &Apache::lonhtmlcommon::end_pick_box().'<br />
453: <input type="button" name="next" value="'.$nexttext.'" onclick="javascript:nextPage(document.'.$formname.')" />
454: </form></div>');
455: $r->print(&Apache::loncommon::end_page());
456: return;
457: }
458:
459: sub request_administration {
460: my ($r,$action,$state,$page,$states,$dom,$jscript,$loaditems) = @_;
461: my $js;
462: if (($action eq 'new') || ($action eq 'view')) {
463: $js = <<END;
464:
465: function nextPage(formname,nextstate) {
466: formname.state.value= nextstate;
467: formname.submit();
468: }
469: function backPage(formname,prevstate) {
470: formname.state.value = prevstate;
471: formname.submit();
472: }
473:
474: END
475: }
476: if ($action eq 'new') {
477: my $jsextra;
478: unless (($state eq 'review') || ($state eq 'process')) {
479: $jsextra = "\n".&Apache::loncommon::coursebrowser_javascript($dom);
480: }
481: $r->print(&header('Request a course',$js.$jscript,$loaditems,$jsextra));
482: if ($state eq 'review') {
483: &print_review($r,$state,$dom);
484: } elsif ($state eq 'process') {
485: &print_request_outcome($r,$state,$dom);
486: } else {
487: &print_request_form($r,$action,$state,$page,$states,$dom);
488: }
489: } elsif ($action eq 'view') {
490: $r->print(&header('Manage course requests',$js.$jscript,$loaditems));
491: } elsif ($action eq 'log') {
492: $r->print(&coursereq_log('View request log',$jscript,$loaditems));
493: }
494: $r->print(&Apache::loncommon::end_page());
495: return;
496: }
497:
498: sub print_request_form {
499: my ($r,$action,$state,$page,$states,$dom) = @_;
500: my $formname = 'requestcrs';
501: my ($next,$prev,$message,$output,$codepicker,$crstype);
502: $prev = $states->{$action}[$page-1];
503: $next = $states->{$action}[$page+1];
504: $crstype = $env{'form.crstype'};
505: $r->print('<form name="'.$formname.'" method="post" action="/adm/requestcourse">');
506: my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk);
507: if ($crstype eq 'official') {
508: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
509: \%cat_order,\@code_order);
510: if ($env{'form.instcode'} ne '') {
511: $instcode = $env{'form.instcode'};
512: }
513: }
514: if ($prev eq 'codepick') {
515: if (@code_order > 0) {
516: my $message;
517: if ($instcode eq '') {
518: foreach my $item (@code_order) {
519: $instcode .= $env{'form.instcode_'.$item};
520: }
521: $r->print('<input type="hidden" name="instcode" value="'.$instcode.'" />'."\n");
522: }
523: if ($instcode ne '') {
524: $code_chk = &Apache::lonnet::auto_validate_instcode('',$dom,$instcode);
525: if ($code_chk eq 'ok') {
526: $message = '<div class="LC_info">'.
527: &mt('The chosen course category [_1] is valid.','<b>'.
528: $instcode.'</b>').'</div>';
529: } else {
530: $message = '<div class="LC_warning">'.
531: &mt('No course was found matching your choice of institutional course category.');
532: if ($code_chk ne '') {
533: $message .= '<br />'.$code_chk;
534: }
535: $message .= '</div>';
536: }
537: } else {
538: $message = '<div class="LC_warning">'.
539: &mt('No course was found matching your choice of institutional course category.');
540: }
541: unless ($code_chk eq 'ok') {
542: $prev = 'crstype';
543: }
544: $r->print($message);
545: }
546: }
547: if ($prev eq 'crstype') {
548: if (@code_order > 0) {
549: $codepicker = &coursecode_form($dom,'instcode',\@codetitles,
550: \%cat_titles,\%cat_order);
551: if ($codepicker) {
552: $r->print('<div>'.&Apache::lonhtmlcommon::start_pick_box().$codepicker.
553: &Apache::lonhtmlcommon::end_pick_box().'</div>');
554: } else {
555: $r->print(&courseinfo_form($dom,$formname,$crstype));
556: }
557: } else {
558: $r->print(&courseinfo_form($dom,$formname,$crstype));
559: }
560: } elsif ($prev eq 'codepick') {
561: $r->print(&courseinfo_form($dom,$formname,$crstype));
562: } elsif ($state eq 'enrollment') {
563: $r->print(&print_enrollment_menu($formname,$instcode,$dom,\@codetitles,
564: \%cat_titles,\%cat_order,\@code_order));
565: } elsif ($state eq 'personnel') {
566: $r->print(&print_personnel_menu($dom,$formname));
567: }
568: my @excluded = ('counter');
569: my %elements = &form_elements($dom);
570: if (ref($states) eq 'HASH') {
571: if (ref($states->{$action}) eq 'ARRAY') {
572: my @items = @{$states->{$action}};
573: my $numitems = scalar(@items);
574: if ($numitems) {
575: for (my $i=$numitems-1; $i>=0; $i--) {
576: if (ref($elements{$action}) eq 'HASH') {
577: if (ref($elements{$action}{$items[$i]}) eq 'HASH') {
578: foreach my $key (keys(%{$elements{$action}{$items[$i]}})) {
579: push(@excluded,$key);
580: }
581: }
582: }
583: last if ($items[$i] eq $state);
584: }
585: }
586: }
587: }
588: if (grep(/^instcode_/,@excluded)) {
589: push(@excluded,'instcode');
590: }
591: $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).'</form>');
592: &display_navbuttons($r,$formname,$prev,'Previous',$next,'Next');
593: return;
594: }
595:
596: sub print_enrollment_menu {
597: my ($formname,$instcode,$dom,$codetitles,$cat_titles,$cat_order,$code_order) =@_;
598: my ($sections,$autoenroll,$access_dates);
599: my $starttime = time;
600: my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
601:
602: my %accesstitles = (
603: 'start' => 'Default start access',
604: 'end' => 'Default end accss',
605: );
606: my %enrolltitles = (
607: 'start' => 'Start auto-enrollment',
608: 'end' => 'End auto-enrollment',
609: );
610: if ($env{'form.crstype'} eq 'official') {
611: if (&Apache::lonnet::auto_run('',$dom)) {
612: my ($section_form,$crosslist_form,$autoenroll_form);
613: $section_form = &inst_section_selector($dom,$instcode);
614: my $crosslisttotal = $env{'form.crosslisttotal'};
615: if (!defined($crosslisttotal)) {
616: $crosslisttotal = 1;
617: }
618: if ($env{'form.addcrosslist'}) {
619: $crosslisttotal ++;
620: }
621: for (my $i=0; $i<$crosslisttotal; $i++) {
622: $crosslist_form .= &coursecode_form($dom,'crosslist',$codetitles,
623: $cat_titles,$cat_order,$i);
624: }
625: if ($crosslist_form) {
626: $crosslist_form .=
627: &Apache::lonhtmlcommon::row_title(&mt('Add another?')).
628: '<input name="crosslisttotal" type="hidden" value="'.$crosslisttotal.'" />'.
629: '<input name="addcrosslist" type="checkbox" value="'.$crosslisttotal.'"'.
630: ' onclick="javascript:nextPage(document.'.$formname.",'".$env{'form.state'}.
631: "'".');" />'.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1);
632: }
633: if ($section_form || $crosslist_form) {
634: $sections = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
635: $section_form.$crosslist_form.
636: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
637: }
638: $autoenroll_form =
639: &Apache::lonhtmlcommon::row_title(&mt('Add registered students automatically')).
640: '<span class="LC_nobreak"><label>'.
641: '<input type="radio" name="autoadds" value="1">'.
642: &mt('Yes').'</label>'.(' 'x3).'<label>'.
643: '<input type="radio" name="autoadds" value="0" checked="checked">'.
644: &mt('No').'</label></span>'.
645: &Apache::lonhtmlcommon::row_closure().
646: &Apache::lonhtmlcommon::row_title(&mt('Drop unregistered students automatically')).
647: '<span class="LC_nobreak"><label>'.
648: '<input type="radio" name="autodrops" value="1">'.
649: &mt('Yes').'</label>'.(' 'x3).'<label>'.
650: '<input type="radio" name="autodrops" value="0" checked="checked">'.
651: &mt('No').'</label></span>'.
652: &Apache::lonhtmlcommon::row_closure().
653: &date_setting_table($starttime,$endtime,$formname,'enroll',%enrolltitles);
654: if ($autoenroll_form) {
655: $autoenroll = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
656: $autoenroll_form.
657: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
658: }
659: }
660: }
661: my $access_dates_form =
662: &date_setting_table($starttime,$endtime,$formname,'access',%accesstitles);
663: if ($access_dates_form) {
664: $access_dates = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
665: $access_dates_form.
666: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
667: }
668: return $sections.$autoenroll.$access_dates;
669: }
670:
671: sub inst_section_selector {
672: my ($dom,$instcode) = @_;
673: my @sections = &Apache::lonnet::auto_get_sections(undef,$dom,$instcode);
674: my $sectotal = scalar(@sections);
675: my $output;
676: if ($sectotal) {
677: $output .= &Apache::lonhtmlcommon::row_title('Sections').
678: &Apache::loncommon::start_data_table().
679: &Apache::loncommon::start_data_table_row().
680: '<th>'.&mt('Include?').'<input type="hidden" name="sectotal" '.
681: 'value="'.$sectotal.'"</th>'.
682: '<th>'.&mt('Institutional Section').'</th>'.
683: '<th>'.&mt('LON-CAPA section').'</th>'.
684: &Apache::loncommon::end_data_table_row();
685: for (my $i=0; $i<@sections; $i++) {
686: my $colflag = $i%2;
687: $output .= &Apache::loncommon::start_data_table_row().
688: '<td><input type="checkbox" name="sec_'.$i.
689: '" checked="checked" /></td>'.
690: '<td>'.$sections[$i].
691: '<input type="hidden" name="secnum_'.$i.'" value="'.
692: $sections[$i].'" /></td>'.
693: '<td><input type="text" size="10" name="loncapasec_'.$i.
694: '" value="'.$sections[$i].'" /></td>'.
695: &Apache::loncommon::end_data_table_row();
696: }
697: $output .= &Apache::loncommon::end_data_table().
698: &Apache::lonhtmlcommon::row_closure();
699: }
700: return $output;
701: }
702:
703: sub date_setting_table {
704: my ($starttime,$endtime,$formname,$suffix,%datetitles) = @_;
705: my ($perpetual,$table);
706: my $startform = &Apache::lonhtmlcommon::date_setter($formname,'start'.$suffix,
707: $starttime,'','','',1,'','','',1);
708: my $endform = &Apache::lonhtmlcommon::date_setter($formname,'end'.$suffix,
709: $endtime,'','','',1,'','','',1);
710: if ($suffix eq 'access') {
711: $perpetual = ' <span class="LC_nobreak"><label>'.
712: '<input type="checkbox" name="no_end_date" />'.
713: &mt('No end date').'</label></span>';
714: }
715: $table = &Apache::lonhtmlcommon::row_title($datetitles{'start'}).
716: $startform.
717: &Apache::lonhtmlcommon::row_closure().
718: &Apache::lonhtmlcommon::row_title($datetitles{'end'}).
719: $endform.$perpetual.
720: &Apache::lonhtmlcommon::row_closure(1);
721: return $table;
722: }
723:
724: sub print_personnel_menu {
725: my ($dom,$formname) = @_;
726: my $output = '<div>'.&Apache::lonhtmlcommon::start_pick_box();
727: my $persontotal = $env{'form.persontotal'};
728: if (!defined($persontotal)) {
729: $persontotal = 1;
730: }
731: if ($env{'form.addperson'}) {
732: $persontotal ++;
733: }
734: my $userlinktxt = &mt('Set User');
735: my @items = ('uname','dom','last','first','email','hidedom');
736:
737: my $roleoptions;
738: my @roles = &Apache::lonuserutils::roles_by_context('course');
739: foreach my $role (@roles) {
740: my $plrole=&Apache::lonnet::plaintext($role);
741: $roleoptions .= ' <option value="'.$role.'">'.$plrole.'</option>'."\n";
742: }
743: my %customroles=&Apache::lonuserutils::my_custom_roles();
744: if (keys(%customroles) > 0) {
745: foreach my $cust (sort(keys(%customroles))) {
746: my $custrole='cr_cr_'.$env{'user.domain'}.
747: '_'.$env{'user.name'}.'_'.$cust;
748: $roleoptions .= ' <option value="'.$custrole.'">'.$cust.'</option>'."\n";
749: }
750: }
751:
752: my @currsecs;
753: if ($env{'form.sectotal'}) {
754: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
755: if (defined($env{'form.loncapasec_'.$i})) {
756: my $lcsec = $env{'form.loncapasec_'.$i};
757: unless (grep(/^\Q$lcsec\E$/,@currsecs)) {
758: push(@currsecs,$lcsec);
759: }
760: }
761: }
762: }
763:
764: my ($existtitle,$existops,$existmult,$newtitle,$seccolspan);
765: if (@currsecs) {
766: my $existsize = scalar(@currsecs);
767: if ($existsize > 3) {
768: $existsize = 3;
769: }
770: if ($existsize > 1) {
771: $existmult = ' multiple="multiple" size="'.$existsize.'" ';
772: }
773: @currsecs = sort { $a <=> $b } (@currsecs);
774: $existtitle = &mt('Official').': ';
775: $existops = '<option value="">'.&mt('None').'</option>';
776: foreach my $sec (@currsecs) {
777: $existops .= '<option value="'.$sec.'">'.$sec.'</option>'."\n";
778: }
779: $seccolspan = ' colspan="2"';
780: $newtitle = &mt('Other').': ';
781: }
782:
783: for (my $i=0; $i<$persontotal; $i++) {
784: my @linkargs = map { 'person_'.$i.'_'.$_ } (@items);
785: my $linkargstr = join("','",@linkargs);
786: my $userlink = &Apache::loncommon::selectuser_link($formname,@linkargs,$userlinktxt);
787: my $uname_form = '<input type="text" name="person_'.$i.'_uname" value=""'.
788: ' onFocus="this.blur();'.
789: 'openuserbrowser('."'$formname','$linkargstr'".');" />';
790: my $onchange = 'javascript:fix_domain('."'$formname','person_".$i."_dom',".
791: "'person_".$i."_hidedom'".');'.
792: 'openuserbrowser('."'$formname','$linkargstr'".');';
793: my $udom_form = &Apache::loncommon::select_dom_form($dom,'person_'.$i.'_dom','',
794: 1,$onchange).
795: '<input type="hidden" name="person_'.$i.'_hidedom" value="'.$dom.'" />';
796: my %form_elems;
797: foreach my $item (@items) {
798: next if (($item eq 'dom') || ($item eq 'uname') || ($item eq 'hidedom'));
799: $form_elems{$item} = '<input type="text" name="person_'.$i.'_'.$item.'" '.
800: 'value="" readonly="readonly" />';
801: }
802: my $roleselector = '<select name="person_'.$i.'_role">'."\n".
803: $roleoptions.'</select>';
804: my $sectionselector;
805: if (@currsecs) {
806: $sectionselector = $existtitle.'<select name="person_'.$i.'_sec"'.
807: $existmult.'>'."\n".$existops.'</select>'.(' ' x3);
808: }
809: $sectionselector .= $newtitle.
810: '<input type="text" name="person_'.$i.'_newsec" size="15" value="" />'.
811: '<input type="hidden" name="person_'.$i.'_sections" value="" />'."\n";
812:
813: $output .=
814: &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel').'<br />'.
815: '<span class="LC_nobreak">'.$userlink.
816: '</span>').
817: '<table><tr><td align="center" valign="top">'.&mt('Username').'<br />'.$uname_form.'</td>'."\n".
818: '<td align="center" valign="top" colspan="2">'.&mt('Domain').'<br />'.$udom_form.'</td></tr><tr>'."\n".
819: '<td align="center" valign="top">'.&mt('First Name').'<br />'.$form_elems{'first'}.'</td>'."\n".
820: '<td align="center" valign="top">'.&mt('Last Name').'<br />'.$form_elems{'last'}.'</td>'."\n".
821: '<td align="center" valign="top">'.&mt('E-mail').'<br />'.$form_elems{email}.'</td></tr>'."\n".
822: '<tr><td align="center" valign="top">'.&mt('Role').'<br />'.$roleselector.'</td>'."\n".
823: '<td'.$seccolspan.' align="center" valign="top">'.&mt('Section(s)').'<br />'.$sectionselector.'</td>'."\n".
824: '</tr></table>'.&Apache::lonhtmlcommon::row_closure();
825: }
826: $output .= &Apache::lonhtmlcommon::row_title(&mt('Add another?')).
827: '<input name="persontotal" type="hidden" value="'.$persontotal.'" />'.
828: '<input name="addperson" type="checkbox" value="'.$persontotal.'"'.
829: ' onclick="javascript:nextPage(document.'.$formname.",'".$env{'form.state'}.
830: "'".');" />'.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1).
831: &Apache::lonhtmlcommon::end_pick_box().'</div>';
832: return $output;
833: }
834:
835: sub print_request_status {
836: return;
837: }
838:
839: sub print_request_logs {
840: return;
841: }
842:
843: sub print_review {
844: my ($r,$state,$dom) = @_;
845: return;
846: }
847:
848: sub courseinfo_form {
849: my ($dom,$formname,$crstype) = @_;
850: my $output = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
851: &Apache::lonhtmlcommon::row_title('Course Description').
852: '<input type="text" size="40" name="cdescr" />'.
853: &Apache::lonhtmlcommon::row_closure(1).
854: &Apache::lonhtmlcommon::end_pick_box().'</div>'.
855: '<div>'.&clone_form($dom,$formname,$crstype).'</div>'."\n";
856: return $output;
857: }
858:
859: sub clone_form {
860: my ($dom,$formname,$crstype) = @_;
861: my $type = 'Course';
862: if ($crstype eq 'community') {
863: $type = 'Community';
864: }
865: my $cloneform = &Apache::loncommon::select_dom_form($dom,'clonedomain').
866: &Apache::loncommon::selectcourse_link($formname,'clonecourse','clonedomain','','','',$type);
867: my %lt = &Apache::lonlocal::texthash(
868: 'cid' => 'Course ID',
869: 'dmn' => 'Domain',
870: 'dsh' => 'Date Shift',
871: 'ncd' => 'Do not clone date parameters',
872: 'prd' => 'Clone date parameters as-is',
873: 'shd' => 'Shift date parameters by number of days',
874: );
875: my $output .=
876: &Apache::lonhtmlcommon::start_pick_box().
877: &Apache::lonhtmlcommon::row_title($lt{'cid'}).'<label>'.
878: '<input type="text" size="25" name="clonecourse" value="" onfocus="this.blur();'.
879: 'opencrsbrowser('."'$formname','clonecourse','clonedomain','','','','$type'".');" />'.
880: '</label>'.&Apache::lonhtmlcommon::row_closure(1).'<label>'.
881: &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'</label>'.
882: $cloneform.'</label>'.&Apache::lonhtmlcommon::row_closure().
883: &Apache::lonhtmlcommon::row_title($lt{'dsh'}).'<label>'.
884: '<input type="radio" name="datemode" value="delete" /> '.$lt{'ncd'}.
885: '</label><br /><label>'.
886: '<input type="radio" name="datemode" value="preserve" /> '.$lt{'prd'}.
887: '</label><br /><label>'.
888: '<input type="radio" name="datemode" value="shift" checked="checked" /> '.
889: $lt{'shd'}.'</label>'.
890: '<input type="text" size="5" name="dateshift" value="365" />'.
891: &Apache::lonhtmlcommon::row_closure(1).
892: &Apache::lonhtmlcommon::end_pick_box();
893: return $output;
894: }
895:
896: sub coursecode_form {
897: my ($dom,$context,$codetitles,$cat_titles,$cat_order,$num) = @_;
898: my $output;
899: my %rowtitle = (
900: instcode => 'Course Category',
901: crosslist => 'Cross Listed Course',
902: );
903: if ((ref($codetitles) eq 'ARRAY') && (ref($cat_titles) eq 'HASH') &&
904: (ref($cat_order))) {
905: my ($sel,$instsec,$lcsec);
906: $sel = $context;
907: if ($context eq 'crosslist') {
908: $sel .= '_'.$num;
909: $instsec = &mt('Institutional section').'<br />'.
910: '<input type="text" size="10" name="'.$sel.'_instsec" />';
911: $lcsec = &mt('LON-CAPA section').'<br />'.
912: '<input type="text" size="10" name="'.$sel.'_lcsec" />';
913: }
914: if (@{$codetitles} > 0) {
915: my $lastitem = pop(@{$codetitles});
916: my $lastinput = '<input type="text" size="5" name="'.$sel.'_'. $lastitem.'" />';
917: if (@{$codetitles} > 0) {
918: $output = &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
919: '<table><tr>';
920: if ($context eq 'crosslist') {
921: $output .= '<td>'.&mt('Include?').'<br />'.
922: '<input type="checkbox" name="'.$sel.'" value="1" /></td>';
923: }
924: foreach my $title (@{$codetitles}) {
925: if (ref($cat_order->{$title}) eq 'ARRAY') {
926: if (@{$cat_order->{$title}} > 0) {
927: $output .= '<td align="center">'.$title.'<br />'."\n".
928: '<select name="'.$sel.'_'.$title.'">'."\n".
929: ' <option value="" selected="selected">'.
930: &mt('Select').'</option>'."\n";
931: foreach my $item (@{$cat_order->{$title}}) {
932: my $longitem = $item;
933: if (ref($cat_titles->{$title}) eq 'HASH') {
934: if ($cat_titles->{$title}{$item} ne '') {
935: $longitem = $cat_titles->{$title}{$item};
936: }
937: }
938: $output .= '<option value="'.$item.'">'.$longitem.
939: '</option>'."\n";
940: }
941: }
942: $output .= '</select></td>'."\n";
943: }
944: }
945: if ($context eq 'crosslist') {
946: $output .= '<td align="center">'.$lastitem.'<br />'."\n".
947: $lastinput.'</td><td align="center">'.$instsec.'</td>'.
948: '<td align="center">'.$lcsec.'</td></tr></table>';
949: } else {
950: $output .= '</tr></table>'.
951: &Apache::lonhtmlcommon::row_closure().
952: &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
953: $lastinput;
954: }
955: } else {
956: if ($context eq 'crosslist') {
957: $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
958: '<table><tr>'.
959: '<td align="center">'.$lastitem.'<br />'.$lastinput.'</td>'.
960: '<td align="center">'.$instsec.'</td><td>'.$lcsec.'</td>'.
961: '</tr></table>';
962: } else {
963: $output .= &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
964: $lastinput;
965: }
966: }
967: $output .= &Apache::lonhtmlcommon::row_closure(1);
968: push(@$codetitles,$lastitem);
969: } elsif ($context eq 'crosslist') {
970: $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
971: '<table><tr><td align="center">'.
972: '<span class="LC_nobreak">'.&mt('Include?').
973: '<input type="checkbox" name="'.$sel.'" value="1" /></span>'.
974: '</td><td align="center">'.&mt('Institutional ID').'<br />'.
975: '<input type="text" size="10" name="'.$sel.'_instsec" />'.
976: '</td><td align="center">'.$lcsec.'</td></tr></table>'.
977: &Apache::lonhtmlcommon::row_closure(1);
978: }
979: }
980: return $output;
981: }
982:
983: sub get_course_dom {
984: my $codedom = &Apache::lonnet::default_login_domain();
985: if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
986: $codedom = $env{'user.domain'};
987: if ($env{'request.role.domain'} ne '') {
988: $codedom = $env{'request.role.domain'};
989: }
990: }
991: if ($env{'form.showdom'} ne '') {
992: if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
993: $codedom = $env{'form.showdom'};
994: }
995: }
996: return $codedom;
997: }
998:
999: sub display_navbuttons {
1000: my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
1001: $r->print('<div class="LC_navbuttons">');
1002: if ($prev) {
1003: $r->print('
1004: <input type="button" name="previous" value = "'.$prevtext.'"
1005: onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
1006: ');
1007: } elsif ($prevtext) {
1008: $r->print('
1009: <input type="button" name="previous" value = "'.$prevtext.'"
1010: onclick="javascript:history.back()"/>
1011: ');
1012: }
1013: if ($next) {
1014: $r->print('
1015: <input type="button" name="next" value="'.$nexttext.'"
1016: onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
1017: }
1018: $r->print('</div>');
1019: }
1020:
1021: sub print_request_outcome {
1022: return;
1023: }
1024:
1025: sub retrieve_settings {
1026: my ($dom,$request_id) = @_;
1027: my %reqinfo = &get_request_settings($request_id,$dom);
1028: my %stored;
1029: $stored{'cdescr'} = &unescape($reqinfo{'description'});
1030: $stored{'startaccess'} = $reqinfo{'startaccess'};
1031: $stored{'endaccess'} = $reqinfo{'endaccess'};
1032: if ($stored{'endaccess'} == 0) {
1033: $stored{'no_end_date'} = 1;
1034: }
1035: $stored{'startenroll'} = $reqinfo{'startenroll'};
1036: $stored{'endenroll'} = $reqinfo{'endenroll'};
1037: $stored{'crosslist'} = $reqinfo{'crosslist'};
1038: $stored{'clonecourse'} = $reqinfo{'clonecourse'};
1039: $stored{'clonedomain'} = $reqinfo{'clonedomain'};
1040: $stored{'sections'} = $reqinfo{'sections'};
1041: $stored{'personnel'} = $reqinfo{'personnel'};
1042:
1043: return %stored;
1044: }
1045:
1046: sub get_request_settings {
1047: my ($request_id,$dom);
1048: }
1049:
1050: 1;
1051:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>