--- loncom/interface/lonrequestcourse.pm	2009/09/05 20:24:15	1.28
+++ loncom/interface/lonrequestcourse.pm	2009/09/08 13:05:00	1.31
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Request a course
 #
-# $Id: lonrequestcourse.pm,v 1.28 2009/09/05 20:24:15 raeburn Exp $
+# $Id: lonrequestcourse.pm,v 1.31 2009/09/08 13:05:00 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -122,6 +122,7 @@ use Apache::lonnet;
 use Apache::loncommon;
 use Apache::lonlocal;
 use Apache::loncoursequeueadmin;
+use Apache::lonuserutils;
 use LONCAPA qw(:DEFAULT :match);
 
 sub handler {
@@ -262,7 +263,11 @@ sub handler {
         if (($state eq 'courseinfo') && ($env{'form.clonedom'} eq '')) {
             $env{'form.clonedom'} = $dom;
         }
-        $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored);
+        if ($state eq 'crstype') {
+            $jscript = &mainmenu_javascript();
+        } else {
+            $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored);
+        }
     }
 
     if ($state eq 'personnel') {
@@ -291,7 +296,7 @@ sub handler {
         }
     } elsif ($action eq 'view') {
         if ($state eq 'crstype') {
-            &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb);
+            &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems,$crumb);
         } else {
             &request_administration($r,$action,$state,$page,\%states,$dom,$jscript,
                                     $loaditems,$crumb);
@@ -315,6 +320,30 @@ sub handler {
     return OK;
 }
 
+sub mainmenu_javascript {
+    return <<"END";
+function setType(courseForm) {
+    for (var i=0; i<courseForm.crstype.length; i++) {
+        if (courseForm.crstype.options[i].value == "$env{'form.crstype'}") {
+            courseForm.crstype.options[i].selected = true;
+        } else {
+            courseForm.crstype.options[i].selected = false;
+        }
+    }
+}
+
+function setAction(courseForm) {
+    for (var i=0; i<courseForm.action.length; i++) {
+        if (courseForm.action.options[i].value == "$env{'form.action'}") {
+            courseForm.action.options[i].selected = true;
+        } else {
+            courseForm.action.options[i].selected = false;
+        }
+    }
+}
+END
+}
+
 sub get_breadcrumbs {
     my ($dom,$action,$state,$states,$trail) = @_;
     my ($crumb,$newinstcode,$codechk,$checkedcode,$numtitles);
@@ -498,9 +527,9 @@ sub form_elements {
                      );
         if ($env{'form.sectotal'} > 0) {
             for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
-                $extras{'sec_'.$i} = 'checkbox',
-                $extras{'secnum_'.$i} = 'text',
-                $extras{'loncapasec_'.$i} = 'text',
+                $extras{'sec_'.$i} = 'radio';
+                $extras{'secnum_'.$i} = 'text';
+                $extras{'loncapasec_'.$i} = 'text';
             }
         }
         my $crosslisttotal = $env{'form.crosslisttotal'};
@@ -555,7 +584,11 @@ sub onload_action {
     my ($action,$state) = @_;
     my %loaditems;
     if (($action eq 'new') || ($action eq 'view')) {
-        $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)';
+        if ($state eq 'crstype') {
+            $loaditems{'onload'} = 'javascript:setAction(document.mainmenu_action);javascript:setType(document.mainmenu_coursetype)';
+        } else {
+            $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)';
+        }
     }
     return \%loaditems;
 }
