aboutsummaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorByron Jones <bjones@mozilla.com>2012-11-22 16:23:53 +0800
committerByron Jones <bjones@mozilla.com>2012-11-22 16:23:53 +0800
commitda12cec61f8c7e667b00fc5fc39c827d3593f021 (patch)
treea7993cf0d3ad5c534dd7604b827c8ce8267fcf38 /js
parentBug 640756 - Make the documentation clearer that attachments created with Bug... (diff)
downloadbugzilla-da12cec61f8c7e667b00fc5fc39c827d3593f021.tar.gz
bugzilla-da12cec61f8c7e667b00fc5fc39c827d3593f021.tar.bz2
bugzilla-da12cec61f8c7e667b00fc5fc39c827d3593f021.zip
Bug 780820: Allows for multiple custom search criteria to match one field
r=dkl,a=LpSolit
Diffstat (limited to 'js')
-rw-r--r--js/custom-search.js174
1 files changed, 157 insertions, 17 deletions
diff --git a/js/custom-search.js b/js/custom-search.js
index 89a788073..61284c50d 100644
--- a/js/custom-search.js
+++ b/js/custom-search.js
@@ -28,7 +28,7 @@ function custom_search_new_row() {
var row = document.getElementById('custom_search_last_row');
var clone = row.cloneNode(true);
- _cs_fix_ids(clone);
+ _cs_fix_row_ids(clone);
// We only want one copy of the buttons, in the new row. So the old
// ones get deleted.
@@ -43,13 +43,28 @@ function custom_search_new_row() {
// Always make sure there's only one row with this id.
row.id = null;
row.parentNode.appendChild(clone);
+ cs_reconfigure(row);
fix_query_string(row);
return clone;
}
+var _cs_source_any_all;
function custom_search_open_paren() {
var row = document.getElementById('custom_search_last_row');
+ // create a copy of j_top and use that as the source, so we can modify
+ // j_top if required
+ if (!_cs_source_any_all) {
+ var j_top = document.getElementById('j_top');
+ _cs_source_any_all = j_top.cloneNode(true);
+ }
+
+ // find the parent any/all select, and remove the grouped option
+ var structure = _cs_build_structure(row);
+ var old_id = _cs_get_row_id(row);
+ var parent_j = document.getElementById(_cs_get_join(structure, 'f' + old_id));
+ _cs_remove_and_g(parent_j);
+
// If there's an "Any/All" select in this row, it needs to stay as
// part of the parent paren set.
var old_any_all = _remove_any_all(row);
@@ -66,21 +81,20 @@ function custom_search_open_paren() {
var not_for_paren = new_not[0].cloneNode(true);
// Preserve the values when modifying the row.
- var id = _cs_fix_ids(row, true);
+ var id = _cs_fix_row_ids(row, true);
var prev_id = id - 1;
var paren_row = row.cloneNode(false);
paren_row.id = null;
paren_row.innerHTML = '(<input type="hidden" name="f' + prev_id
- + '" value="OP">';
+ + '" id="f' + prev_id + '" value="OP">';
paren_row.insertBefore(not_for_paren, paren_row.firstChild);
row.parentNode.insertBefore(paren_row, row);
-
+
// New paren set needs a new "Any/All" select.
var any_all_container = document.createElement('div');
YAHOO.util.Dom.addClass(any_all_container, ANY_ALL_SELECT_CLASS);
- var j_top = document.getElementById('j_top');
- var any_all = j_top.cloneNode(true);
+ var any_all = _cs_source_any_all.cloneNode(true);
any_all.name = 'j' + prev_id;
any_all.id = any_all.name;
any_all_container.appendChild(any_all);
@@ -92,6 +106,7 @@ function custom_search_open_paren() {
YAHOO.util.Dom.setStyle(row, 'margin-left', new_margin + 'em');
YAHOO.util.Dom.removeClass('cp_container', 'bz_default_hidden');
+ cs_reconfigure(any_all_container);
fix_query_string(any_all_container);
}
@@ -100,7 +115,7 @@ function custom_search_close_paren() {
// We need to up the new row's id by one more, because we're going
// to insert a "CP" before it.
- var id = _cs_fix_ids(new_row);
+ var id = _cs_fix_row_ids(new_row);
var margin = YAHOO.util.Dom.getStyle(new_row, 'margin-left');
var int_match = margin.match(/\d+/);
@@ -110,7 +125,7 @@ function custom_search_close_paren() {
var paren_row = new_row.cloneNode(false);
paren_row.id = null;
paren_row.innerHTML = ')<input type="hidden" name="f' + (id - 1)
- + '" value="CP">';
+ + '" id="f' + (id - 1) + '" value="CP">';
new_row.parentNode.insertBefore(paren_row, new_row);
@@ -118,6 +133,7 @@ function custom_search_close_paren() {
YAHOO.util.Dom.addClass('cp_container', 'bz_default_hidden');
}
+ cs_reconfigure(new_row);
fix_query_string(new_row);
}
@@ -160,19 +176,17 @@ function redirect_html4_browsers() {
document.location = url;
}
-function _cs_fix_ids(parent, preserve_values) {
+function _cs_fix_row_ids(row, preserve_values) {
// Update the label of the checkbox.
- var label = YAHOO.util.Dom.getElementBy(function() { return true },
- 'label', parent);
+ var label = YAHOO.util.Dom.getElementBy(function() { return true }, 'label', row);
var id_match = label.htmlFor.match(/\d+$/);
var id = parseInt(id_match[0]) + 1;
label.htmlFor = label.htmlFor.replace(/\d+$/, id);
- // Sets all the inputs in the parent back to their default
+ // Sets all the inputs in the row back to their default
// and fixes their id.
var fields =
- YAHOO.util.Dom.getElementsByClassName('custom_search_form_field', null,
- parent);
+ YAHOO.util.Dom.getElementsByClassName('custom_search_form_field', null, row);
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
@@ -184,15 +198,141 @@ function _cs_fix_ids(parent, preserve_values) {
field.value = '';
}
}
-
- // Update the numeric id for the new row.
+
+ // Update the numeric id for the row.
field.name = field.name.replace(/\d+$/, id);
field.id = field.name;
}
-
+
return id;
}
+function _cs_build_structure(form_member) {
+ // build a map of the structure of the custom fields
+ var form = YAHOO.util.Dom.getAncestorByTagName(form_member, 'form');
+ var last_id = _get_last_cs_row_id(form);
+ var structure = [ 'j_top' ];
+ var nested = [ structure ];
+ for (var id = 1; id <= last_id; id++) {
+ var f = form['f' + id];
+ if (!f || !f.parentNode.parentNode) continue;
+
+ if (f.value == 'OP') {
+ var j = [ 'j' + id ];
+ nested[nested.length - 1].push(j);
+ nested.push(j);
+ continue;
+ } else if (f.value == 'CP') {
+ nested.pop();
+ continue;
+ } else {
+ nested[nested.length - 1].push('f' + id);
+ }
+ }
+ return structure;
+}
+
+function cs_reconfigure(form_member) {
+ var structure = _cs_build_structure(form_member);
+ _cs_add_listeners(structure);
+ _cs_trigger_j_listeners(structure);
+ fix_query_string(form_member);
+
+ var j = _cs_get_join(structure, 'f' + _get_last_cs_row_id());
+ document.getElementById('op_button').disabled = document.getElementById(j).value == 'AND_G';
+}
+
+function _cs_add_listeners(parents) {
+ for (var i = 0, l = parents.length; i < l; i++) {
+ if (typeof(parents[i]) == 'object') {
+ // nested
+ _cs_add_listeners(parents[i]);
+ } else if (i == 0) {
+ // joiner
+ YAHOO.util.Event.removeListener(parents[i], 'change', _cs_j_change);
+ YAHOO.util.Event.addListener(parents[i], 'change', _cs_j_change, parents);
+ } else {
+ // field
+ YAHOO.util.Event.removeListener(parents[i], 'change', _cs_f_change);
+ YAHOO.util.Event.addListener(parents[i], 'change', _cs_f_change, parents);
+ }
+ }
+}
+
+function _cs_trigger_j_listeners(fields) {
+ var has_children = false;
+ for (var i = 0, l = fields.length; i < l; i++) {
+ if (typeof(fields[i]) == 'undefined') {
+ continue;
+ } else if (typeof(fields[i]) == 'object') {
+ // nested
+ _cs_trigger_j_listeners(fields[i]);
+ has_children = true;
+ } else if (i == 0) {
+ _cs_j_change(undefined, fields);
+ }
+ }
+ if (has_children) {
+ _cs_remove_and_g(document.getElementById(fields[0]));
+ }
+}
+
+function _cs_get_join(parents, field) {
+ for (var i = 0, l = parents.length; i < l; i++) {
+ if (typeof(parents[i]) == 'object') {
+ // nested
+ var result = _cs_get_join(parents[i], field);
+ if (result) return result;
+ } else if (parents[i] == field) {
+ return parents[0];
+ }
+ }
+ return false;
+}
+
+function _cs_remove_and_g(join_field) {
+ var index = bz_optionIndex(join_field, 'AND_G');
+ join_field.options[index] = null;
+ join_field.options[bz_optionIndex(join_field, 'AND')].innerHTML = cs_and_label;
+ join_field.options[bz_optionIndex(join_field, 'OR')].innerHTML = cs_or_label;
+}
+
+function _cs_j_change(evt, fields, field) {
+ var j = document.getElementById(fields[0]);
+ if (j && j.value == 'AND_G') {
+ for (var i = 1, l = fields.length; i < l; i++) {
+ if (typeof(fields[i]) == 'object') continue;
+ if (!field) {
+ field = document.getElementById(fields[i]).value;
+ } else {
+ document.getElementById(fields[i]).value = field;
+ }
+ }
+ if (evt) {
+ fix_query_string(j);
+ }
+ if ('f' + _get_last_cs_row_id() == fields[fields.length - 1]) {
+ document.getElementById('op_button').style.display = 'none';
+ }
+ } else {
+ document.getElementById('op_button').style.display = '';
+ }
+}
+
+function _cs_f_change(evt, args) {
+ var field = YAHOO.util.Event.getTarget(evt);
+ _cs_j_change(evt, args, field.value);
+}
+
+function _get_last_cs_row_id() {
+ return _cs_get_row_id('custom_search_last_row');
+}
+
+function _cs_get_row_id(row) {
+ var label = YAHOO.util.Dom.getElementBy(function() { return true }, 'label', row);
+ return parseInt(label.htmlFor.match(/\d+$/)[0]);
+}
+
function _remove_any_all(parent) {
var any_all = YAHOO.util.Dom.getElementsByClassName(
ANY_ALL_SELECT_CLASS, null, parent);