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

raeburn lon-capa-cvs-allow@mail.lon-capa.org
Thu, 08 May 2008 22:13:32 -0000


This is a MIME encoded message

--raeburn1210284812
Content-Type: text/plain

raeburn		Thu May  8 18:13:32 2008 EDT

  Modified files:              
    /loncom/interface	domainprefs.pm 
  Log:
  - javascript to automatically update selections in select boxes for a particular category when the position of one subcategory is changed.
  
  
--raeburn1210284812
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20080508181332.txt"

Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.48 loncom/interface/domainprefs.pm:1.49
--- loncom/interface/domainprefs.pm:1.48	Wed May  7 19:01:50 2008
+++ loncom/interface/domainprefs.pm	Thu May  8 18:13:32 2008
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.48 2008/05/07 23:01:50 raeburn Exp $
+# $Id: domainprefs.pm,v 1.49 2008/05/08 22:13:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -370,7 +370,11 @@
 sub print_config_box {
     my ($r,$dom,$confname,$phase,$action,$item,$settings) = @_;
     my $rowtotal = 0;
-    my $output = 
+    my $output;
+    if ($action eq 'coursecategories') {
+        $output = &coursecategories_javascript($settings);
+    }  
+    $output .= 
          '<table class="LC_nested_outer">
           <tr>
            <th align="left"><span class="LC_nobreak">'.&mt($item->{text}).
@@ -1935,15 +1939,14 @@
     return ($url,$error);
 }
 