@@ -767,8 +800,15 @@ END
     }
     if ($action eq 'new') {
         my $jsextra;
-        unless (($state eq 'review') || ($state eq 'process')) {
+        if ($state eq 'courseinfo') {
             $jsextra = "\n".&Apache::loncommon::coursebrowser_javascript($dom);
+        } elsif ($state eq 'enrollment') {
+            if (($env{'form.crstype'} eq 'official') && 
+                (&Apache::lonnet::auto_run('',$dom))) {
+                $js .= "\n".&section_check_javascript()."\n".&enrollment_lcsec_js();
+            }
+        } elsif ($state eq 'personnel') {
+            $js .= "\n".&section_check_javascript()."\n".&personnel_lcsec_js();
         }
         $r->print(&header('Request a course',$js.$jscript,$loaditems,$jsextra).$crumb);
         &print_request_form($r,$action,$state,$page,$states,$dom,$newinstcode,
@@ -792,7 +832,7 @@ END
         my $form = '<form method="post" name="'.$formname.'" action="/adm/requestcourse" />';
         if ($state eq 'pick_request') {
             $r->print('<h3>'.&mt('Pending course requests').'</h3><div>'."\n".$form."\n".
-                      &print_request_status($dom).'</form>');
+                      &print_request_status($dom).'</form></div>');
         } elsif ($state eq 'details') {
             my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk);
             my $origcnum = $env{'form.cnum'};
@@ -816,8 +856,8 @@ END
                                                       other => 'Modify Request',
                                                       next => 'Cancel Request',
                                                      );
-            &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},$next,$navtxt{'next'},
-                                $state,$other,$navtxt{'other'});
+            &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next,
+                                $navtxt{'next'},$state,$other,$navtxt{'other'});
             $r->print('</form>');
         } elsif ($state eq 'cancel') {
             my ($result,$output) = &print_cancel_request($dom,$env{'form.origcnum'});
@@ -830,10 +870,11 @@ END
                                                       next => 'Confirm Cancellation',
                                                      );
             if ($result eq 'ok') {
-                &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},$next,
+                &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next,
                                     $navtxt{'next'},$state);
             } else {
-                &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},undef,'',$state);
+                &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},undef,
+                                    '',$state);
             }
             $r->print('</form>');
         } elsif ($state eq 'removal') {
@@ -896,6 +937,166 @@ END
     return;
 }
 
