[LON-CAPA-cvs] cvs: loncom(version_2_11_X) /interface domainprefs.pm

raeburn raeburn at source.lon-capa.org
Tue Sep 25 19:20:43 EDT 2012


raeburn		Tue Sep 25 23:20:43 2012 EDT

  Modified files:              (Branch: version_2_11_X)
    /loncom/interface	domainprefs.pm 
  Log:
  - For 2.11.
    - Backport 1.171.
  
  
-------------- next part --------------
Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.160.6.6 loncom/interface/domainprefs.pm:1.160.6.7
--- loncom/interface/domainprefs.pm:1.160.6.6	Tue Sep 25 20:38:47 2012
+++ loncom/interface/domainprefs.pm	Tue Sep 25 23:20:42 2012
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.160.6.6 2012/09/25 20:38:47 raeburn Exp $
+# $Id: domainprefs.pm,v 1.160.6.7 2012/09/25 23:20:42 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -217,7 +217,11 @@
                        'usercreation','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',
                        'serverstatuses','usersessions');
-    if (keys(%servers) > 1) {
+    my %existing;
+    if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+        %existing = %{$domconfig{'loadbalancing'}};
+    }
+    if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
         push(@prefs_order,'loadbalancing');
     }
     my %prefs = (
@@ -360,9 +364,9 @@
                               col2 => 'Rules'}],
                  },
          'loadbalancing' =>