-sub print_coursecategories { 
-    my ($dom,$item,$settings,$rowtotal) = @_;
+sub print_coursecategories {
+    my ($dom,$hdritem,$settings,$rowtotal) = @_;
     my ($datatable,$css_class);
     my $itemcount = 1;
-    # FIXME Need to add javascrpt to update other select boxes when one is changed.
     if (ref($settings) eq 'HASH') {
-        my (@cats,@trails,%allitems);
-        &extract_categories($settings,\@cats,\@trails,\%allitems);
-        my $maxdepth = scalar(@cats); 
+        my (@cats,@trails,%allitems,%idx,@jsarray);
+        &extract_categories($settings,\@cats,\@trails,\%allitems,\%idx,\@jsarray);
+        my $maxdepth = scalar(@cats);
         my $colattrib = '';
         if ($maxdepth > 2) {
             $colattrib = ' colspan="2" ';
@@ -1956,12 +1959,15 @@
                 if ((!grep(/^instcode$/,@{$cats[0]})) || ($settings->{'instcode::0'} eq '')) {
                     $maxnum ++;
                 }
+                my $lastidx;
                 for (my $i=0; $i<$numtop; $i++) {
                     my $parent = $cats[0][$i];
                     $css_class = $itemcount%2?' class="LC_odd_row"':'';
                     my $item = &escape($parent).'::0';
+                    my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$item','$idx{$item}'".');"';
+                    $lastidx = $idx{$item};
                     $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
-                                  .'<select name="'.$item.'">';
+                                  .'<select name="'.$item.'"'.$chgstr.'>';
                     for (my $k=0; $k<=$maxnum; $k++) {
                         my $vpos = $k+1;
                         my $selstr;
@@ -1986,13 +1992,14 @@
                     }
                     my $depth = 1;
                     push(@path,$parent);
-                    $datatable .= &build_category_rows($itemcount,\@cats,$depth,$parent,\@path);
+                    $datatable .= &build_category_rows($itemcount,\@cats,$depth,$parent,\@path,\%idx);
                     pop(@path);
                     $datatable .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>';
                     $itemcount ++;
                 }
                 $css_class = $itemcount%2?' class="LC_odd_row"':'';
-                $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="addcategory_pos">';
+                my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','$lastidx'".');"';
+                $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="addcategory_pos"'.$chgstr.'>';
                 for (my $k=0; $k<=$maxnum; $k++) {
                     my $vpos = $k+1;
                     my $selstr;
@@ -2007,8 +2014,9 @@
                 $itemcount ++;
                 if ((!grep(/^instcode$/,@{$cats[0]})) || ($settings->{'instcode::0'} eq '')) {
                     $css_class = $itemcount%2?' class="LC_odd_row"':'';
+                    my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','instcode_pos','$lastidx'".');"';
                     $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'.
-                                  '<span class="LC_nobreak"><select name="instcode_pos">';
+                                  '<span class="LC_nobreak"><select name="instcode_pos"'.$chgstr.'>';
                     for (my $k=0; $k<=$maxnum; $k++) {
                         my $vpos = $k+1;
                         my $selstr;
@@ -2030,17 +2038,102 @@
             $datatable .= &initialize_categories($itemcount);
         }
     } else {
-        $datatable .= '<td class="LC_right_item">'.$item->{'header'}->[0]->{'col2'}.'</td>'
+        $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[0]->{'col2'}.'</td>'
                       .&initialize_categories($itemcount);
     }
     $$rowtotal += $itemcount;
     return $datatable;
 }
 
+sub coursecategories_javascript {
+    my ($settings) = @_;
+    my ($output,$jstext);
+    if (ref($settings) eq 'HASH') {
+        my (@cats,@jsarray,%idx);
+        &gather_categories($settings,\@cats,\%idx,\@jsarray);
+        if (@jsarray > 0) {
+            $jstext = '    var categories = Array('.scalar(@jsarray).');'."\n";
+            for (my $i=0; $i<@jsarray; $i++) {
+                if (ref($jsarray[$i]) eq 'ARRAY') {
+                    my $catstr = join('","',@{$jsarray[$i]});
+                    $jstext .= '    categories['.$i.'] = Array("'.$catstr.'");'."\n";
+                }
+            }
+        }
+    } else {
+        $jstext  = '    var categories = Array(1);'."\n".
+                   '    categories[0] = Array("instcode_pos");'."\n"; 
+    }
+    $output = <<"ENDSCRIPT";
+<script type="text/javascript">
+function reorderCats(form,parent,item,idx) {
+    var changedVal;
+$jstext
+    var newpos = 'addcategory_pos';
+    var current = new Array;
+    if (parent == '') {
+        var has_instcode = 0;
+        var maxtop = categories[idx].length;
+        for (var j=0; j<maxtop; j++) {
+            if (categories[idx][j] == 'instcode::0') {
+                has_instcode == 1;
+            }
+        }
+        if (has_instcode == 0) {
+            categories[idx][maxtop] = 'instcode_pos';
+        }
+    } else {
+        newpos += '_'+parent;
+    }
+    var maxh = 1 + categories[idx].length;
+    var current = new Array;
+    var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
+    if (item == newpos) {
+        changedVal = newitemVal;
+    } else {
+        changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
+        current[newitemVal] = newpos;
+    }
+    for (var i=0; i<categories[idx].length; i++) {
+        var elementName = categories[idx][i];
+        if (elementName != item) {
+            if (form.elements[elementName]) {
+                var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
+                current[currVal] = elementName;
+            }
+        }
+    }
+    var oldVal;
+    for (var j=0; j<maxh; j++) {
+        if (current[j] == undefined) {
+            oldVal = j;
+        }
+    }
+    if (oldVal < changedVal) {
+        for (var k=oldVal+1; k<=changedVal ; k++) {
+           var elementName = current[k];
+           form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
+        }
+    } else {
+        for (var k=changedVal; k<oldVal; k++) {
+            var elementName = current[k];
+            form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
+        }
+    }
+    return;
+}
+</script>
+
+ENDSCRIPT
+    return $output;
+}
+
 sub initialize_categories {
     my ($itemcount) = @_;
     my $datatable;
     my $css_class = $itemcount%2?' class="LC_odd_row"':'';
+    my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','instcode_pos','0'".');"';
+
     $datatable = '<tr '.$css_class.'><td><span class="LC_nobreak">'
                  .'<select name="instcode_pos"><option value="0" selected="selected">1</option>'
                  .'<option value="1">2</option></select>&nbsp;'
@@ -2052,8 +2145,9 @@
                  .'</label></span></td></tr>';
     $itemcount ++;
     $css_class = $itemcount%2?' class="LC_odd_row"':'';
+    $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','0'".');"';
     $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
-                  .'<select name="addcategory_pos"><option value="0">1</option>'
+                  .'<select name="addcategory_pos"'.$chgstr/'><option value="0">1</option>'
                   .'<option value="1" selected="selected">2</option></select>&nbsp;'
                   .&mt('Add category').'</td><td>'.&mt('Name:')
                   .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></td></tr>';