+sub enrollment_lcsec_js {
+    my %alerts = &section_check_alerts();
+    my $secname = $alerts{'badsec'};
+    my $secnone = $alerts{'reserved'};
+    my $output = '
+function validateEnrollSections(formname,nextstate) {
+    var badsectotal = 0;
+    var reservedtotal = 0;
+    var secTest = "";
+';
+    for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
+        $output .= "
+    var selSec = 0;
+    for (var j=0; j<document.requestcrs.sec_".$i.".length; j++) {
+        if (document.requestcrs.sec_".$i."[j].checked) {
+            selSec = document.requestcrs.sec_".$i."[j].value;
+        }
+        if (selSec == 1) {
+            secTest = validsection(document.requestcrs.loncapasec_".$i.");
+            if (secTest == 'badsec') {
+                badsectotal++;
+            }
+            if (secTest == 'reserved') {
+                reservedtotal++;
+            }
+        }
+    }
+";
+    }
+    for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) {
+        $output .= "
+    if (document.requestcrs.crosslist_".$i.".checked) {
+        secTest = validsection(document.requestcrs.crosslist_".$i."_lcsec);
+        if (secTest == 'badsec') {
+            badsectotal++;
+        }
+        if (secTest == 'reserved') {
+            reservedtotal++;
+        }
+    }
+";
+    }
+    $output .= "
+    if (badsectotal>0) {
+        alert('$secname');
+        return false;
+    }
+    if (reservedtotal>0) {
+        alert('$secnone');
+        return false;
+    }
+    formname.state.value= nextstate;
+    formname.submit();
+    return;
+}
+";
+    return $output;
+}
+
+sub personnel_lcsec_js {
+    my %alerts = &section_check_alerts();
+    my $secname = $alerts{'badsec'}.'\\n'.$alerts{'separate'};
+    my $secnone = $alerts{'reserved'};
+    my $output = '
+function validatePersonnelSections(formname,nextstate) {
+    var badsectotal = 0;
+    var reservedtotal = 0;
+    var secTest = "";
+';
+    for (my $i=0; $i<$env{'form.persontotal'}; $i++) {
+        $output .= "
+    if (document.requestcrs.person_".$i."_uname.value != '') {
+        secTest = validsection(document.requestcrs.person_".$i."_newsec,'1');
+        if (secTest == 'badsec') {
+            badsectotal++; 
+        }
+        if (secTest == 'reserved') {
+            reservedtotal++;
+        }
+    }
+";
+    }
+    $output .= "
+    if (badsectotal > 0) {
+        alert('$secname');
+        return false;
+    } else {
+        if (reservedtotal > 0) {
+            alert('$secnone');
+            return false;
+        }
+    }
+    formname.state.value = nextstate;
+    formname.submit();
+    return;
+}
+";
+    return $output;
+}
+
+sub section_check_alerts {
+    my %lt = 
+        &Apache::lonlocal::texthash(
+            reserved => "You need to change one or more LON-CAPA section names - none is a reserved word in the system, and may not be used.",
+            badsec => 'You need to change one or more LON-CAPA section names - names may only contain letters or numbers.',
+            separate => 'Separate multiple sections with a comma.'
+        );
+    return %lt;
+}
+
+sub section_check_javascript {
+    return <<"END";
+function validsection(field,mult) {
+    var str = field.value;
+    var badsec=0;
+    var reserved=0;
+    if (window.RegExp) {
+        var badsecnum=0;
+        var reservednum=0;
+        var pattern=/[^a-zA-Z0-9]/; 
+        str = str.replace(/(^\\s*)|(\\s*\$)/gi,"");
+        str = str.replace(/[ ]{2,}/gi," ");
+        if (mult == '1') {
+            var sections = new Array();
+            sections = str.split(/\\s*[\\s,;:]\\s*/);
+            var i;
+            for (i=0; i<sections.length; i++) {
+                if ((sections[i] != '') && (sections[i] != undefined) && (sections[i] != null)) {
+                    if (pattern.test(sections[i])) {
+                        badsecnum++;
+                    } else {
+                        if (sections[i] == 'none') {
+                            reservednum++;
+                        }
+                    }
+                }
+            }
+        } else {
+            if ((str != '') && (str != undefined) && (str != null)) {
+                if (pattern.test(str)) {
+                    badsecnum++;
+                } else {
+                    if (str == 'none') {
+                        reservednum++;
+                    }
+                }
+            }
+        }
+        if (badsecnum > 0) {
+            return 'badsec';
+        }
+        if (reservednum > 0) {
+            return 'reserved';
+        }
+    }
+    return;
+}
+END
+}
+
 sub close_popup_form {
     my $close= &mt('Close Window');
     return << "END";
@@ -934,7 +1135,8 @@ sub print_request_form {
                                              );
     $crstype = $env{'form.crstype'};
     $r->print('<form name="'.$formname.'" method="post" action="/adm/requestcourse">');
-    my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk);
+    my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk,
+        @disallowed);
     if ($crstype eq 'official') {
         if ($env{'form.instcode'} ne '') {
             $instcode = $env{'form.instcode'};
@@ -997,6 +1199,79 @@ sub print_request_form {
     } elsif ($state eq 'personnel') {
         $r->print(&print_personnel_menu($dom,$formname,$crstype,$invalidcrosslist));
     } elsif ($state eq 'review') {
+        my (%alerts,%rulematch,%inst_results,%curr_rules,%got_rules,%disallowmsg);
+        my $now = time;
+        for (my $i=0; $i<$env{'form.persontotal'}; $i++) {
+            my $personname = $env{'form.person_'.$i.'_uname'};
+            my $persondom = $env{'form.person_'.$i.'_dom'};
+            if (($personname =~ /^$match_username$/) && 
+                ($persondom =~ /^$match_domain$/)) {
+                if (&Apache::lonnet::domain($persondom)) {
+                    my $personhome = 
+                        &Apache::lonnet::homeserver($personname,$persondom);
+                    if ($personhome eq 'no_host') {
+                        if ($persondom ne $dom) {
+                            my $skipuser = 1;
+                            if ($env{'user.role.dc./'.$persondom.'/'}) {
+                                my ($start,$end) = split('.',$env{'user.role.dc./'.$persondom.'/'});
+                                if (((!$start) || ($start < $now)) && 
+                                    ((!$end) || ($end > $now))) {
+                                    $skipuser = 0;
+                                }
+                            }
+                            if ($skipuser) {
+                                push(@disallowed,$i);
+                                $disallowmsg{$i} = &mt('[_1] was excluded because new users need be from the course domain','<tt>'.$personname.':'.$persondom.'</tt>');
+                                next;
+                            }
+                        }
+                        if (&get_cancreate_status($persondom,$personname,$dom)) {
+                            my ($allowed,$msg) = 
+                                &check_newuser_rules($persondom,$personname,
+                                    \%alerts,\%rulematch,\%inst_results,
+                                    \%curr_rules,\%got_rules);
+                            if ($allowed) {
+                                if (ref($inst_results{$personname.':'.$persondom}) eq 'HASH') {
+                                    if ($inst_results{$personname.':'.$persondom}{'lastname'} ne '') {
+                                        $env{'form.person_'.$i.'_lastname'} = $inst_results{$personname.':'.$persondom}{'lastname'};
+                                    }
+                                    if ($inst_results{$personname.':'.$persondom}{'firstname'} ne '') {
+                                        $env{'form.person_'.$i.'_firstname'} = $inst_results{$personname.':'.$persondom}{'firstname'};
+                                    }
+                                    if ($inst_results{$personname.':'.$persondom}{'permanentemail'} ne '') {
+                                        $env{'form.person_'.$i.'_emailaddr'} = $inst_results{$personname.':'.$persondom}{'permanentemail'};
+                                    }
+                                }
+                            } else {
+                                push(@disallowed,$i);
+                                $disallowmsg{$i} = &mt('[_1] was excluded because the username violated format rules for the domain','<tt>'.$personname.':'.$persondom.'</tt>');  
+                            }
+                        } else {
+                            push(@disallowed,$i);
+                            $disallowmsg{$i} = &mt('[_1] was excluded because you may not request new users in the domain','<tt>'.$personname.':'.$persondom.'</tt>');
+                        }
+                    } else {
+                        my %userenv = 
+                            &Apache::lonnet::userenvironment($persondom,$personname,'lastname','firstname','permanentemail');
+                        if ($env{'form.person_'.$i.'_lastname'} eq '') {
+                            $env{'form.person_'.$i.'_lastname'} = $userenv{'lastname'};
+                        }
+                        if ($env{'form.person_'.$i.'_firstname'} eq '') {
+                            $env{'form.person_'.$i.'_firstname'} = $userenv{'firstname'};
+                        }
+                        if ($env{'form.person_'.$i.'_emailaddr'} eq '') {
+                            $env{'form.person_'.$i.'_emailaddr'} = $userenv{'permanentemail'};
+                        }
+                    }
+                } elsif ($personname ne '') {
+                    push(@disallowed,$i);
+                    $disallowmsg{$i} = &mt('[_1] was excluded because the domain is invalid','<tt>'.$personname.':'.$persondom.'</tt>');
+                }
+            } elsif ($personname ne '') {
+                push(@disallowed,$i);
+                $disallowmsg{$i} = &mt('[_1] was excluded because the username or domain is invalid.','<tt>'.$personname.':'.$persondom.'</tt>');
+            }
+        }
         my $cnum;
         if ($env{'form.origcnum'} =~ /^($match_courseid)$/) {
             $cnum = $env{'form.origcnum'};
@@ -1006,7 +1281,7 @@ sub print_request_form {
         &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
                                                  \%cat_order,\@code_order);
         $r->print('<h3>'.&mt('Review course request details before submission').'</h3>'.
-                  &print_review($dom,\@codetitles,\%cat_titles,\%cat_order,\@code_order).
+                  &print_review($dom,\@codetitles,\%cat_titles,\%cat_order,\@code_order,'','',\@disallowed,\%disallowmsg).
                   '<input type="hidden" name="cnum" value="'.$cnum.'" />');
         $navtxt{'next'} = &mt('Submit course request');
     }  elsif ($state eq 'process') {
@@ -1031,14 +1306,80 @@ sub print_request_form {
     if ($state eq 'personnel') {
         push(@excluded,'persontotal');
     }
+    if ($state eq 'review') {
+        if (@disallowed > 0) {
+            my @items = qw(uname dom lastname firstname emailaddr hidedom role newsec);
+            my @currsecs = &current_lc_sections();
+            if (@currsecs) {
+                push(@items,'sec');
+            }
+            my $count = 0;
+            for (my $i=0; $i<$env{'form.persontotal'}; $i++) {
+                unless ($env{'form.person_'.$i.'_uname'} eq '') {
+                    if (grep(/^$i$/,@disallowed)) {
+                        foreach my $item (@items) {
+                            $env{'form.person_'.$i.'_'.$item} = '';
+                        }
+                    } else { 
+                        foreach my $item (@items) {
+                            $env{'form.person_'.$count.'_'.$item} = $env{'form.person_'.$i.'_'.$item};
+                        }
+                    }
+                }
+                $count ++;
+            }
+            $env{'form.persontotal'} = $count;
+             
+        }
+    }
     if ($state eq 'enrollment') {
         push(@excluded,'crosslisttotal');
     }
     $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).'</form>');
-    &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},$next,$navtxt{'next'},$state);
+    &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next,
+                        $navtxt{'next'},$state);
     return;
 }
 