-                 {text  => 'Dedicated Load Balancer',
+                 {text  => 'Dedicated Load Balancer(s)',
                   help  => 'Domain_Configuration_Load_Balancing',
-                  header => [{col1 => 'Server',
+                  header => [{col1 => 'Balancers',
                               col2 => 'Default destinations',
                               col3 => 'User affliation',
                               col4 => 'Overrides'},
@@ -390,10 +394,11 @@
         &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles);
     } elsif ($phase eq 'display') {
         my $js = &recaptcha_js();
-        if (keys(%servers) > 1) {
+        if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
             my ($othertitle,$usertypes,$types) =
                 &Apache::loncommon::sorted_inst_types($dom);
-            $js .= &lonbalance_targets_js($dom,$types,\%servers).
+            $js .= &lonbalance_targets_js($dom,$types,\%servers,
+                                          $domconfig{'loadbalancing'}).
                    &new_spares_js().
                    &common_domprefs_js().
                    &Apache::loncommon::javascript_array_indexof();
@@ -2849,16 +2854,13 @@
     my $numinrow = 1;
     my $datatable;
     my %servers = &Apache::lonnet::internet_dom_servers($dom);
-    my ($currbalancer,$currtargets,$currrules);
-    if (keys(%servers) > 1) {
-        if (ref($settings) eq 'HASH') {
-            $currbalancer = $settings->{'lonhost'};
-            $currtargets = $settings->{'targets'};
-            $currrules = $settings->{'rules'};
-        } else {
-            ($currbalancer,$currtargets) = 
-                &Apache::lonnet::get_lonbalancer_config(\%servers);
-        }
+    my (%currbalancer,%currtargets,%currrules,%existing);
+    if (ref($settings) eq 'HASH') {
+        %existing = %{$settings};
+    }
+    if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
+        &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
+                                  \%currtargets,\%currrules);
     } else {
         return;
     }
@@ -2868,104 +2870,191 @@
     if (ref($types) eq 'ARRAY') {
         $rownum += scalar(@{$types});
     }
-    my $css_class = ' class="LC_odd_row"';
-    my $targets_div_style = 'display: none';
-    my $disabled_div_style = 'display: block';
-    my $homedom_div_style = 'display: none';
-    $datatable = '<tr'.$css_class.'>'.
-                 '<td rowspan="'.$rownum.'" valign="top">'.
-                 '<p><select name="loadbalancing_lonhost" onchange="toggleTargets();">'."\n".
-                 '<option value=""';
-    if (($currbalancer eq '') || (!grep(/^\Q$currbalancer\E$/,keys(%servers)))) {
-        $datatable .= ' selected="selected"';
-    } else {
-        $targets_div_style = 'display: block';
-        $disabled_div_style = 'display: none';
-        if ($dom eq &Apache::lonnet::host_domain($currbalancer)) {
-            $homedom_div_style = 'display: block'; 
-        }
-    }
-    $datatable .= '>'.&mt('None').'</option>'."\n";
-    foreach my $lonhost (sort(keys(%servers))) {
-        my $selected;
-        if ($lonhost eq $currbalancer) {
-            $selected .= ' selected="selected"';
-        }
-        $datatable .= '<option value="'.$lonhost.'"'.$selected.'>'.$lonhost.'</option>'."\n";
-    }
-    $datatable .= '</select></p></td><td rowspan="'.$rownum.'" valign="top">'.
-                  '<div id="loadbalancing_disabled" style="'.$disabled_div_style.'">'.&mt('No dedicated Load Balancer').'</div>'."\n".
-                  '<div id="loadbalancing_targets" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />';
-    my ($numspares, at spares) = &count_servers($currbalancer,%servers);
-    my @sparestypes = ('primary','default');
-    my %typetitles = &sparestype_titles();
-    foreach my $sparetype (@sparestypes) {
-        my $targettable;
-        for (my $i=0; $i<$numspares; $i++) {
-            my $checked;
-            if (ref($currtargets) eq 'HASH') {
-                if (ref($currtargets->{$sparetype}) eq 'ARRAY') {
-                    if (grep(/^\Q$spares[$i]\E$/,@{$currtargets->{$sparetype}})) {
-                        $checked = ' checked="checked"';
+    my @css_class = ('LC_odd_row','LC_even_row');
+    my $balnum = 0;
+    my $islast;
+    my (@toshow,$disabledtext);
+    if (keys(%currbalancer) > 0) {
+        @toshow = sort(keys(%currbalancer));
+        if (scalar(@toshow) < scalar(keys(%servers)) + 1) {
+            push(@toshow,'');
+        }
+    } else {
+        @toshow = ('');
+        $disabledtext = &mt('No existing load balancer');
+    }
+    foreach my $lonhost (@toshow) {
+        if ($balnum == scalar(@toshow)-1) {
+            $islast = 1;
+        } else {
+            $islast = 0;
+        }
+        my $cssidx = $balnum%2;
+        my $targets_div_style = 'display: none';
+        my $disabled_div_style = 'display: block';
+        my $homedom_div_style = 'display: none';
+        $datatable .= '<tr class="'.$css_class[$cssidx].'">'.
+                      '<td rowspan="'.$rownum.'" valign="top">'.
+                      '<p>';
+        if ($lonhost eq '') {
+            $datatable .= '<span class="LC_nobreak">';
+            if (keys(%currbalancer) > 0) {
+                $datatable .= &mt('Add balancer:');
+            } else {
+                $datatable .= &mt('Enable balancer:');
+            }
+            $datatable .= ' '.
+                          '<select name="loadbalancing_lonhost_'.$balnum.'"'.
+                          ' id="loadbalancing_lonhost_'.$balnum.'"'.
+                          ' onchange="toggleTargets('."'$balnum'".');">'."\n".
+                          '<option value="" selected="selected">'.&mt('None').
+                          '</option>'."\n";
+            foreach my $server (sort(keys(%servers))) {
+                next if ($currbalancer{$server});
+                $datatable .= '<option value="'.$server.'">'.$server.'</option>'."\n";
+            }
+            $datatable .=
+                '</select>'."\n".
+                '<input type="hidden" name="loadbalancing_prevlonhost_'.$balnum.'" id="loadbalancing_prevlonhost_'.$balnum.'" value="" /> </span>'."\n";
+        } else {
+            $datatable .= '<i>'.$lonhost.'</i><br /><span class="LC_nobreak">'.
+                          '<label><input type="checkbox" name="loadbalancing_delete" value="'.$balnum.'" id="loadbalancing_delete_'.$balnum.'" onclick="javascript:balancerDeleteChange('."'$balnum'".');" /> '.
+                           &mt('Stop balancing').'</label>'.
+                           '<input type="hidden" name="loadbalancing_lonhost_'.$balnum.'" value="'.$lonhost.'" id="loadbalancing_lonhost_'.$balnum.'" /></span>';
+            $targets_div_style = 'display: block';
+            $disabled_div_style = 'display: none';
+            if ($dom eq &Apache::lonnet::host_domain($lonhost)) {
+                $homedom_div_style = 'display: block';
+            }
+        }
+        $datatable .= '</p></td><td rowspan="'.$rownum.'" valign="top">'.
+                  '<div id="loadbalancing_disabled_'.$balnum.'" style="'.
+                  $disabled_div_style.'">'.$disabledtext.'</div>'."\n".
+                  '<div id="loadbalancing_targets_'.$balnum.'" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />';
+        my ($numspares, at spares) = &count_servers($lonhost,%servers);
+        my @sparestypes = ('primary','default');
+        my %typetitles = &sparestype_titles();
+        foreach my $sparetype (@sparestypes) {
+            my $targettable;
+            for (my $i=0; $i<$numspares; $i++) {
+                my $checked;
+                if (ref($currtargets{$lonhost}) eq 'HASH') {
+                    if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') {
+                        if (grep(/^\Q$spares[$i]\E$/,@{$currtargets{$lonhost}{$sparetype}})) {
+                            $checked = ' checked="checked"';
+                        }
+                    }
+                }
+                my ($chkboxval,$disabled);
+                if (($lonhost ne '') && (exists($servers{$lonhost}))) {
+                    $chkboxval = $spares[$i];
+                }
+                if (exists($currbalancer{$spares[$i]})) {
+                    $disabled = ' disabled="disabled"';
+                }
+                $targettable .=
+                    '<td><label><input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.
+                    $checked.$disabled.' value="'.$chkboxval.'" id="loadbalancing_target_'.$balnum.'_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$balnum','$sparetype'".');" /><span id="loadbalancing_targettxt_'.$balnum.'_'.$sparetype.'_'.$i.'"> '.$chkboxval.
+                    '</span></label></td>';
+                my $rem = $i%($numinrow);
+                if ($rem == 0) {
+                    if (($i > 0) && ($i < $numspares-1)) {
+                        $targettable .= '</tr>';
+                    }
+                    if ($i < $numspares-1) {
+                        $targettable .= '<tr>';
                     }
                 }
             }
-            my $chkboxval;
-            if (($currbalancer ne '') && (grep((/^\Q$currbalancer\E$/,keys(%servers))))) {
-                $chkboxval = $spares[$i];
-            }
-            $targettable .= '<td><label><input type="checkbox" name="loadbalancing_target_'.$sparetype.'"'.
-                      $checked.' value="'.$chkboxval.'" id="loadbalancing_target_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$sparetype'".');" /><span id="loadbalancing_targettxt_'.$sparetype.'_'.$i.'"> '.$chkboxval.
-                      '</span></label></td>';
-            my $rem = $i%($numinrow);
-            if ($rem == 0) {
-                if ($i > 0) {
-                    $targettable .= '</tr>';
-                }
-                $targettable .= '<tr>';
+            if ($targettable ne '') {
+                my $rem = $numspares%($numinrow);
+                my $colsleft = $numinrow - $rem;
+                if ($colsleft > 1 ) {
+                    $targettable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
+                                    ' </td>';
+                } elsif ($colsleft == 1) {
+                    $targettable .= '<td class="LC_left_item"> </td>';
+                }
+                $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.
+                               '<table><tr>'.$targettable.'</tr></table><br />';
+            }
+        }
+        my $cssidx = $balnum%2;
+        $datatable .= '</div></td></tr>'.
+                      &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
+                                           $othertitle,$usertypes,$types,\%servers,
+                                           \%currbalancer,$lonhost,
+                                           $targets_div_style,$homedom_div_style,
+                                           $css_class[$cssidx],$balnum,$islast);
+        $$rowtotal += $rownum;
+        $balnum ++;
+    }
+    $datatable .= '<input type="hidden" name="loadbalancing_total" id="loadbalancing_total" value="'.$balnum.'" />';
+    return $datatable;
+}
+
+sub get_loadbalancers_config {
+    my ($servers,$existing,$currbalancer,$currtargets,$currrules) = @_;
+    return unless ((ref($servers) eq 'HASH') &&
+                   (ref($existing) eq 'HASH') && (ref($currbalancer) eq 'HASH') &&
+                   (ref($currtargets) eq 'HASH') && (ref($currrules) eq 'HASH'));
+    if (keys(%{$existing}) > 0) {
+        my $oldlonhost;
+        foreach my $key (sort(keys(%{$existing}))) {
+            if ($key eq 'lonhost') {
+                $oldlonhost = $existing->{'lonhost'};
+                $currbalancer->{$oldlonhost} = 1;
+            } elsif ($key eq 'targets') {
+                if ($oldlonhost) {
+                    $currtargets->{$oldlonhost} = $existing->{'targets'};
+                }
+            } elsif ($key eq 'rules') {
+                if ($oldlonhost) {
+                    $currrules->{$oldlonhost} = $existing->{'rules'};
+                }
+            } elsif (ref($existing->{$key}) eq 'HASH') {
+                $currbalancer->{$key} = 1;
+                $currtargets->{$key} = $existing->{$key}{'targets'};
+                $currrules->{$key} = $existing->{$key}{'rules'};
             }
         }
-        if ($targettable ne '') {
-            my $rem = $numspares%($numinrow);
-            my $colsleft = $numinrow - $rem;
-            if ($colsleft > 1 ) {
-                $targettable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
-                                ' </td>';
-            } elsif ($colsleft == 1) {
-                $targettable .= '<td class="LC_left_item"> </td>';
+    } else {
+        my ($balancerref,$targetsref) =
+                &Apache::lonnet::get_lonbalancer_config($servers);
+        if ((ref($balancerref) eq 'HASH') && (ref($targetsref) eq 'HASH')) {
+            foreach my $server (sort(keys(%{$balancerref}))) {
+                $currbalancer->{$server} = 1;
+                $currtargets->{$server} = $targetsref->{$server};
             }
-            $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.
-                           '<table><tr>'.$targettable.'</table><br />';
         }
     }
-    $datatable .= '</div></td></tr>'.
-                  &loadbalancing_rules($dom,$intdom,$currrules,$othertitle,
-                                       $usertypes,$types,\%servers,$currbalancer,
-                                       $targets_div_style,$homedom_div_style,$css_class);
-    $$rowtotal += $rownum;
-    return $datatable;
+    return;
 }
 
 sub loadbalancing_rules {
     my ($dom,$intdom,$currrules,$othertitle,$usertypes,$types,$servers,
-        $currbalancer,$targets_div_style,$homedom_div_style,$css_class) = @_;
+        $currbalancer,$lonhost,$targets_div_style,$homedom_div_style,
+        $css_class,$balnum,$islast) = @_;
     my $output;
-    my ($alltypes,$othertypes,$titles) = 
+    my $num = 0;
+    my ($alltypes,$othertypes,$titles) =
         &loadbalancing_titles($dom,$intdom,$usertypes,$types);
     if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH'))  {
         foreach my $type (@{$alltypes}) {
+            $num ++;
             my $current;
             if (ref($currrules) eq 'HASH') {
                 $current = $currrules->{$type};
             }
             if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
-                if ($dom ne &Apache::lonnet::host_domain($currbalancer)) {
+                if ($dom ne &Apache::lonnet::host_domain($lonhost)) {
                     $current = '';
                 }
             }
             $output .= &loadbalance_rule_row($type,$titles->{$type},$current,
-                                             $servers,$currbalancer,$dom,
-                                             $targets_div_style,$homedom_div_style,$css_class);
+                                             $servers,$currbalancer,$lonhost,$dom,
+                                             $targets_div_style,$homedom_div_style,
+                                             $css_class,$balnum,$num,$islast);
         }
     }
     return $output;
@@ -3002,8 +3091,8 @@
 }
 
 sub loadbalance_rule_row {
-    my ($type,$title,$current,$servers,$currbalancer,$dom,$targets_div_style,
-        $homedom_div_style,$css_class) = @_;
+    my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom,
+        $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_;
     my @rulenames = ('default','homeserver');
     my %ruletitles = &offloadtype_text();
     if ($type eq '_LC_external') {
@@ -3016,9 +3105,15 @@
     if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
         $style = $homedom_div_style;
     }
-    my $output = 
-        '<tr'.$css_class.'><td valign="top"><div id="balanceruletitle_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
-        '<td><div id="balancerule_'.$type.'" style="'.$style.'">'."\n";
+    my $space;
+    if ($islast && $num == 1) {
+        $space = '<div display="inline-block"> </div>';
+    }
+    my $output =
+        '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space.
+        '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
+        '<td valaign="top">'.$space.
+        '<div id="balancerule_'.$balnum.'_'.$type.'" style="'.$style.'">'."\n";
     for (my $i=0; $i<@rulenames; $i++) {
         my $rule = $rulenames[$i];
         my ($checked,$extra);
@@ -3034,17 +3129,20 @@
                 unless ($checked) {
                     $default = ' selected="selected"';
                 }
-                $extra = ': <select name="loadbalancing_singleserver_'.$type.
-                         '" id="loadbalancing_singleserver_'.$type.
-                         '" onchange="singleServerToggle('."'$type'".')">'."\n".
-                         '<option value=""'.$default.'></option>'."\n";
-                foreach my $lonhost (sort(keys(%{$servers}))) {
-                    next if ($lonhost eq $currbalancer);
+                $extra =
+                    ': <select name="loadbalancing_singleserver_'.$balnum.'_'.$type.
+                    '" id="loadbalancing_singleserver_'.$balnum.'_'.$type.
+                    '" onchange="singleServerToggle('."'$balnum','$type'".')">'."\n".
+                    '<option value=""'.$default.'></option>'."\n";
+                foreach my $server (sort(keys(%{$servers}))) {
+                    if (ref($currbalancer) eq 'HASH') {
+                        next if (exists($currbalancer->{$server}));
+                    }
                     my $selected;
-                    if ($lonhost eq $current) {
+                    if ($server eq $current) {
                         $selected = ' selected="selected"';
                     }
-                    $extra .= '<option value="'.$lonhost.'"'.$selected.'>'.$lonhost.'</option>';
+                    $extra .= '<option value="'.$server.'"'.$selected.'>'.$server.'</option>';
                 }
                 $extra .= '</select>';
             }
@@ -3052,9 +3150,9 @@
             $checked = ' checked="checked"';
         }
         $output .= '<span class="LC_nobreak"><label>'.
-                   '<input type="radio" name="loadbalancing_rules_'.$type.
-                   '" id="loadbalancing_rules_'.$type.'_'.$i.'" value="'.
-                   $rule.'" onclick="balanceruleChange('."this.form,'$type'".
+                   '<input type="radio" name="loadbalancing_rules_'.$balnum.'_'.$type.
+                   '" id="loadbalancing_rules_'.$balnum.'_'.$type.'_'.$i.'" value="'.
+                   $rule.'" onclick="balanceruleChange('."this.form,'$balnum','$type'".
                    ')"'.$checked.' /> '.$ruletitles{$rulenames[$i]}.
                    '</label>'.$extra.'</span><br />'."\n";
     }
@@ -8036,186 +8134,192 @@
     my @sparestypes = ('primary','default');
     my %typetitles = &sparestype_titles();
     my $resulttext;
-    if (keys(%servers) > 1) {
-        my ($currbalancer,$currtargets,$currrules);
-        if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
-            $currbalancer = $domconfig{'loadbalancing'}{'lonhost'};
-            $currtargets = $domconfig{'loadbalancing'}{'targets'};
-            $currrules = $domconfig{'loadbalancing'}{'rules'};
-        } else {
-            ($currbalancer,$currtargets) = 
-                &Apache::lonnet::get_lonbalancer_config(\%servers);
-        }
-        my ($saveloadbalancing,%defaultshash,%changes);
-        my ($alltypes,$othertypes,$titles) =
-            &loadbalancing_titles($dom,$intdom,$usertypes,$types);
-        my %ruletitles = &offloadtype_text();
-        my $balancer = $env{'form.loadbalancing_lonhost'};
-        if (!$servers{$balancer}) {
-            undef($balancer);
-        }
-        if ($currbalancer ne $balancer) {
-            $changes{'lonhost'} = 1;
-        }
-        $defaultshash{'loadbalancing'}{'lonhost'} = $balancer;
-        if ($balancer ne '') {
-            unless (ref($domconfig{'loadbalancing'}) eq 'HASH') {
-                $saveloadbalancing = 1;
+    my (%currbalancer,%currtargets,%currrules,%existing);
+    if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+        %existing = %{$domconfig{'loadbalancing'}};
+    }
+    &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
+                              \%currtargets,\%currrules);
+    my ($saveloadbalancing,%defaultshash,%changes);
+    my ($alltypes,$othertypes,$titles) =
+        &loadbalancing_titles($dom,$intdom,$usertypes,$types);
+    my %ruletitles = &offloadtype_text();
+    my @deletions = &Apache::loncommon::get_env_multiple('form.loadbalancing_delete');
+    for (my $i=0; $i<$env{'form.loadbalancing_total'}; $i++) {
+        my $balancer = $env{'form.loadbalancing_lonhost_'.$i};
+        if ($balancer eq '') {
+            next;
+        }
+        if (!exists($servers{$balancer})) {
+            if (exists($currbalancer{$balancer})) {
+                push(@{$changes{'delete'}},$balancer);
             }
-            foreach my $sparetype (@sparestypes) {
-                my @targets = &Apache::loncommon::get_env_multiple('form.loadbalancing_target_'.$sparetype);
-                my @offloadto;
-                foreach my $target (@targets) {
-                    if (($servers{$target}) && ($target ne $balancer)) {
-                        if ($sparetype eq 'default') {
-                            if (ref($defaultshash{'loadbalancing'}{'targets'}{'primary'}) eq 'ARRAY') {
-                                next if (grep(/^\Q$target\E$/,@{$defaultshash{'loadbalancing'}{'targets'}{'primary'}}));
-                            }
-                        }
-                        unless(grep(/^\Q$target\E$/, at offloadto)) {
-                            push(@offloadto,$target);
+            next;
+        }
+        if ((@deletions > 0) && (grep(/^\Q$i\E$/, at deletions))) {
+            push(@{$changes{'delete'}},$balancer);
+            next;
+        }
+        if (!exists($currbalancer{$balancer})) {
+            push(@{$changes{'add'}},$balancer);
+        }
+        $defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'} = [];
+        $defaultshash{'loadbalancing'}{$balancer}{'targets'}{'default'} = [];
+        $defaultshash{'loadbalancing'}{$balancer}{'rules'} = {};
+        unless (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+            $saveloadbalancing = 1;
+        }
+        foreach my $sparetype (@sparestypes) {
+            my @targets = &Apache::loncommon::get_env_multiple('form.loadbalancing_target_'.$i.'_'.$sparetype);
+            my @offloadto;
+            foreach my $target (@targets) {
+                if (($servers{$target}) && ($target ne $balancer)) {
+                    if ($sparetype eq 'default') {
+                        if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'}) eq 'ARRAY') {
+                            next if (grep(/^\Q$target\E$/,@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'}}));
                         }
                     }
-                    $defaultshash{'loadbalancing'}{'targets'}{$sparetype} = \@offloadto;
+                    unless(grep(/^\Q$target\E$/, at offloadto)) {
+                        push(@offloadto,$target);
+                    }
                 }
-            }
-        } else {
-            foreach my $sparetype (@sparestypes) {
-                $defaultshash{'loadbalancing'}{'targets'}{$sparetype} = [];
+                $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
             }
         }
-        if (ref($currtargets) eq 'HASH') {
+        if (ref($currtargets{$balancer}) eq 'HASH') {
             foreach my $sparetype (@sparestypes) {
-                if (ref($currtargets->{$sparetype}) eq 'ARRAY') {
-                    my @targetdiffs = &Apache::loncommon::compare_arrays($currtargets->{$sparetype},$defaultshash{'loadbalancing'}{'targets'}{$sparetype});
+                if (ref($currtargets{$balancer}{$sparetype}) eq 'ARRAY') {
+                    my @targetdiffs = &Apache::loncommon::compare_arrays($currtargets{$balancer}{$sparetype},$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype});
                     if (@targetdiffs > 0) {
-                        $changes{'targets'} = 1;
+                        $changes{'curr'}{$balancer}{'targets'} = 1;
                     }
-                } elsif (ref($defaultshash{'loadbalancing'}{'targets'}{$sparetype}) eq 'ARRAY') {
-                    if (@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}} > 0) {
-                        $changes{'targets'} = 1;
+                } elsif (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
+                    if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
+                        $changes{'curr'}{$balancer}{'targets'} = 1;
                     }
                 }
             }
         } else {
-            foreach my $sparetype (@sparestypes) {
-                if (ref($defaultshash{'loadbalancing'}{'targets'}{$sparetype}) eq 'ARRAY') {
-                    if (@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}} > 0) {
-                        $changes{'targets'} = 1;  
+            if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') {
+                foreach my $sparetype (@sparestypes) {
+                    if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
+                        if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
+                            $changes{'curr'}{$balancer}{'targets'} = 1;
+                        }
                     }
                 }
-            }  
+            }
         }
         my $ishomedom;
-        if ($balancer ne '') {
-            if (&Apache::lonnet::host_domain($balancer) eq $dom) {
-                $ishomedom = 1;
-            }
+        if (&Apache::lonnet::host_domain($balancer) eq $dom) {
+            $ishomedom = 1;
         }
         if (ref($alltypes) eq 'ARRAY') {
             foreach my $type (@{$alltypes}) {
                 my $rule;
-                if ($balancer ne '') {
-                    unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) && 
+                unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) &&
                          (!$ishomedom)) {
-                        $rule = $env{'form.loadbalancing_rules_'.$type};
-                    }
-                    if ($rule eq 'specific') {
-                        $rule = $env{'form.loadbalancing_singleserver_'.$type};
-                    }
+                    $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};
+                }
+                if ($rule eq 'specific') {
+                    $rule = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
                 }
-                $defaultshash{'loadbalancing'}{'rules'}{$type} = $rule;
-                if (ref($currrules) eq 'HASH') {
-                    if ($rule ne $currrules->{$type}) {
-                        $changes{'rules'}{$type} = 1;
+                $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type} = $rule;
+                if (ref($currrules{$balancer}) eq 'HASH') {
+                    if ($rule ne $currrules{$balancer}{$type}) {
+                        $changes{'curr'}{$balancer}{'rules'}{$type} = 1;
                     }
                 } elsif ($rule ne '') {
-                    $changes{'rules'}{$type} = 1;
+                    $changes{'curr'}{$balancer}{'rules'}{$type} = 1;
                 }
             }
         }
-        my $nochgmsg = &mt('No changes made to Load Balancer settings.');
-        if ((keys(%changes) > 0) || ($saveloadbalancing)) {
-            my $putresult = &Apache::lonnet::put_dom('configuration',
-                                                     \%defaultshash,$dom);
-            if ($putresult eq 'ok') {
-                if (keys(%changes) > 0) {
-                    if ($changes{'lonhost'}) {
-                        if ($currbalancer ne '') {
-                            &Apache::lonnet::remote_devalidate_cache($currbalancer,'loadbalancing',$dom);
-                        }
-                        if ($balancer eq '') {
-                            $resulttext .= '<li>'.&mt('Load Balancing with dedicated server discontinued').'</li>'; 
-                        } else {
-                            &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
-                            $resulttext .= '<li>'.&mt('Dedicated Load Balancer server set to [_1]',$balancer);
-                        }
-                    } else {
+    }
+    my $nochgmsg = &mt('No changes made to Load Balancer settings.');
+    if ((keys(%changes) > 0) || ($saveloadbalancing)) {
+        unless (ref($defaultshash{'loadbalancing'}) eq 'HASH') {
+            $defaultshash{'loadbalancing'} = {};
+        }
+        my $putresult = &Apache::lonnet::put_dom('configuration',
+                                                 \%defaultshash,$dom);
+
+        if ($putresult eq 'ok') {
+            if (keys(%changes) > 0) {
+                if (ref($changes{'delete'}) eq 'ARRAY') {
+                    foreach my $balancer (sort(@{$changes{'delete'}})) {
+                        $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';
                         &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
                     }
-                    if (($changes{'targets'}) && ($balancer ne '')) {
-                        my %offloadstr;
-                        foreach my $sparetype (@sparestypes) {
-                            if (ref($defaultshash{'loadbalancing'}{'targets'}{$sparetype}) eq 'ARRAY') {
-                                if (@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}} > 0) {
-                                    $offloadstr{$sparetype} = join(', ',@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}});
+                }
+                if (ref($changes{'add'}) eq 'ARRAY') {
+                    foreach my $balancer (sort(@{$changes{'add'}})) {
+                        $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);
+                    }
+                }
+                if (ref($changes{'curr'}) eq 'HASH') {
+                    foreach my $balancer (sort(keys(%{$changes{'curr'}}))) {
+                        if (ref($changes{'curr'}{$balancer}) eq 'HASH') {
+                            if ($changes{'curr'}{$balancer}{'targets'}) {
+                                my %offloadstr;
+                                foreach my $sparetype (@sparestypes) {
+                                    if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
+                                        if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
+                                            $offloadstr{$sparetype} = join(', ',@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}});
+                                        }
+                                    }
                                 }
-                            }
-                        }
-                        if (keys(%offloadstr) == 0) {
-                            $resulttext .= '<li>'.&mt("Servers to which Load Balance server offloads set to 'None', by default").'</li>';
-                        } else {
-                            my $showoffload;
-                            foreach my $sparetype (@sparestypes) {
-                                $showoffload .= '<i>'.$typetitles{$sparetype}.'</i>: ';
-                                if (defined($offloadstr{$sparetype})) {
-                                    $showoffload .= $offloadstr{$sparetype};
+                                if (keys(%offloadstr) == 0) {
+                                    $resulttext .= '<li>'.&mt("Servers to which Load Balance server offloads set to 'None', by default").'</li>';
                                 } else {
-                                    $showoffload .= &mt('None');
+                                    my $showoffload;
+                                    foreach my $sparetype (@sparestypes) {
+                                        $showoffload .= '<i>'.$typetitles{$sparetype}.'</i>: ';
+                                        if (defined($offloadstr{$sparetype})) {
+                                            $showoffload .= $offloadstr{$sparetype};
+                                        } else {
+                                            $showoffload .= &mt('None');
+                                        }
+                                        $showoffload .= (' 'x3);
+                                    }
+                                    $resulttext .= '<li>'.&mt('By default, Load Balancer: [_1] set to offload to - [_2]',$balancer,$showoffload).'</li>';
                                 }
-                                $showoffload .= (' 'x3);
                             }
-                            $resulttext .= '<li>'.&mt('By default, Load Balancer server set to offload to: [_1]',$showoffload).'</li>';
                         }
-                    }
-                    if ((ref($changes{'rules'}) eq 'HASH') && ($balancer ne '')) {
-                        if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH')) {
-                            foreach my $type (@{$alltypes}) {
-                                if ($changes{'rules'}{$type}) {
-                                    my $rule = $defaultshash{'loadbalancing'}{'rules'}{$type};
-                                    my $balancetext;
-                                    if ($rule eq '') {
-                                        $balancetext =  $ruletitles{'default'};
-                                    } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer')) {
-                                        $balancetext =  $ruletitles{$rule};
-                                    } else {
-                                        $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{'rules'}{$type});
+                        if (ref($changes{'curr'}{$balancer}{'rules'}) eq 'HASH') {
+                            if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH')) {
+                                foreach my $type (@{$alltypes}) {
+                                    if ($changes{'curr'}{$balancer}{'rules'}{$type}) {
+                                        my $rule = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type};
+                                        my $balancetext;
+                                        if ($rule eq '') {
+                                            $balancetext =  $ruletitles{'default'};
+                                        } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer')) {
+                                            $balancetext =  $ruletitles{$rule};
+                                        } else {
+                                            $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});
+                                        }
+                                        $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'</li>'; 
                                     }
-                                    $resulttext .= '<li>'.&mt('Load Balancing for [_1] set to: [_2]',$titles->{$type},$balancetext).'</li>';     
                                 }
                             }
                         }
+                        &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
                     }
-                    if ($resulttext ne '') {
-                        $resulttext = &mt('Changes made:').'<ul>'.$resulttext.'</ul>';
-                    } else {
-                        $resulttext = $nochgmsg;
-                    }
+                }
+                if ($resulttext ne '') {
+                    $resulttext = &mt('Changes made:').'<ul>'.$resulttext.'</ul>';
                 } else {
                     $resulttext = $nochgmsg;
-                    if ($balancer ne '') {
-                        &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
-                    }
                 }
             } else {
-                $resulttext = '<span class="LC_error">'.
-                              &mt('An error occurred: [_1]',$putresult).'</span>';
+                $resulttext = $nochgmsg;
             }
         } else {
-            $resulttext = $nochgmsg;
+            $resulttext = '<span class="LC_error">'.
+                          &mt('An error occurred: [_1]',$putresult).'</span>';
         }
     } else {
-        $resulttext =  &mt('Load Balancing unavailable as this domain only has one server.');
+        $resulttext = $nochgmsg;
     }
     return $resulttext;
 }
@@ -8371,7 +8475,7 @@
 }
 
 sub lonbalance_targets_js {
-    my ($dom,$types,$servers) = @_;
+    my ($dom,$types,$servers,$settings) = @_;
     my $select = &mt('Select');
     my ($alltargets,$allishome,$allinsttypes, at alltypes);
     if (ref($servers) eq 'HASH') {
@@ -8393,39 +8497,71 @@
     }
     push(@alltypes,'default','_LC_adv','_LC_author','_LC_internetdom','_LC_external');
     $allinsttypes = join("','", at alltypes);
+    my (%currbalancer,%currtargets,%currrules,%existing);
+    if (ref($settings) eq 'HASH') {
+        %existing = %{$settings};
+    }
+    &get_loadbalancers_config($servers,\%existing,\%currbalancer,
+                              \%currtargets,\%currrules);
+    my $balancers = join("','",sort(keys(%currbalancer)));
     return <<"END";
 
 <script type="text/javascript">
 // <![CDATA[
 
-function toggleTargets() {
-    var balancer = document.display.loadbalancing_lonhost.options[document.display.loadbalancing_lonhost.selectedIndex].value;
+currBalancers = new Array('$balancers');
+
+function toggleTargets(balnum) {
+    var lonhostitem = document.getElementById('loadbalancing_lonhost_'+balnum);
+    var prevhostitem = document.getElementById('loadbalancing_prevlonhost_'+balnum);
+    var balancer = lonhostitem.options[lonhostitem.selectedIndex].value;
+    var prevbalancer = prevhostitem.value;
+    var baltotal = document.getElementById('loadbalancing_total').value;
+    prevhostitem.value = balancer;
+    if (prevbalancer != '') {
+        var prevIdx = currBalancers.indexOf(prevbalancer);
+        if (prevIdx != -1) {
+            currBalancers.splice(prevIdx,1);
+        }
+    }
     if (balancer == '') {
-        hideSpares();
+        hideSpares(balnum);
     } else {
+        var currIdx = currBalancers.indexOf(balancer);
+        if (currIdx == -1) {
+            currBalancers.push(balancer);
+        }
         var homedoms = new Array('$allishome');
-        var ishomedom = homedoms[document.display.loadbalancing_lonhost.selectedIndex];
-        showSpares(balancer,ishomedom);
+        var ishomedom = homedoms[lonhostitem.selectedIndex];
+        showSpares(balancer,ishomedom,balnum);
     }
+    balancerChange(balnum,baltotal,'change',prevbalancer,balancer);
     return;
 }
 
-function showSpares(balancer,ishomedom) {
+function showSpares(balancer,ishomedom,balnum) {
     var alltargets = new Array('$alltargets');
     var insttypes = new Array('$allinsttypes');
     var offloadtypes = new Array('primary','default');
 
-    document.getElementById('loadbalancing_targets').style.display='block';
-    document.getElementById('loadbalancing_disabled').style.display='none';
+    document.getElementById('loadbalancing_targets_'+balnum).style.display='block';
+    document.getElementById('loadbalancing_disabled_'+balnum).style.display='none';
  
     for (var i=0; i<offloadtypes.length; i++) {
         var count = 0;
         for (var j=0; j<alltargets.length; j++) {
             if (alltargets[j] != balancer) {
-                document.getElementById('loadbalancing_target_'+offloadtypes[i]+'_'+count).value = alltargets[j];
-                document.getElementById('loadbalancing_targettxt_'+offloadtypes[i]+'_'+count).style.textAlign='left';
-                document.getElementById('loadbalancing_targettxt_'+offloadtypes[i]+'_'+count).style.textFace='normal';
-                document.getElementById('loadbalancing_targettxt_'+offloadtypes[i]+'_'+count).innerHTML = alltargets[j];
+                var item = document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+count);
+                item.value = alltargets[j];
+                item.style.textAlign='left';
+                item.style.textFace='normal';
+                document.getElementById('loadbalancing_targettxt_'+balnum+'_'+offloadtypes[i]+'_'+count).innerHTML = alltargets[j];
+                if (currBalancers.indexOf(alltargets[j]) == -1) {
+                    item.disabled = '';
+                } else {
+                    item.disabled = 'disabled';
+                    item.checked = false;
+                }
                 count ++;
             }
         }
@@ -8433,25 +8569,29 @@
     for (var k=0; k<insttypes.length; k++) {
         if ((insttypes[k] == '_LC_external') || (insttypes[k] == '_LC_internetdom')) {
             if (ishomedom == 1) {
-                document.getElementById('balanceruletitle_'+insttypes[k]).style.display='block';
-                document.getElementById('balancerule_'+insttypes[k]).style.display='block';
+                document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
+                document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='block';
             } else {
-                document.getElementById('balanceruletitle_'+insttypes[k]).style.display='none';
-                document.getElementById('balancerule_'+insttypes[k]).style.display='none';
+                document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
+                document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
 
             }
         } else {
-            document.getElementById('balanceruletitle_'+insttypes[k]).style.display='block';
-            document.getElementById('balancerule_'+insttypes[k]).style.display='block';
+            document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
+            document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='block';
         }
         if ((insttypes[k] != '_LC_external') && 
             ((insttypes[k] != '_LC_internetdom') ||
              ((insttypes[k] == '_LC_internetdom') && (ishomedom == 1)))) {
-            document.getElementById('loadbalancing_singleserver_'+insttypes[k]).options[0] = new Option("","",true,true);
+            var item = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]);
+            item.options.length = 0;
+            item.options[0] = new Option("","",true,true);
+            var idx = 0;
             for (var m=0; m<alltargets.length; m++) {
-                var idx = m+1;
-                if (alltargets[m] != balancer) {
-                    document.getElementById('loadbalancing_singleserver_'+insttypes[k]).options[idx] = new Option(alltargets[m],alltargets[m],false,false);
+                if ((currBalancers.indexOf(alltargets[m]) == -1) && (alltargets[m] != balancer)) {
+                    idx ++;
+                    item.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
+
                 }
             }
         }
@@ -8459,34 +8599,34 @@
     return;
 }
 
-function hideSpares() {
+function hideSpares(balnum) {
     var alltargets = new Array('$alltargets');
     var insttypes = new Array('$allinsttypes');
     var offloadtypes = new Array('primary','default');
 
-    document.getElementById('loadbalancing_targets').style.display='none';
-    document.getElementById('loadbalancing_disabled').style.display='block';
+    document.getElementById('loadbalancing_targets_'+balnum).style.display='none';
+    document.getElementById('loadbalancing_disabled_'+balnum).style.display='block';
 
     var total = alltargets.length - 1;
     for (var i=0; i<offloadtypes; i++) {
         for (var j=0; j<total; j++) {
-           document.getElementById('loadbalancing_target_'+offloadtypes[i]+'_'+j).checked = false;
-           document.getElementById('loadbalancing_target_'+offloadtypes[i]+'_'+j).value = '';
-           document.getElementById('loadbalancing_targettxt_'+offloadtypes[i]+'_'+j).innerHTML = '';
+           document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+j).checked = false;
+           document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+j).value = '';
+           document.getElementById('loadbalancing_targettxt_'+balnum+'_'+offloadtypes[i]+'_'+j).innerHTML = '';
         }
     }
     for (var k=0; k<insttypes.length; k++) {
-        document.getElementById('balanceruletitle_'+insttypes[k]).style.display='none';
-        document.getElementById('balancerule_'+insttypes[k]).style.display='none';
+        document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
+        document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
         if (insttypes[k] != '_LC_external') {
-            document.getElementById('loadbalancing_singleserver_'+insttypes[k]).length = 0;
-            document.getElementById('loadbalancing_singleserver_'+insttypes[k]).options[0] = new Option("","",true,true);
+            document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]).length = 0;
+            document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]).options[0] = new Option("","",true,true);
         }
     }
     return;
 }
 
