]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 122154 - change arrays to numeric, and clean up query.atml js
authorbbaetz%student.usyd.edu.au <>
Wed, 30 Jan 2002 21:43:11 +0000 (21:43 +0000)
committerbbaetz%student.usyd.edu.au <>
Wed, 30 Jan 2002 21:43:11 +0000 (21:43 +0000)
patch by kiko@async.com.br, r=caillon,bbaetz

template/default/query/query.atml

index c98d7bdc6076ffa0204d2dadc5ac3bc1f2124dbe..d4f8dbd171e8a13259f6465c1df5ae5ef3d8cd40 100644 (file)
 
 [%# Note: use Template comments and not JS ones here, to avoid bloating
     what we actually send to the browser %]
+
+[% IF Param('usetargetmilestone') %]
+[%   tms = 1 %]
+[% ELSE %]
+[%   tms = 0 %]
+[% END %]
     
 <script language="JavaScript" type="text/javascript"> <!--
 
-var first_load = 1;            [%# is this the first time we load the page? %]
-var last_sel = [];                                [%# caches last selection %]
-var usetms = [% IF Param('usetargetmilestone') %]true[% ELSE %]false[% END %]; 
-                                           [%# do we have target milestone? %]
+var first_load = true;         [%# is this the first time we load the page? %]
+var last_sel = new Array();    [%# caches last selection %]
+var usetms = [% IF tms %]true[% ELSE %]false[% END %];
+                               [%# do we have target milestone? %]
+
+var cpts = new Array();
+var vers = new Array();
+var tms = new Array();
 
-var cpts = new Object();
-var vers = new Object();
-var tms = new Object();
+[%# Create three arrays of components, versions and target milestones, indexed 
+  # numerically according to the product they refer to. #%]
 
+[% n = 0 %]
 [% FOREACH p = product %]
-  cpts['[% p FILTER js %]'] = [ 
-    [%- FOREACH item = componentsbyproduct.$p %]'[% item FILTER js %]', [%- END -%]]
-  vers['[% p FILTER js %]'] = [ 
-    [%- FOREACH item = versionsbyproduct.$p -%]'[%  item FILTER js %]', [%- END -%]]
-   tms['[% p FILTER js %]'] = [ 
-    [%- FOREACH item = milestonesbyproduct.$p %]'[% item FILTER js %]', [%- END -%]]
+  cpts[[% n %]] = [ 
+    [%- FOREACH item = componentsbyproduct.$p %]'[% item FILTER js %]', [%- END -%]];
+  vers[[% n %]] = [ 
+    [%- FOREACH item = versionsbyproduct.$p -%]'[%  item FILTER js %]', [%- END -%]];
+  [% IF tms %]
+  tms[[% n %]]  = [ 
+     [%- FOREACH item = milestonesbyproduct.$p %]'[% item FILTER js %]', [%- END -%]];
+  [% END %]
+  [% n = n+1 %]
 [% END %]
 
-[%# Adds to the target select object all elements in array that
+[%# updateSelect(array, sel, target, merging)
+  #
+  # Adds to the target select object all elements in array that
   # correspond to the elements selected in source.
-  # - array should be a array of arrays, indexed by product name. the
-  #   array should contain the elements that correspont to that
-  #   product. Example:
-  #     var array = Array();
-  #     array['ProductOne'] = [ 'ComponentA', 'ComponentB' ];
-  #     updateSelect(array, source, target);
+  # - array should be a array of arrays, indexed by number. the
+  #   array should contain the elements that correspond to that
+  #   product. 
   # - sel is a list of selected items, either whole or a diff
-  #   depending on sel_is_diff.
-  # - sel_is_diff determines if we are sending in just a diff or the
-  #   whole selection. a diff is used to optimize adding selections.
+  #   depending on merging.
   # - target should be the target select object.
-  # - single specifies if we selected a single item. if we did, no
-  #   need to merge. %]
-function updateSelect(array, sel, target, sel_is_diff, single) {
+  # - merging (boolean) determines if we are mergine in a diff or
+  #   substituting the whole selection. a diff is used to optimize adding
+  #   selections.
+  #
+  # Example (compsel is a select form control)
+  #
+  #     var components = Array();
+  #     components[1] = [ 'ComponentA', 'ComponentB' ];
+  #     components[2] = [ 'ComponentC', 'ComponentD' ];
+  #     source = [ 2 ];
+  #     updateSelect(components, source, compsel, 0, 0);
+  #
+  # would clear compsel and add 'ComponentC' and 'ComponentD' to it.
+  #
+  %]
+
+function updateSelect(array, sel, target, merging) {
         
-    var i, comp;
+    var i, item;
 
-    [%# if single, even if it's a diff (happens when you have nothing
-        selected and select one item alone), skip this. %]
-    if (!single) {
-        [%# array merging/sorting in the case of multiple selections %]
-        if (sel_is_diff) {        
-            [%# merge in the current options with the first selection %]
-            comp = merge_arrays(array[sel[0]], target.options, 1);
+    [%# If we have no versions/components/milestones %]
+    if (array.length < 1) {
+        target.options.length = 0;
+        return false;
+    }
 
-            [%# merge the rest of the selection with the results %]
-            for (i = 1 ; i < sel.length ; i++) {
-                comp = merge_arrays(array[sel[i]], comp, 0);
-            }
-        } else {
-            [%# here we micro-optimize for two arrays to avoid merging with a
-                null array %]
-            comp = merge_arrays(array[sel[0]],array[sel[1]], 0);
+    if (merging) {
+        [%# array merging/sorting in the case of multiple selections %]
+        [%# merge in the current options with the first selection %]
+        item = merge_arrays(array[sel[0]], target.options, 1);
 
-            [%# merge the arrays. not very good for multiple selections. %]
-            for (i = 2; i < sel.length; i++) {
-                comp = merge_arrays(comp, array[sel[i]], 0);
-            }
+        [%# merge the rest of the selection with the results %]
+        for (i = 1 ; i < sel.length ; i++) {
+            item = merge_arrays(array[sel[i]], item, 0);
         }
-    } else {
-        [%# single item in selection, just get me the list %]
-        comp = array[sel[0]];
+    } else if ( sel.length > 1 ) {
+        [%# here we micro-optimize for two arrays to avoid merging with a
+            null array %]
+        item = merge_arrays(array[sel[0]],array[sel[1]], 0);
+
+        [%# merge the arrays. not very good for multiple selections. %]
+        for (i = 2; i < sel.length; i++) {
+            item = merge_arrays(item, array[sel[i]], 0);
+        }
+    } else { [%# single item in selection, just get me the list %]
+        item = array[sel[0]];
     }
 
     [%# clear select %]
     target.options.length = 0;
 
     [%# load elements of list into select %]
-    for (i = 0; i < comp.length; i++) {
-        target.options[i] = new Option(comp[i], comp[i]);
+    for (i = 0; i < item.length; i++) {
+        target.options[i] = new Option(item[i], item[i]);
     }
+    return true;
 }
 
 [%# Returns elements in a that are not in b. 
@@ -108,19 +134,19 @@ function updateSelect(array, sel, target, sel_is_diff, single) {
   #    - a,b: arrays of values to be compare. %]
 function fake_diff_array(a, b) {
     var newsel = new Array();
+    var found = false;
 
     [%# do a boring array diff to see who's new %]
     for (var ia in a) {
-        var found = 0;
         for (var ib in b) {
             if (a[ia] == b[ib]) {
-                found = 1;
+                found = true;
             }
         }
         if (!found) {
             newsel[newsel.length] = a[ia];
         }
-        found = 0;
+        found = false;
     }
     return newsel;
 }
@@ -185,6 +211,34 @@ function merge_arrays(a, b, b_is_select) {
     return ret;
 }
 
+[%# Returns an array of indexes.
+  #    - control: select control from which to find selections
+  #    - findall: boolean, dumping all options if all or just the selected 
+  #      indexes. %]
+function getSelection(control, findall) {
+    var ret = new Array();
+
+    if ((!findall) && (control.selectedIndex == -1)) {
+        return ret;
+    }
+
+    for (var i=0; i<control.length; i++) {
+        if (findall || control.options[i].selected) {
+            ret[ret.length] = i;
+        }
+    }
+    return ret;
+}
+
+[%# Selects items in control that have index defined in sel
+  #    - control: SELECT control to be restored
+  #    - sel: array of indexes in select form control %]
+function restoreSelection(control, sel) {
+    for (var s in sel) {
+        control.options[sel[s]].selected = true;
+    }
+}
+
 [%# selectProduct reads the selection from f.product and updates
   # f.version, component and target_milestone accordingly.
   #     - f: a form containing product, component, varsion and
@@ -202,7 +256,7 @@ function merge_arrays(a, b, b_is_select) {
   #       changed, and optimize for additions. %]
 function selectProduct(f) {
     [%# this is to avoid handling events that occur before the form
-       itself is ready, which happens in buggy browsers. %]
+        itself is ready, which could happen in buggy browsers. %]
     if ((!f) || (!f.product)) {
         return;
     }
@@ -210,7 +264,7 @@ function selectProduct(f) {
     [%# if this is the first load and nothing is selected, no need to
        merge and sort all components; perl gives it to us sorted. %]
     if ((first_load) && (f.product.selectedIndex == -1)) {
-        first_load = 0;
+        first_load = false;
         return;
     }
     
@@ -221,49 +275,40 @@ function selectProduct(f) {
         item, selectProduct will be called but the clause will be valid
         (since selectedIndex == -1), and we will return - incorrectly -
         without merge/sorting. %]
-    first_load = 0;
+    first_load = false;
 
     [%# - sel keeps the array of products we are selected. 
-        - is_diff says if it is a full list or just a list of products that
-          were added to the current selection.
-        - single indicates if a single item was selected %]
+        - merging says if it is a full list or just a list of products that
+          were added to the current selection. %]
+    var merging = false;
     var sel = Array();
-    var is_diff = 0;
-    var single;
 
     [%# if nothing selected, pick all %]
     if (f.product.selectedIndex == -1) {
-        for (var i = 0 ; i < f.product.length ; i++) {
-            sel[sel.length] = f.product.options[i].value;
-        }
-        single = 0;
+        sel = getSelection(f.product, true);
     } else {
-        for (i = 0 ; i < f.product.length ; i++) {
-            if (f.product.options[i].selected) {
-                sel[sel.length] = f.product.options[i].value;
-            }
-        }
+        sel = getSelection(f.product, false);
 
-        single = (sel.length == 1);
-
-        [%# save last_sel before we kill it %]
-        var tmp = last_sel;
-        last_sel = sel;
+        [%# save sel for the next invocation of selectProduct() %]
+        var tmp = sel;
     
-        [%# this is an optimization: if we have added components, no need
-           to remerge them; just merge the new ones with the existing
-           options. %]
-        if ((tmp) && (tmp.length < sel.length)) {
-            sel = fake_diff_array(sel, tmp);
-            is_diff = 1;
+        [%# this is an optimization: if we have just added products to an
+            existing selection, no need to clear the form controls and add 
+            everybody again; just merge the new ones with the existing 
+            options. %]
+        if ((last_sel.length > 0) && (last_sel.length < sel.length)) {
+            sel = fake_diff_array(sel, last_sel);
+            merging = true;
         }
+
+        last_sel = tmp;
     }
 
     [%# do the actual fill/update %]
-    updateSelect(cpts, sel, f.component, is_diff, single);
-    updateSelect(vers, sel, f.version, is_diff, single);
+    updateSelect(cpts, sel, f.component, merging);
+    updateSelect(vers, sel, f.version, merging);
     if (usetms) {
-        updateSelect(tms, sel, f.target_milestone, is_diff, single);
+        updateSelect(tms, sel, f.target_milestone, merging);
     }
 }