+sub get_cancreate_status {
+    my ($persondom,$personname,$dom) = @_;
+    my ($rules,$ruleorder) =
+        &Apache::lonnet::inst_userrules($persondom,'username');
+    my $usertype = &Apache::lonuserutils::check_usertype($persondom,$personname,
+                                                         $rules);
+    return &Apache::lonuserutils::can_create_user($dom,'requestcrs',$usertype);
+}
+
+sub check_newuser_rules {
+    my ($persondom,$personname,$alerts,$rulematch,$inst_results,$curr_rules,
+        $got_rules) = @_;
+    my $allowed = 1;
+    my $newuser = 1;
+    my ($checkhash,$userchkmsg);
+    my $checks = { 'username' => 1 };
+    $checkhash->{$personname.':'.$persondom} = { 'newuser' => $newuser };
+    &Apache::loncommon::user_rule_check($checkhash,$checks,$alerts,$rulematch,
+                                        $inst_results,$curr_rules,$got_rules);
+    if (ref($alerts->{'username'}) eq 'HASH') {
+        if (ref($alerts->{'username'}{$persondom}) eq 'HASH') {
+            my $domdesc =
+                &Apache::lonnet::domain($persondom,'description');
+            if ($alerts->{'username'}{$persondom}{$personname}) {
+                if (ref($curr_rules->{$persondom}) eq 'HASH') {
+                    $userchkmsg =
+                        &Apache::loncommon::instrule_disallow_msg('username',
+                                                                  $domdesc,1).
+                        &Apache::loncommon::user_rule_formats($persondom,
+                            $domdesc,$curr_rules->{$persondom}{'username'},
+                            'username');
+                }
+                $allowed = 0;
+            }
+        }
+    }
+    return ($allowed,$userchkmsg);
+}
+
 sub get_excluded_elements {
     my ($dom,$states,$action,$state) = @_;
     my @excluded = ('counter');
@@ -1193,14 +1534,18 @@ sub inst_section_selector {
                     &Apache::loncommon::end_data_table_row();
         for (my $i=0; $i<@sections; $i++) {
             my $colflag = $i%2;
-            my $checked = ' checked="checked"';
+            my $secon = ' checked="checked"';
+            my $secoff = '';
             if ($env{'form.origcnum'}) {
-                $checked='';
+                $secoff = $secon;
+                $secon='';
             }
             $output .= &Apache::loncommon::start_data_table_row().
-                       '<td><input type="checkbox" name="sec_'.$i.
-                       '"'.$checked.' value="1" /></td>'.
-                       '<td>'.$sections[$i].
+                       '<td><label><input type="radio" name="sec_'.$i.
+                       '"'.$secon.' value="1" />'.&mt('Yes').'</label>'.
+                       ('&nbsp;'x2).'<label><input type="radio" name="sec_'.$i.
+                        '"'.$secoff.' value="0" />'.&mt('No').'</label></td>'.
+                       '<td align="center">'.$sections[$i].
                        '<input type="hidden" name="secnum_'.$i.'" value="'.
                        $sections[$i].'" /></td>'.
                        '<td><input type="text" size="10" name="loncapasec_'.$i.
@@ -1252,7 +1597,6 @@ sub print_personnel_menu {
     if ($env{'form.addperson'}) {
         $persontotal ++;
     }
-    my $userlinktxt = &mt('Set User');
     my @items = ('uname','dom','lastname','firstname','emailaddr','hidedom');
 
     my $roleoptions;
@@ -1273,17 +1617,7 @@ sub print_personnel_menu {
         }
     }
 
-    my @currsecs;
-    if ($env{'form.sectotal'}) {
-        for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
-            if (defined($env{'form.loncapasec_'.$i})) {
-                my $lcsec = $env{'form.loncapasec_'.$i};
-                unless (grep(/^\Q$lcsec\E$/,@currsecs)) {
-                    push(@currsecs,$lcsec);
-                }
-            }
-        }
-    }
+    my @currsecs = &current_lc_sections();
 
     my ($existtitle,$existops,$existmult,$newtitle,$seccolspan);
     if (@currsecs) {
@@ -1311,16 +1645,12 @@ sub print_personnel_menu {
     for (my $i=0; $i<$persontotal; $i++) { 
         my @linkargs = map { 'person_'.$i.'_'.$_ } (@items);
         my $linkargstr = join("','",@linkargs);
-        my $userlink = &Apache::loncommon::selectuser_link($formname,@linkargs,$dom,$userlinktxt);
-        my $uname_form = '<input type="text" name="person_'.$i.'_uname" value=""'.
-                         ' onFocus="this.blur();'.
-                         'openuserbrowser('."'$formname','$linkargstr','$dom'".');" />';
+        my $uname_form = '<input type="text" name="person_'.$i.'_uname" value="" size="20" />';
         my $onchange = 'javascript:fix_domain('."'$formname','person_".$i."_dom',".
-                       "'person_".$i."_hidedom'".');'.
-                       'openuserbrowser('."'$formname','$linkargstr','$dom'".');';
+                       "'person_".$i."_hidedom','person_".$i."_uname'".');';
         my $udom_form = &Apache::loncommon::select_dom_form($dom,'person_'.$i.'_dom','',
                                                             1,$onchange).
-                        '<input type="hidden" name="person_'.$i.'_hidedom" value="'.$dom.'" />';
+                        '<input type="hidden" name="person_'.$i.'_hidedom" value="" />';
         my %form_elems;
         foreach my $item (@items) {
             next if (($item eq 'dom') || ($item eq 'uname') || ($item eq 'hidedom'));
@@ -1336,12 +1666,19 @@ sub print_personnel_menu {
         }
         $sectionselector .= $newtitle.
             '<input type="text" name="person_'.$i.'_newsec" size="15" value="" />'."\n";
+        my $usersrchlinktxt = &mt('Search for user');
+        my $usersrchlink =  &Apache::loncommon::selectuser_link($formname,@linkargs,$dom,
+                            $usersrchlinktxt);
+        my $userchklinktxt = &mt('Check username');
+        my $userchklink = &Apache::loncommon::selectuser_link($formname,@linkargs,$dom,
+                            $userchklinktxt,'checkusername');
         $output .= 
-            &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel').'<br />'.
-                                              '<span class="LC_nobreak">'.$userlink.
-                                              '</span>').
-            '<table><tr><td align="center" valign="top">'.&mt('Username').'<br />'.$uname_form.'</td>'."\n".
-            '<td align="center" valign="top" colspan="2">'.&mt('Domain').'<br />'.$udom_form.'</td></tr><tr>'."\n".
+            &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel')).
+            '<table><tr><td align="center" valign="middle"><b>'.$usersrchlink.'</b></td>'."\n".
+            '<td align="left" valign="top" colspan="2"><span class="LC_nobreak">'.
+            &mt('Username').':&nbsp;'.$uname_form.'&nbsp;'.$userchklink.'</span><br />'."\n".
+            '<span class="LC_nobreak">'.&mt('Domain').':&nbsp;'.$udom_form.'</span></td>'.
+            '</tr>'."\n".'<tr>'.
             '<td align="center" valign="top">'.&mt('First Name').'<br />'.$form_elems{'firstname'}.'</td>'."\n".
             '<td align="center" valign="top">'.&mt('Last Name').'<br />'.$form_elems{'lastname'}.'</td>'."\n".
             '<td align="center" valign="top">'.&mt('E-mail').'<br />'.$form_elems{'emailaddr'}.'</td></tr>'."\n".
@@ -1358,6 +1695,23 @@ sub print_personnel_menu {
     return $output;
 }
 
+sub current_lc_sections {
+    my @currsecs;
+    if ($env{'form.sectotal'}) {
+        for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
+            if ($env{'form.sec_'.$i}) { 
+                if (defined($env{'form.loncapasec_'.$i})) {
+                    my $lcsec = $env{'form.loncapasec_'.$i};
+                    unless (grep(/^\Q$lcsec\E$/,@currsecs)) {
+                        push(@currsecs,$lcsec);
+                    }
+                }
+            }
+        }
+    }
+    return @currsecs;
+}
+
 sub print_request_status {
     my ($dom) = @_;
     my %statusinfo = &Apache::lonnet::dump('courserequests',$env{'user.domain'},
@@ -1466,8 +1820,7 @@ sub print_request_status {
         $output .= '<div>'.&mt('You have no matching course requests awaiting approval by a Domain Coordinator or held in a queue pending administrative action at your institution.').'</div>';
     }
     $output .= '
-<br /><input type="button" name="prev" value="'.&mt('Back').'" onclick="javascript:backPage(document.'.$formname.",'crstype'".')" />
-</form></div>';
+<br /><input type="button" name="prev" value="'.&mt('Back').'" onclick="javascript:backPage(document.'.$formname.",'crstype'".')" />';
     return $output;
 }
 
@@ -1573,7 +1926,8 @@ sub print_request_logs {
 }
 
 sub print_review {
-    my ($dom,$codetitles,$cat_titles,$cat_order,$code_order,$uname,$udom) = @_;
+    my ($dom,$codetitles,$cat_titles,$cat_order,$code_order,$uname,$udom,
+        $disallowed,$disallowmsg) = @_;
     my ($types,$typename) = &course_types();
     my ($owner,$ownername,$owneremail);
     if ($uname eq '' || $udom eq '') {
@@ -1751,14 +2105,25 @@ sub print_review {
                          '<td>'.&mt('None').'</td></tr>';
     for (my $i=0; $i<$env{'form.persontotal'}; $i++) {
         if ($env{'form.person_'.$i.'_uname'} ne '') {
-            my @allsecs = &Apache::loncommon::get_env_multiple('form.person_'.$i.'_sec');
+            if (ref($disallowed) eq 'ARRAY') {
+                next if (grep(/^$i$/,@{$disallowed}));
+            } 
+            my @officialsecs = &Apache::loncommon::get_env_multiple('form.person_'.$i.'_sec');
+            my @allsecs;
+            foreach my $sec (@officialsecs) {
+                next unless ($sec =~ /\w/);
+                next if ($sec =~ /\W/);
+                next if ($sec eq 'none');
+                push(@allsecs,$sec);
+            }
             my $newsec = $env{'form.person_'.$i.'_newsec'};
             $newsec =~ s/^\s+//;
             $newsec =~s/\s+$//;
-            my @newsecs = split(/[\s,;]+/,$newsec);
+            my @newsecs = split(/\s*[\s,;:]\s*/,$newsec);
             foreach my $sec (@newsecs) {
+                next unless ($sec =~ /\w/); 
                 next if ($sec =~ /\W/);
-                next if ($newsec eq 'none');
+                next if ($sec eq 'none');
                 if ($sec ne '') {
                     unless (grep(/^\Q$sec\E$/,@allsecs)) {
                         push(@allsecs,$sec); 
@@ -1785,8 +2150,20 @@ sub print_review {
                 '<td>'.$showsec.'</td></tr>';
         }
     }
-    my $output =  
-                  '<div>'.&Apache::lonhtmlcommon::start_pick_box().
+    my $output;
+    if (ref($disallowed) eq 'ARRAY') {
+        if (@{$disallowed} > 0) {
+            if (ref($disallowmsg) eq 'HASH') {
+                $output = '<p class="LC_warning">'.
+                          &mt('Not all requested personnel could be included.').'<ul>'; 
+                foreach my $item (@{$disallowed}) {
+                    $output .= '<li>'.$disallowmsg->{$item}.'</li>';
+                }
+                $output .= '</ul></p>';
+            }
+        }
+    }
+    $output .=    '<div>'.&Apache::lonhtmlcommon::start_pick_box().
                   &Apache::lonhtmlcommon::row_title(&mt('Owner')).
                   '<table class="LC_innerpickbox"><tr>'.
                   '<th>'.&mt('Name').'</th>'.
@@ -1887,8 +2264,7 @@ sub clone_form {
     my %lt = &clone_text();
     my $output .= 
         &Apache::lonhtmlcommon::row_title($lt{'cid'}).'<label>'.
-        '<input type="text" size="25" name="clonecrs" value="" onfocus="this.blur();'.
-        'opencrsbrowser('."'$formname','clonecrs','clonedom','','','','$type'".');" />'.
+        '<input type="text" size="25" name="clonecrs" value=""  />'.
         '</label>'.&Apache::lonhtmlcommon::row_closure(1).'<label>'.
         &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'</label>'.
         $cloneform.'</label>'.&Apache::lonhtmlcommon::row_closure(1).
@@ -2049,11 +2425,11 @@ sub get_course_dom {
 }
 
 sub display_navbuttons {
-    my ($r,$formname,$prev,$prevtext,$next,$nexttext,$state,$other,$othertext) = @_;
+    my ($r,$dom,$formname,$prev,$prevtext,$next,$nexttext,$state,$other,$othertext) = @_;
     $r->print('<div class="LC_navbuttons">');
     if ($prev) {
         $r->print('<input type="button" name="previous" value = "'.$prevtext.'" '.
-                  'onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>'.
+                  'onclick="javascript:backPage('."document.$formname,'$prev'".')"/>'.
                   ('&nbsp;'x3));
     } elsif ($prevtext) {
         $r->print('<input type="button" name="previous" value = "'.$prevtext.'" '.
@@ -2061,16 +2437,34 @@ sub display_navbuttons {
     }
     if ($state eq 'details') {
         $r->print(' <input type="button" name="other" value="'.$othertext.'" '.
-                  'onclick="javascript:nextPage(document.'.$formname.','."'".$other."'".
+                  'onclick="javascript:nextPage('."document.$formname,'$other'".
                   ')" />');
     }
+    my $gotnext;
     if ($state eq 'courseinfo') {
         $r->print('<input type="button" name="next" value="'.$nexttext.'" '.
                   'onclick="javascript:validateForm();" />');
-    } elsif ($next) {
-        $r->print('
-      <input type="button" name="next" value="'.$nexttext.'" '.
-      'onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
+        $gotnext = 1;
+    } elsif ($state eq 'enrollment') {
+        if (($env{'form.crstype'} eq 'official') && 
+            (&Apache::lonnet::auto_run('',$dom))) {
+            $r->print('<input type="button" name="next" value="'.$nexttext.'" '.
+                      'onclick="javascript:validateEnrollSections('."document.$formname,'$next'".');" />');
+                $gotnext = 1;
+        }
+    } elsif ($state eq 'personnel') {
+        if ($env{'form.persontotal'} > 0) { 
+            $r->print('<input type="button" name="next" value="'.$nexttext.'" '.
+                      'onclick="javascript:validatePersonnelSections('."document.$formname,'$next'".');" />');
+            $gotnext = 1;
+        }
+    }
+    unless ($gotnext) {
+        if ($next) {
+            $r->print('
+                      <input type="button" name="next" value="'.$nexttext.'" '.
+      'onclick="javascript:nextPage('."document.$formname,'$next'".')" />');
+        }
     }
     $r->print('</div>');
 }
@@ -2160,20 +2554,27 @@ sub print_request_outcome {
                         @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = ();
                     } else {
                         my @currsec = &Apache::loncommon::get_env_multiple('form.person_'.$i.'_sec');
+                        my @allsecs;
+                        foreach my $sec (@currsec) {
+                            next unless ($sec =~ /\w/);
+                            next if ($sec =~ /\W/);
+                            next if ($sec eq 'none');
+                            push(@allsecs,$sec);
+                        }
                         my $newsec = $env{'form.person_'.$i.'_newsec'};
                         $newsec =~ s/^\s+//;
                         $newsec =~s/\s+$//;
                         my @newsecs = split(/[\s,;]+/,$newsec);
                         foreach my $sec (@newsecs) {
                             next if ($sec =~ /\W/);
-                            next if ($newsec eq 'none');
+                            next if ($sec eq 'none');
                             if ($sec ne '') {
-                                unless (grep(/^\Q$sec\E$/,@currsec)) {
-                                    push(@currsec,$sec);
+                                unless (grep(/^\Q$sec\E$/,@allsecs)) {
+                                    push(@allsecs,$sec);
                                 }
                             }
                         }
-                        @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = @currsec;
+                        @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = @allsecs;
                     }
                 }
             } else {