-function checkOffloads(item,type) {
+function checkOffloads(item,balnum,type) {
     var alltargets = new Array('$alltargets');
     var offloadtypes = new Array('primary','default');
     if (item.checked) {
@@ -8498,10 +8638,10 @@
             other = offloadtypes[0];
         }
         for (var i=0; i<total; i++) {
-            var server = document.getElementById('loadbalancing_target_'+other+'_'+i).value;
+            var server = document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).value;
             if (server == item.value) {
-                if (document.getElementById('loadbalancing_target_'+other+'_'+i).checked) {
-                    document.getElementById('loadbalancing_target_'+other+'_'+i).checked = false;
+                if (document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).checked) {
+                    document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).checked = false;
                 }
             }
         }
@@ -8509,31 +8649,129 @@
     return;
 }
 
-function singleServerToggle(type) {
-    var offloadtoSelIdx = document.getElementById('loadbalancing_singleserver_'+type).selectedIndex;
+function singleServerToggle(balnum,type) {
+    var offloadtoSelIdx = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).selectedIndex;
     if (offloadtoSelIdx == 0) {
-        document.getElementById('loadbalancing_rules_'+type+'_0').checked = true;
-        document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '';
+        document.getElementById('loadbalancing_rules_'+balnum+'_'+type+'_0').checked = true;
+        document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '';
 
     } else {
-        document.getElementById('loadbalancing_rules_'+type+'_2').checked = true;
-        document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '$select';
+        document.getElementById('loadbalancing_rules_'+balnum+'_'+type+'_2').checked = true;
+        document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '$select';
     }
     return;
 }
 
