diff options
Diffstat (limited to 'template/en')
-rw-r--r-- | template/en/default/search/form.html.tmpl | 298 | ||||
-rw-r--r-- | template/en/default/search/search-advanced.html.tmpl | 40 |
2 files changed, 40 insertions, 298 deletions
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl index 2fd458148..f875f3541 100644 --- a/template/en/default/search/form.html.tmpl +++ b/template/en/default/search/form.html.tmpl @@ -23,302 +23,6 @@ [% PROCESS global/variables.none.tmpl %] - [%# Note: use Template comments and not JS ones here, to avoid bloating - what we actually send to the browser %] - -<script language="JavaScript" type="text/javascript"> <!-- - -var first_load = true; [%# is this the first time we load the page? %] -var last_sel = new Array(); [%# caches last selection %] - -var cpts = new Array(); -var vers = new Array(); -[% IF Param('usetargetmilestone') %] -var tms = new Array(); -[% END %] - -[%# Create three arrays of components, versions and target milestones, indexed - # numerically according to the product they refer to. #%] - -[% n = 0 %] -[% FOREACH p = product %] - cpts[[% n %]] = [ - [%- FOREACH item = p.components %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; - vers[[% n %]] = [ - [%- FOREACH item = p.versions -%]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; - [% IF Param('usetargetmilestone') %] - tms[[% n %]] = [ - [%- FOREACH item = p.milestones %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; - [% END %] - [% n = n+1 %] -[% END %] - -[%# 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 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 merging. - # - target should be the target select object. - # - 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, item; - - [%# If we have no versions/components/milestones %] - if (array.length < 1) { - target.options.length = 0; - return false; - } - - 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 rest of the selection with the results %] - for (i = 1 ; i < sel.length ; i++) { - item = merge_arrays(array[sel[i]], item, 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 < item.length; i++) { - target.options[i] = new Option(item[i], item[i]); - } - return true; -} - -[%# Returns elements in a that are not in b. - # NOT A REAL DIFF: does not check the reverse. - # - 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) { - for (var ib in b) { - if (a[ia] == b[ib]) { - found = true; - } - } - if (!found) { - newsel[newsel.length] = a[ia]; - } - found = false; - } - return newsel; -} - -[%# takes two arrays and sorts them by string, returning a new, sorted - # array. the merge removes dupes, too. - # - a, b: arrays to be merge. - # - b_is_select: if true, then b is actually an optionitem and as - # such we need to use item.value on it. %] -function merge_arrays(a, b, b_is_select) { - var pos_a = 0; - var pos_b = 0; - var ret = new Array(); - var bitem, aitem; - - [%# iterate through both arrays and add the larger item to the return - list. remove dupes, too. Use toLowerCase to provide - case-insensitivity. %] - while ((pos_a < a.length) && (pos_b < b.length)) { - if (b_is_select) { - bitem = b[pos_b].value; - } else { - bitem = b[pos_b]; - } - aitem = a[pos_a]; - - [%# smaller item in list a %] - if (aitem.toLowerCase() < bitem.toLowerCase()) { - ret[ret.length] = aitem; - pos_a++; - } else { - [%# smaller item in list b %] - if (aitem.toLowerCase() > bitem.toLowerCase()) { - ret[ret.length] = bitem; - pos_b++; - } else { - [%# list contents are equal, inc both counters. %] - ret[ret.length] = aitem; - pos_a++; - pos_b++; - } - } - } - - [%# catch leftovers here. these sections are ugly code-copying. %] - if (pos_a < a.length) { - for (; pos_a < a.length ; pos_a++) { - ret[ret.length] = a[pos_a]; - } - } - - if (pos_b < b.length) { - for (; pos_b < b.length; pos_b++) { - if (b_is_select) { - bitem = b[pos_b].value; - } else { - bitem = b[pos_b]; - } - ret[ret.length] = bitem; - } - } - return ret; -} - -[%# Returns an array of indexes or values from a select form control. - # - control: select control from which to find selections - # - findall: boolean, store all options when true or just the selected - # indexes - # - want_values: boolean; we store values when true and indexes when - # false %] -function get_selection(control, findall, want_values) { - 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] = want_values ? control.options[i].value : i; - } - } - return ret; -} - -[%# Selects items in control that have index defined in sel - # - control: SELECT control to be restored - # - selnames: array of indexes in select form control %] -function restoreSelection(control, selnames) { - [%# right. this sucks. but I see no way to avoid going through the - # list and comparing to the contents of the control. %] - for (var j=0; j < selnames.length; j++) { - for (var i=0; i < control.options.length; i++) { - if (control.options[i].value == selnames[j]) { - control.options[i].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 - # target_milestone select boxes. - # globals (3vil!): - # - cpts, vers, tms: array of arrays, indexed by product name. the - # subarrays contain a list of names to be fed to the respective - # selectboxes. For bugzilla, these are generated with perl code - # at page start. - # - first_load: boolean, specifying if it is the first time we load - # the query page. - # - last_sel: saves our last selection list so we know what has - # changed, and optimize for additions. %] -function selectProduct(f) { - [%# this is to avoid handling events that occur before the form - itself is ready, which could happen in buggy browsers. %] - if ((!f) || (!f.product)) { - return; - } - - [%# 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 = false; - return; - } - - [%# turn first_load off. this is tricky, since it seems to be - redundant with the above clause. It's not: if when we first load - the page there is _one_ element selected, it won't fall into that - clause, and first_load will remain 1. Then, if we unselect that - item, selectProduct will be called but the clause will be valid - (since selectedIndex == -1), and we will return - incorrectly - - without merge/sorting. %] - first_load = false; - - [%# - sel keeps the array of products we are 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(); - - [%# if nothing selected, pick all %] - var findall = f.product.selectedIndex == -1; - sel = get_selection(f.product, findall, false); - if (!findall) { - [%# save sel for the next invocation of selectProduct() %] - var tmp = sel; - - [%# 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; - } - [%# save original options selected %] - var saved_cpts = get_selection(f.component, false, true); - var saved_vers = get_selection(f.version, false, true); - [% IF Param('usetargetmilestone') %] - var saved_tms = get_selection(f.target_milestone, false, true); - [% END %] - - [%# do the actual fill/update, reselect originally selected options %] - updateSelect(cpts, sel, f.component, merging); - restoreSelection(f.component, saved_cpts); - updateSelect(vers, sel, f.version, merging); - restoreSelection(f.version, saved_vers); - [% IF Param('usetargetmilestone') %] - updateSelect(tms, sel, f.target_milestone, merging); - restoreSelection(f.target_milestone, saved_tms); - [% END %] -} - -// --> -</script> - [% query_variants = [ { value => "allwordssubstr", description => "contains all of the words/strings" }, { value => "anywordssubstr", description => "contains any of the words/strings" }, @@ -379,7 +83,7 @@ function selectProduct(f) { <td align="left"> <label for="product" accesskey="p"> <select name="product" multiple="multiple" size="5" id="product" - onchange="selectProduct(this.form);"> + onchange="doOnSelectProduct();"> [% FOREACH p = product %] <option value="[% p.name FILTER html %]" [% " selected" IF lsearch(default.product, p.name) != -1 %]> diff --git a/template/en/default/search/search-advanced.html.tmpl b/template/en/default/search/search-advanced.html.tmpl index bbed6c2d6..89938adbe 100644 --- a/template/en/default/search/search-advanced.html.tmpl +++ b/template/en/default/search/search-advanced.html.tmpl @@ -30,10 +30,48 @@ [% USE Bugzilla %] [% cgi = Bugzilla.cgi %] + +[% js_data = BLOCK %] +function doOnSelectProduct() { + var f = document.forms['queryform']; + milestone = (typeof(f.target_milestone) == "undefined" ? + null : f.target_milestone); + selectProduct(f.product, f.component, f.version, milestone); +} + +var first_load = true; [%# is this the first time we load the page? %] +var last_sel = new Array(); [%# caches last selection %] + +var cpts = new Array(); +var vers = new Array(); +[% IF Param('usetargetmilestone') %] +var tms = new Array(); +[% END %] + +[%# Create three arrays of components, versions and target milestones, indexed + # numerically according to the product they refer to. #%] + +[% n = 0 %] +[% FOREACH p = product %] + cpts[[% n %]] = [ + [%- FOREACH item = p.components %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; + vers[[% n %]] = [ + [%- FOREACH item = p.versions -%]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; + [% IF Param('usetargetmilestone') %] + tms[[% n %]] = [ + [%- FOREACH item = p.milestones %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; + [% END %] + [% n = n+1 %] +[% END %] + +[% END %] + [% PROCESS global/header.html.tmpl title = "Search for $terms.bugs" h1 = "" - onload = "selectProduct(document.forms['queryform']);initHelp();" + onload = "doOnSelectProduct(); initHelp();" + javascript = js_data + javascript_urls = [ "js/productform.js" ] style = "td.selected_tab { border-width: 2px 2px 0px; border-style: solid; |