@@ -2061,8 +2155,8 @@
 }
 
 sub build_category_rows {
-    my ($itemcount,$cats,$depth,$parent,$path) = @_;
-    my ($text,$name,$item);
+    my ($itemcount,$cats,$depth,$parent,$path,$idx) = @_;
+    my ($text,$name,$item,$chgstr);
     if (ref($cats) eq 'ARRAY') {
         my $maxdepth = scalar(@{$cats});
         if (ref($cats->[$depth]) eq 'HASH') {
@@ -2070,22 +2164,27 @@
                 my $numchildren = @{$cats->[$depth]{$parent}};
                 my $css_class = $itemcount%2?' class="LC_odd_row"':'';
                 $text .= '<td><table class="LC_datatable">';
+                my ($idxnum,$parent_name,$parent_item);
+                my $higher = $depth - 1;
+                if ($higher == 0) {
+                    $parent_name = &escape($parent).'::'.$higher;
+                } else {
+                    if (ref($path) eq 'ARRAY') {
+                        $parent_name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
+                    }
+                }
+                $parent_item = 'addcategory_pos_'.$parent_name;
                 for (my $j=0; $j<=$numchildren; $j++) {
-                    if ($j == $numchildren) {
-                        my $higher = $depth-1;
-                        if ($higher == 0) {
-                            $name = &escape($parent).'::'.$higher;
-                        } else {
-                            if (ref($path) eq 'ARRAY') {
-                                $name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
-                            }
-                        }
-                        $item = 'addcategory_pos_'.$name;
-                    } else {
+                    if ($j < $numchildren) {
                         $name = $cats->[$depth]{$parent}[$j];
                         $item = &escape($name).':'.&escape($parent).':'.$depth;
+                        $idxnum = $idx->{$item};
+                    } else {
+                        $name = $parent_name;
+                        $item = $parent_item;
                     }
-                    $text .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="'.$item.'">';
+                    $chgstr = ' onchange="javascript:reorderCats(this.form,'."'$parent_name','$item','$idxnum'".');"';
+                    $text .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="'.$item.'"'.$chgstr.'>';
                     for (my $i=0; $i<=$numchildren; $i++) {
                         my $vpos = $i+1;
                         my $selstr;
@@ -2102,7 +2201,7 @@
                                  .$item.'" />'.&mt('Delete').'</label></span></td><td>';
                         if(ref($path) eq 'ARRAY') {
                             push(@{$path},$name);
-                            $text .= &build_category_rows($itemcount,$cats,$deeper,$name,$path);
+                            $text .= &build_category_rows($itemcount,$cats,$deeper,$name,$path,$idx);
                             pop(@{$path});
                         }
                     } else {
@@ -4226,22 +4325,41 @@
     return;
 }
 
+sub gather_categories {
+    my ($categories,$cats,$idx,$jsarray) = @_;
+    my %counters;
+    my $num = 0;
+    foreach my $item (keys(%{$categories})) {
+        my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item);
+        if ($container eq '' && $depth == 0) {
+            $cats->[$depth][$categories->{$item}] = $cat;
+        } else {
+            $cats->[$depth]{$container}[$categories->{$item}] = $cat;
+        }
+        my ($escitem,$tail) = split(/:/,$item,2);
+        if ($counters{$tail} eq '') {
+            $counters{$tail} = $num;
+            $num ++;
+        }
+        if (ref($idx) eq 'HASH') {
+            $idx->{$item} = $counters{$tail};
+        }
+        if (ref($jsarray) eq 'ARRAY') { 
+            push(@{$jsarray->[$counters{$tail}]},$item);
+        }
+    }
+    return;
+}
+
 sub extract_categories {
-    my ($categories,$cats,$trails,$allitems) = @_;
+    my ($categories,$cats,$trails,$allitems,$idx,$jsarray) = @_;
     if (ref($categories) eq 'HASH') {
-        foreach my $item (keys(%{$categories})) {
-            my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item);
-            if ($container eq '' && $depth == 0) {
-                $cats->[$depth][$categories->{$item}] = $cat;
-            } else {
-                $cats->[$depth]{$container}[$categories->{$item}] = $cat;
-            }
-        }
+        &gather_categories($categories,$cats,$idx,$jsarray);
         if (ref($cats->[0]) eq 'ARRAY') {
             for (my $i=0; $i<@{$cats->[0]}; $i++) {
                 my $name = $cats->[0][$i];
                 my $item = &escape($name).'::0';
-                my $trailstr; 
+                my $trailstr;
                 if ($name eq 'instcode') {
                     $trailstr = &mt('Official courses (with institutional codes)');
                 } else {
@@ -4266,9 +4384,9 @@
 
 sub recurse_categories {
     my ($cats,$depth,$category,$trails,$allitems,$parents) = @_;
+    my $shallower = $depth - 1;
     if (ref($cats->[$depth]{$category}) eq 'ARRAY') {
         for (my $k=0; $k<@{$cats->[$depth]{$category}}; $k++) {
-            my $shallower = $depth - 1;
             my $name = $cats->[$depth]{$category}[$k];
             my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower;
             my $trailstr = join(' -&gt; ',(@{$parents},$category));
@@ -4282,8 +4400,7 @@
             pop(@{$parents});
         }
     } else {
-        $depth --;
-        my $item = &escape($category).':'.&escape($parents->[-1]).':'.$depth;
+        my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower;
         my $trailstr = join(' -&gt; ',(@{$parents},$category));
         if ($allitems->{$item} eq '') {
             push(@{$trails},$trailstr);

--raeburn1210284812--