-function balanceruleChange(formname,type) {
+function balanceruleChange(formname,balnum,type) {
     if (type == '_LC_external') {
         return; 
     }
-    var typesRules = getIndicesByName(formname,'loadbalancing_rules_'+type);
+    var typesRules = getIndicesByName(formname,'loadbalancing_rules_'+balnum+'_'+type);
     for (var i=0; i<typesRules.length; i++) {
         if (formname.elements[typesRules[i]].checked) {
             if (formname.elements[typesRules[i]].value != 'specific') {
-                document.getElementById('loadbalancing_singleserver_'+type).selectedIndex = 0;
-                document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '';
+                document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).selectedIndex = 0;
+                document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '';
             } else {
-                document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '$select';
+                document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '$select';
+            }
+        }
+    }
+    return;
+}
+
+function balancerDeleteChange(balnum) {
+    var hostitem = document.getElementById('loadbalancing_lonhost_'+balnum);
+    var baltotal = document.getElementById('loadbalancing_total').value;
+    var addtarget;
+    var removetarget;
+    var action = 'delete';
+    if (document.getElementById('loadbalancing_delete_'+balnum)) {
+        var lonhost = hostitem.value;
+        var currIdx = currBalancers.indexOf(lonhost);
+        if (document.getElementById('loadbalancing_delete_'+balnum).checked) {
+            if (currIdx != -1) {
+                currBalancers.splice(currIdx,1);
+            }
+            addtarget = lonhost;
+        } else {
+            if (currIdx == -1) {
+                currBalancers.push(lonhost);
+            }
+            removetarget = lonhost;
+            action = 'undelete';
+        }
+        balancerChange(balnum,baltotal,action,addtarget,removetarget);
+    }
+    return;
+}
+
+function balancerChange(balnum,baltotal,action,addtarget,removetarget) {
+    if (baltotal > 1) {
+        var offloadtypes = new Array('primary','default');
+        var alltargets = new Array('$alltargets');
+        var insttypes = new Array('$allinsttypes');
+        for (var i=0; i<baltotal; i++) {
+            if (i != balnum) {
+                for (var j=0; j<offloadtypes.length; j++) {
+                    var total = alltargets.length - 1;
+                    for (var k=0; k<total; k++) {
+                        var serveritem = document.getElementById('loadbalancing_target_'+i+'_'+offloadtypes[j]+'_'+k);
+                        var server = serveritem.value;
+                        if ((action == 'delete') || (action == 'change' && addtarget != ''))  {
+                            if (server == addtarget) {
+                                serveritem.disabled = '';
+                            }
+                        }
+                        if ((action == 'undelete') || (action == 'change' && removetarget != '')) {
+                            if (server == removetarget) {
+                                serveritem.disabled = 'disabled';
+                                serveritem.checked = false;
+                            }
+                        }
+                    }
+                }
+                for (var j=0; j<insttypes.length; j++) {
+                    if (insttypes[j] != '_LC_external') {
+                        if (document.getElementById('loadbalancing_singleserver_'+i+'_'+insttypes[j])) {
+                            var singleserver = document.getElementById('loadbalancing_singleserver_'+i+'_'+insttypes[j]);
+                            var currSel = singleserver.selectedIndex;
+                            var currVal = singleserver.options[currSel].value;
+                            if ((action == 'delete') || (action == 'change' && addtarget != '')) {
+                                var numoptions = singleserver.options.length;
+                                var needsnew = 1;
+                                for (var k=0; k<numoptions; k++) {
+                                    if (singleserver.options[k] == addtarget) {
+                                        needsnew = 0;
+                                        break;
+                                    }
+                                }
+                                if (needsnew == 1) {
+                                    singleserver.options[numoptions] = new Option(addtarget,addtarget,false,false);
+                                }
+                            }
+                            if ((action == 'undelete') || (action == 'change' && removetarget != '')) {
+                                singleserver.options.length = 0;
+                                if ((currVal) && (currVal != removetarget)) {
+                                    singleserver.options[0] = new Option("","",false,false);
+                                } else {
+                                    singleserver.options[0] = new Option("","",true,true);
+                                }
+                                var idx = 0;
+                                for (var m=0; m<alltargets.length; m++) {
+                                    if (currBalancers.indexOf(alltargets[m]) == -1) {
+                                        idx ++;
+                                        if (currVal == alltargets[m]) {
+                                            singleserver.options[idx] = new Option(alltargets[m],alltargets[m],true,true);
+                                        } else {
+                                            singleserver.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
             }
         }
     }


More information about the LON-CAPA-cvs mailing list