summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kanat-Alexander <mkanat@bugzilla.org>2011-08-09 23:19:43 +0200
committerMax Kanat-Alexander <mkanat@bugzilla.org>2011-08-09 23:19:43 +0200
commit80c6d150b42ae5d9ba7464c5e20023cc90388259 (patch)
tree77df9794d444fbc861f53aa0240128a53f9d6467
parent93175c689f0349d879b3dfca5bd0236c19b73855 (diff)
downloadbugzilla-80c6d150b42ae5d9ba7464c5e20023cc90388259.tar.gz
bugzilla-80c6d150b42ae5d9ba7464c5e20023cc90388259.tar.xz
Bug 636416: Use the standard value-controller javascript to control the
drop-down fields on the Advanced Search page. r=glob, a=mkanat
-rw-r--r--js/field.js190
-rw-r--r--js/util.js28
-rwxr-xr-xquery.cgi66
-rw-r--r--template/en/default/search/field.html.tmpl79
-rw-r--r--template/en/default/search/form.html.tmpl104
-rw-r--r--template/en/default/search/search-advanced.html.tmpl12
-rw-r--r--template/en/default/search/search-create-series.html.tmpl2
-rw-r--r--template/en/default/search/search-report-graph.html.tmpl2
-rw-r--r--template/en/default/search/search-report-table.html.tmpl2
9 files changed, 310 insertions, 175 deletions
diff --git a/js/field.js b/js/field.js
index 1a3bc3efd..ea1769bd1 100644
--- a/js/field.js
+++ b/js/field.js
@@ -517,44 +517,143 @@ function handleVisControllerValueChange(e, args) {
}
}
-function showValueWhen(controlled_field_id, controlled_value_ids,
- controller_field_id, controller_value_id)
+/**
+ * This is a data structure representing the tree of controlled values.
+ * Let's call the "controller value" the "source" and the "controlled
+ * value" the "target". A target can have only one source, but a source
+ * can have an infinite number of targets.
+ *
+ * The data structure is a series of hash tables that go something
+ * like this:
+ *
+ * source_field -> target_field -> source_value_id -> target_value_ids
+ *
+ * We always know source_field when our event handler is called, since
+ * that's the field the event is being triggered on. We can then enumerate
+ * through every target field, check the status of each source field value,
+ * and act appropriately on each target value.
+ */
+var bz_value_controllers = {};
+// This keeps track of whether or not we've added an onchange handler
+// for the source field yet.
+var bz_value_controller_has_handler = {};
+function showValueWhen(target_field_id, target_value_ids,
+ source_field_id, source_value_id, empty_shows_all)
{
- var controller_field = document.getElementById(controller_field_id);
- // Note that we don't get an object for the controlled field here,
- // because it might not yet exist in the DOM. We just pass along its id.
- YAHOO.util.Event.addListener(controller_field, 'change',
- handleValControllerChange, [controlled_field_id, controlled_value_ids,
- controller_field, controller_value_id]);
+ if (!bz_value_controllers[source_field_id]) {
+ bz_value_controllers[source_field_id] = {};
+ }
+ if (!bz_value_controllers[source_field_id][target_field_id]) {
+ bz_value_controllers[source_field_id][target_field_id] = {};
+ }
+ var source_values = bz_value_controllers[source_field_id][target_field_id];
+ source_values[source_value_id] = target_value_ids;
+
+ if (!bz_value_controller_has_handler[source_field_id]) {
+ var source_field = document.getElementById(source_field_id);
+ YAHOO.util.Event.addListener(source_field, 'change',
+ handleValControllerChange, [source_field, empty_shows_all]);
+ bz_value_controller_has_handler[source_field_id] = true;
+ }
}
function handleValControllerChange(e, args) {
- var controlled_field = document.getElementById(args[0]);
- var controlled_value_ids = args[1];
- var controller_field = args[2];
- var controller_value_id = args[3];
-
- var controller_item = document.getElementById(
- _value_id(controller_field.id, controller_value_id));
-
- for (var i = 0; i < controlled_value_ids.length; i++) {
- var item = getPossiblyHiddenOption(controlled_field,
- controlled_value_ids[i]);
- if (item.disabled && controller_item && controller_item.selected) {
- item = showOptionInIE(item, controlled_field);
- YAHOO.util.Dom.removeClass(item, 'bz_hidden_option');
- item.disabled = false;
+ var source = args[0];
+ var empty_shows_all = args[1];
+
+ for (var target_field_id in bz_value_controllers[source.id]) {
+ var target = document.getElementById(target_field_id);
+ if (!target) continue;
+ _update_displayed_values(source, target, empty_shows_all);
+ }
+}
+
+/* See the docs for bz_option_duplicate count lower down for an explanation
+ * of this data structure.
+ */
+var bz_option_hide_count = {};
+
+function _update_displayed_values(source, target, empty_shows_all) {
+ var show_all = (empty_shows_all && source.selectedIndex == -1);
+
+ bz_option_hide_count[target.id] = {};
+
+ var source_values = bz_value_controllers[source.id][target.id];
+ for (source_value_id in source_values) {
+ var source_option = getPossiblyHiddenOption(source, source_value_id);
+ var target_values = source_values[source_value_id];
+ for (var i = 0; i < target_values.length; i++) {
+ var target_value_id = target_values[i];
+ _handle_source_target(source_option, target, target_value_id,
+ show_all);
}
- else if (!item.disabled) {
- YAHOO.util.Dom.addClass(item, 'bz_hidden_option');
- if (item.selected) {
- item.selected = false;
- bz_fireEvent(controlled_field, 'change');
- }
- item.disabled = true;
- hideOptionInIE(item, controlled_field);
+ }
+
+ // We may have updated which elements are selected or not selected
+ // in the target field, and it may have handlers associated with
+ // that, so we need to fire the change event on the target.
+ bz_fireEvent(target, 'change');
+}
+
+function _handle_source_target(source_option, target, target_value_id,
+ show_all)
+{
+ var target_option = getPossiblyHiddenOption(target, target_value_id);
+
+ // We always call either _show_option or _hide_option on every single
+ // target value. Although this is not theoretically the most efficient
+ // thing we can do, it handles all possible edge cases, and there are
+ // a lot of those, particularly when this code is being used on the
+ // search form.
+ if (source_option.selected || (show_all && !source_option.disabled)) {
+ _show_option(target_option, target);
+ }
+ else {
+ _hide_option(target_option, target);
+ }
+}
+
+/* When an option has duplicates (see the docs for bz_option_duplicates
+ * lower down in this file), we only want to hide it if *all* the duplicates
+ * would be hidden. So we keep a counter of how many duplicates each option
+ * has. Then, when we run through a "change" call for a source field,
+ * we count how many times each value gets hidden, and only actually
+ * hide it if the counter hits a number higher than the duplicate count.
+ */
+var bz_option_duplicate_count = {};
+
+function _show_option(option, field) {
+ if (!option.disabled) return;
+ option = showOptionInIE(option, field);
+ YAHOO.util.Dom.removeClass(option, 'bz_hidden_option');
+ option.disabled = false;
+}
+
+function _hide_option(option, field) {
+ if (option.disabled) return;
+
+ var value_id = option.bz_value_id;
+
+ if (field.id in bz_option_duplicate_count
+ && value_id in bz_option_duplicate_count[field.id])
+ {
+ if (!bz_option_hide_count[field.id][value_id]) {
+ bz_option_hide_count[field.id][value_id] = 0;
}
+ bz_option_hide_count[field.id][value_id]++;
+ var current = bz_option_hide_count[field.id][value_id];
+ var dups = bz_option_duplicate_count[field.id][value_id];
+ // We check <= because the value in bz_option_duplicate_count is
+ // 1 less than the total number of duplicates (since the shown
+ // option is also a "duplicate" but not counted in
+ // bz_option_duplicate_count).
+ if (current <= dups) return;
}
+
+ YAHOO.util.Dom.addClass(option, 'bz_hidden_option');
+ option.selected = false;
+ option.disabled = true;
+ hideOptionInIE(option, field);
}
// A convenience function to generate the "id" tag of an <option>
@@ -571,7 +670,7 @@ function _value_id(field_name, id) {
* on <option> tags. However, you *can* insert a Comment Node as a
* child of a <select> tag. So we just insert a Comment where the <option>
* used to be. */
-var ie_hidden_options = new Array();
+var ie_hidden_options = {};
function hideOptionInIE(anOption, aSelect) {
if (browserCanHideOptions(aSelect)) return;
@@ -591,7 +690,7 @@ function hideOptionInIE(anOption, aSelect) {
// Store the comment node for quick access for getPossiblyHiddenOption
if (!ie_hidden_options[aSelect.id]) {
- ie_hidden_options[aSelect.id] = new Array();
+ ie_hidden_options[aSelect.id] = {};
}
ie_hidden_options[aSelect.id][anOption.id] = commentNode;
}
@@ -620,6 +719,7 @@ function showOptionInIE(aNode, aSelect) {
function initHidingOptionsForIE(select_name) {
var aSelect = document.getElementById(select_name);
if (browserCanHideOptions(aSelect)) return;
+ if (!aSelect) return;
for (var i = 0; ;i++) {
var item = aSelect.options[i];
@@ -631,7 +731,27 @@ function initHidingOptionsForIE(select_name) {
}
}
+/* Certain fields, like the Component field, have duplicate values in
+ * them (the same name, but different ids). We don't display these
+ * duplicate values in the UI, but the option hiding/showing code still
+ * uses the ids of these unshown duplicates. So, whenever we get the
+ * id of an unshown duplicate in getPossiblyHiddenOption, we have to
+ * return the actually-used <option> instead.
+ *
+ * The structure of the data looks like:
+ *
+ * field_name -> unshown_value_id -> shown_value_id_it_is_a_duplicate_of
+ */
+var bz_option_duplicates = {};
+
function getPossiblyHiddenOption(aSelect, optionId) {
+
+ if (bz_option_duplicates[aSelect.id]
+ && bz_option_duplicates[aSelect.id][optionId])
+ {
+ optionId = bz_option_duplicates[aSelect.id][optionId];
+ }
+
// Works always for <option> tags, and works for commentNodes
// in IE (but not in Webkit).
var id = _value_id(aSelect.id, optionId);
@@ -643,6 +763,10 @@ function getPossiblyHiddenOption(aSelect, optionId) {
val = ie_hidden_options[aSelect.id][id];
}
+ // We add this property for our own convenience, it's used in
+ // other places.
+ val.bz_value_id = optionId;
+
return val;
}
diff --git a/js/util.js b/js/util.js
index 6dcabbbc9..56649ac66 100644
--- a/js/util.js
+++ b/js/util.js
@@ -220,6 +220,34 @@ function bz_valueSelected(aSelect, aValue) {
}
/**
+ * Returns all Option elements that are selected in a <select>,
+ * as an array. Returns an empty array if nothing is selected.
+ *
+ * @param aSelect The select you want the selected values of.
+ */
+function bz_selectedOptions(aSelect) {
+ // HTML 5
+ if (aSelect.selectedOptions) {
+ return aSelect.selectedOptions;
+ }
+
+ var start_at = aSelect.selectedIndex;
+ if (start_at == -1) return [];
+ var first_selected = aSelect.options[start_at];
+ if (!aSelect.multiple) return first_selected;
+ // selectedIndex is specified as being the "first selected item",
+ // so we can start from there.
+ var selected = [first_selected];
+ var options_length = aSelect.options.length;
+ // We start after first_selected
+ for (var i = start_at + 1; i < options_length; i++) {
+ var this_option = aSelect.options[i];
+ if (this_option.selected) selected.push(this_option);
+ }
+ return selected;
+}
+
+/**
* Tells you where (what index) in a <select> a particular option is.
* Returns -1 if the value is not in the <select>
*
diff --git a/query.cgi b/query.cgi
index 93de62b63..0182f66eb 100755
--- a/query.cgi
+++ b/query.cgi
@@ -40,6 +40,46 @@ use Bugzilla::Keyword;
use Bugzilla::Field;
use Bugzilla::Install::Util qw(vers_cmp);
+###############
+# Subroutines #
+###############
+
+sub get_product_values {
+ my ($products, $field, $vars) = @_;
+ my @all_values = map { @{ $_->$field } } @$products;
+
+ my (@unique, %duplicates, %duplicate_count, %seen);
+ foreach my $value (@all_values) {
+ my $lc_name = lc($value->name);
+ if ($seen{$lc_name}) {
+ $duplicate_count{$seen{$lc_name}->id}++;
+ $duplicates{$value->id} = $seen{$lc_name};
+ next;
+ }
+ push(@unique, $value);
+ $seen{$lc_name} = $value;
+ }
+
+ if ($field eq 'version') {
+ @unique = sort { vers_cmp(lc($a->name), lc($b->name)) } @unique;
+ }
+ else {
+ @unique = sort { lc($a->name) cmp lc($b->name) } @unique;
+ }
+
+ $field =~ s/s$//;
+ $field = 'target_milestone' if $field eq 'milestone';
+ $vars->{duplicates}->{$field} = \%duplicates;
+ $vars->{duplicate_count}->{$field} = \%duplicate_count;
+ # "component" is a reserved word in Template Toolkit.
+ $field = 'component_' if $field eq 'component';
+ $vars->{$field} = \@unique;
+}
+
+###############
+# Main Script #
+###############
+
my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
@@ -133,38 +173,18 @@ if (!PrefillForm($buffer)) {
my @selectable_products = sort {lc($a->name) cmp lc($b->name)}
@{$user->get_selectable_products};
Bugzilla::Product::preload(\@selectable_products);
+$vars->{'product'} = \@selectable_products;
# Create the component, version and milestone lists.
-my %components;
-my %versions;
-my %milestones;
-
-foreach my $product (@selectable_products) {
- $components{$_->name} = 1 foreach (@{$product->components});
- $versions{$_->name} = 1 foreach (@{$product->versions});
- $milestones{$_->name} = 1 foreach (@{$product->milestones});
+foreach my $field (qw(components versions milestones)) {
+ get_product_values(\@selectable_products, $field, $vars);
}
-my @components = sort(keys %components);
-my @versions = sort { vers_cmp (lc($a), lc($b)) } keys %versions;
-my @milestones = sort(keys %milestones);
-
-$vars->{'product'} = \@selectable_products;
-
# Create data structures representing each classification
if (Bugzilla->params->{'useclassification'}) {
$vars->{'classification'} = $user->get_selectable_classifications;
}
-# We use 'component_' because 'component' is a Template Toolkit reserved word.
-$vars->{'component_'} = \@components;
-
-$vars->{'version'} = \@versions;
-
-if (Bugzilla->params->{'usetargetmilestone'}) {
- $vars->{'target_milestone'} = \@milestones;
-}
-
my @chfields;
push @chfields, "[Bug creation]";
diff --git a/template/en/default/search/field.html.tmpl b/template/en/default/search/field.html.tmpl
index defc94cc3..c237ac16c 100644
--- a/template/en/default/search/field.html.tmpl
+++ b/template/en/default/search/field.html.tmpl
@@ -121,22 +121,71 @@
[% legal_values = ${"component_"} %]
[% END %]
[% FOREACH current_value = legal_values %]
- [% IF current_value.id %]
- [%# current_value is a hash instead of a value which
- only applies for Resolution really, everywhere else current_value
- is just the value %]
- [% v = current_value.name OR '---' -%]
- <option value="[% v FILTER html %]"
- [% ' selected="selected"' IF value.contains( v ) %]>
- [% display_value(field.name, current_value.name) FILTER html %]
- </option>
- [% ELSE %]
- <option value="[% current_value OR '---' FILTER html %]"
- [% ' selected="selected"' IF value.contains( current_value ) %]>
- [% display_value(field.name, current_value) FILTER html %]
- </option>
- [% END %]
+ [% SET v = current_value.name OR '---' -%]
+ [% SET display = display_value(field.name, current_value.name) %]
+ <option [% IF v != display %]value="[% v FILTER html %]"[% END ~%]
+ id="v[% current_value.id FILTER html %]_[% field.name FILTER html %]"
+ [% ' selected="selected"' IF value.contains( v ) %]>
+ [%~ display FILTER html ~%]
+ </option>
[% END %]
</select>
</div>
+
+ [% IF value_controllers.${field.name}.defined %]
+ <script type="text/javascript"><!--
+ [%+ FILTER collapse %]
+ [% FOREACH accessor = value_controllers.${field.name}.keys %]
+ [% PROCESS controller_js %]
+ [% END %]
+ [%~ END ~%]
+ // --></script>
+ [% END %]
+ [% IF duplicates.${field.name}.keys.size %]
+ [% SET field_dups = duplicates.${field.name} %]
+ [% SET dup_counts = duplicate_count.${field.name} %]
+ <script type="text/javascript">
+ [%+ FILTER collapse %]
+ bz_option_duplicates['[% field.name FILTER js %]'] = {
+ [% FOREACH dup = field_dups.keys %]
+ [% dup FILTER js %]:[% field_dups.$dup.id FILTER js %]
+ [%~ ',' UNLESS loop.last %]
+ [% END ~%]
+ };
+ bz_option_duplicate_count['[% field.name FILTER js %]'] = {
+ [% FOREACH dup_target = dup_counts.keys %]
+ [% dup_target FILTER js %]:[% dup_counts.$dup_target %]
+ [%~ ',' UNLESS loop.last %]
+ [% END %]
+ };
+ [% END %]
+ </script>
+ [% END %]
+
+ [% END %]
+[%# END OF SWITCH %]
+
+[% BLOCK controller_js %]
+ [%# If there are selected values already, we need to fire the
+ # "change" event once the page has loaded, so we can set all
+ # the values in all the other <select>s properly.
+ #%]
+ YAHOO.util.Event.onDOMReady(function() {
+ var field = document.getElementById('[% field.name FILTER js %]');
+ if (field.selectedIndex != -1) bz_fireEvent(field, 'change');
+ });
+
+ [% SET sub_field = value_controllers.${field.name}.$accessor %]
+ [% FOREACH legal_value = legal_values %]
+ [% SET controlled_ids = [] %]
+ [% FOREACH sub_value = legal_value.$accessor %]
+ [% controlled_ids.push(sub_value.id) %]
+ [% END %]
+ [% NEXT IF !controlled_ids.size %]
+ showValueWhen('[% sub_field.name FILTER js %]',
+ [[% controlled_ids.join(',') FILTER js %]],
+ '[% field.name FILTER js %]',
+ [% legal_value.id FILTER js %],
+ true);
[% END %]
+[% END %]
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
index 41e116518..fb9454ff6 100644
--- a/template/en/default/search/form.html.tmpl
+++ b/template/en/default/search/form.html.tmpl
@@ -25,85 +25,6 @@
<script type="text/javascript">
-var first_load = true; [%# is this the first time we load the page? %]
-var last_sel = new Array(); [%# caches last selection %]
-
-[% IF Param('useclassification') %]
-var useclassification = true;
-var prods = new Array();
-[% ELSE %]
-var useclassification = false;
-[% END %]
-var cpts = new Array();
-var vers = new Array();
-[% IF Param('usetargetmilestone') %]
-var tms = new Array();
-[% END %]
-
-[%# Create an array of products, indexed by the classification #%]
-
-[% nclass = 0 %]
-[% FOREACH c = classification %]
- prods[[% nclass FILTER js %]] = [
- [% sep = '' %]
- [%- FOREACH item = user.get_selectable_products(c.id) -%]
- [%- IF item.components.size -%]
- [%- sep FILTER js %]'[% item.name FILTER js %]'
- [%- sep = ',' -%]
- [%- END -%]
- [%- END -%] ];
- [% nclass = nclass+1 %]
-[% END %]
-
-[%# Create three arrays of components, versions and target milestones, indexed
- # numerically according to the product they refer to. #%]
-
-[% n = 0 %]
-[% FOREACH p = product %]
- [% NEXT IF NOT p.components.size %]
- [% IF Param('useclassification') %]
- prods['[% p.name FILTER js %]'] = [% n %]
- [% END %]
- cpts[[% n %]] = [
- [%- FOREACH item = p.components %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
- vers[[% n %]] = [
- [%- FOREACH item = p.versions -%]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
- [% IF Param('usetargetmilestone') %]
- tms[[% n %]] = [
- [%- FOREACH item = p.milestones %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
- [% END %]
- [% n = n+1 %]
-[% END %]
-
-/*
- * doOnSelectProduct determines which selection should get updated
- *
- * - selectmode = 0 - init
- * selectmode = 1 - classification selected
- * selectmode = 2 - product selected
- *
- * globals:
- * queryform - string holding the name of the selection form
- */
-function doOnSelectProduct(selectmode) {
- var f = document.forms[queryform];
- var milestone = (typeof(f.target_milestone) == "undefined" ?
- null : f.target_milestone);
- if (selectmode == 0) {
- // If there is no classification selected, give us a chance to fill
- // the select fields with values from the possibly selected product.
- if (useclassification && f.classification.selectedIndex > -1) {
- selectClassification(f.classification, f.product, f.component, f.version, milestone);
- } else {
- selectProduct(f.product, f.component, f.version, milestone, null);
- }
- } else if (selectmode == 1) {
- selectClassification(f.classification, f.product, f.component, f.version, milestone);
- } else {
- selectProduct(f.product, f.component, f.version, milestone, null);
- }
-}
-
// Hide the Advanced Fields by default, unless the user has a cookie
// that specifies otherwise.
// &#9656; and &#9662; are both utf8 escaped characters for right
@@ -143,7 +64,7 @@ TUI_hide_default('information_query');
accesskey = "s"
%]
<script type="text/javascript"> <!--
- document.forms[queryform].short_desc.focus();
+ document.getElementById('short_desc').focus();
// -->
</script>
@@ -154,23 +75,26 @@ TUI_hide_default('information_query');
</div>
[%# *** Classification Product Component *** %]
-
+
+[% value_controllers = {
+ 'classification' => { 'products' => bug_fields.product },
+ 'product' => { 'components' => bug_fields.component,
+ 'versions' => bug_fields.version,
+ 'milestones' => bug_fields.target_milestone },
+} %]
+
[% Hook.process('before_selects_top') %]
[% IF Param('useclassification') %]
- [% fake_classfication = { name => bug_fields.classification.name,
- type => constants.FIELD_TYPE_SINGLE_SELECT } %]
- [% INCLUDE "search/field.html.tmpl"
- field => fake_classfication
- accesskey => "c"
- onchange => "doOnSelectProduct(1);"
- value => default.classification
- %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.classification
+ accesskey => "c"
+ value => default.classification
+ %]
[% END %]
[% INCLUDE "search/field.html.tmpl"
field => bug_fields.product
accesskey => "p"
- onchange => "doOnSelectProduct(2);"
value => default.product
%]
[% INCLUDE "search/field.html.tmpl"
diff --git a/template/en/default/search/search-advanced.html.tmpl b/template/en/default/search/search-advanced.html.tmpl
index ef7fa769a..4f6f37bf2 100644
--- a/template/en/default/search/search-advanced.html.tmpl
+++ b/template/en/default/search/search-advanced.html.tmpl
@@ -30,21 +30,12 @@
[% cgi = Bugzilla.cgi %]
-[% js_data = BLOCK %]
-var queryform = "queryform"
-[% END %]
-
[% PROCESS global/header.html.tmpl
title = "Search for $terms.bugs"
- onload = "doOnSelectProduct(0);"
- javascript = js_data
yui = [ 'autocomplete', 'calendar' ]
- javascript_urls = [ "js/productform.js", "js/util.js", "js/TUI.js", "js/field.js"]
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js"]
style_urls = [ "skins/standard/search_form.css" ]
doc_section = "query.html"
- style = "dl.bug_changes dt {
- margin-top: 15px;
- }"
%]
[% WRAPPER search/tabs.html.tmpl %]
@@ -63,7 +54,6 @@ var queryform = "queryform"
</form>
-
[% END %]
[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/search/search-create-series.html.tmpl b/template/en/default/search/search-create-series.html.tmpl
index 3ca68ac49..6863eba10 100644
--- a/template/en/default/search/search-create-series.html.tmpl
+++ b/template/en/default/search/search-create-series.html.tmpl
@@ -35,7 +35,7 @@
onload = "doOnSelectProduct(0);"
yui = [ 'autocomplete', 'calendar' ]
javascript = js_data
- javascript_urls = [ "js/util.js", "js/productform.js", "js/TUI.js", "js/field.js" ]
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js" ]
style_urls = [ "skins/standard/search_form.css" ]
doc_section = "reporting.html#charts-new-series"
%]
diff --git a/template/en/default/search/search-report-graph.html.tmpl b/template/en/default/search/search-report-graph.html.tmpl
index 3c894cf73..362c910fa 100644
--- a/template/en/default/search/search-report-graph.html.tmpl
+++ b/template/en/default/search/search-report-graph.html.tmpl
@@ -34,7 +34,7 @@ var queryform = "reportform"
onload = "doOnSelectProduct(0); chartTypeChanged()"
yui = [ 'autocomplete', 'calendar' ]
javascript = js_data
- javascript_urls = [ "js/util.js", "js/productform.js", "js/TUI.js", "js/field.js" ]
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js" ]
style_urls = [ "skins/standard/search_form.css" ]
doc_section = "reporting.html#reports"
%]
diff --git a/template/en/default/search/search-report-table.html.tmpl b/template/en/default/search/search-report-table.html.tmpl
index 7e087e7fe..c59743965 100644
--- a/template/en/default/search/search-report-table.html.tmpl
+++ b/template/en/default/search/search-report-table.html.tmpl
@@ -34,7 +34,7 @@ var queryform = "reportform"
onload = "doOnSelectProduct(0)"
yui = [ 'autocomplete', 'calendar' ]
javascript = js_data
- javascript_urls = [ "js/util.js", "js/productform.js", "js/TUI.js", "js/field.js" ]
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js" ]
style_urls = [ "skins/standard/search_form.css" ]
doc_section = "reporting.html#reports"
%]