Module: check_mk
Branch: master
Commit: c7638e67f22f03eabc712a8233cc7fe2e3765262
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=c7638e67f22f03…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Fri Sep 21 10:17:48 2012 +0200
FIX: Fixed handling of filter configuration in view editor where filters
are using same variable names. Overlaping filters are now disabled in the editor.
---
ChangeLog | 3 ++
web/htdocs/js/checkmk.js | 62 ++++++++++++++++++++++++++++++++++-----------
web/htdocs/views.py | 32 +++++++++++++++++++++--
3 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f33ad6a..5dabe23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -100,6 +100,9 @@
* FIX: Fixed error in printer_supply valuespec which lead to an exception
when defining host/service specific rules
* FIX: Fixed button url icon in docu-url link
+ * FIX: Fixed handling of filter configuration in view editor where filters
+ are using same variable names. Overlaping filters are now disabled
+ in the editor.
BI:
* Great speed up of rule compilation in large environments
diff --git a/web/htdocs/js/checkmk.js b/web/htdocs/js/checkmk.js
index dd43ee0..9658447 100644
--- a/web/htdocs/js/checkmk.js
+++ b/web/htdocs/js/checkmk.js
@@ -55,6 +55,17 @@ if (!Array.prototype.indexOf)
};
}
+// The nextSibling attribute points also to "text nodes" which might
+// be created by spaces or even newlines in the HTML code and not to
+// the next painted dom object.
+// This works around the problem and really returns the next object.
+function real_next_sibling(o) {
+ var n = o.nextSibling;
+ while (n.nodeType != 1)
+ n = n.nextSibling;
+ return n;
+}
+
var classRegexes = {};
function hasClass(obj, cls) {
@@ -297,29 +308,50 @@ function update_headinfo(text)
}
}
+function toggle_input_fields(container, type, disable) {
+ var fields = container.getElementsByTagName(type);
+ for(var a = 0; a < fields.length; a++) {
+ fields[a].disabled = disable;
+ }
+}
+
+function toggle_other_filters(fname, disable_others) {
+ for(var i = 0; i < g_filter_groups[fname].length; i++) {
+ var other_fname = g_filter_groups[fname][i];
+ var oSelect = document.getElementById('filter_' + other_fname);
+
+ // When the filter is active, disable the other filters and vice versa
+
+ // Disable the "filter mode" dropdown
+ oSelect.disabled = disable_others;
+
+ // Now dig into the filter and rename all input fields.
+ // If disabled add an "_disabled" to the end of the var
+ // If enabled remve "_disabled" from the end of the var
+ var oFloatFilter = real_next_sibling(oSelect);
+ if (oFloatFilter) {
+ toggle_input_fields(oFloatFilter, 'input', disable_others);
+ toggle_input_fields(oFloatFilter, 'select', disable_others);
+ oFloatFilter = null;
+ }
+
+ oSelect = null;
+ }
+}
function filter_activation(oSelect)
{
var usage = oSelect.value;
+ var fname = oSelect.id.replace('filter_', '');
+
+ // Disable/Enable other filters which conflict with this filter
+ toggle_other_filters(fname, usage != 'off');
+
+ // Make the current filter visible/invisible
var oDiv = oSelect.parentNode;
oDiv.setAttribute("className", "filtersetting " + usage);
oDiv.setAttribute("class", "filtersetting " + usage);
- // If the filter is not in state hard or show, disable filter
- // input
- var disabled = usage != "hard" && usage != "show";
- var oFloatFilter = oSelect.nextSibling;
- if (oFloatFilter) {
- for (var i in oFloatFilter.childNodes) {
- oNode = oFloatFilter.childNodes[i];
- if (oNode.tagName == "INPUT" || oNode.tagName ==
"SELECT") {
- oNode.disabled = disabled;
- }
- }
- oFloatFilter = null;
- }
-
- p = null;
oDiv = null;
oSelect = null;
}
diff --git a/web/htdocs/views.py b/web/htdocs/views.py
index 502866f..eaf7dd9 100644
--- a/web/htdocs/views.py
+++ b/web/htdocs/views.py
@@ -590,11 +590,33 @@ def page_edit_view():
forms.header(_("Filters"), isopen=False)
allowed_filters = filters_allowed_for_datasource(datasourcename)
+
# sort filters according to title
s = [(filt.sort_index, filt.title, fname, filt)
for fname, filt in allowed_filters.items()
if fname not in ubiquitary_filters ]
s.sort()
+
+ # Construct a list of other filters which conflict with this filter. A filter uses
one or
+ # several http variables for transporting the filter data. There are several filters
which
+ # have overlaping vars which must not be used at the same time. Those filters must
exclude
+ # eachother. This is done in the JS code. When activating one filter it checks which
other
+ # filters to disable and makes the "mode" dropdowns unchangable.
+ filter_htmlvars = {}
+ for sortindex, title, fname, filt in s:
+ for htmlvar in filt.htmlvars:
+ if htmlvar not in filter_htmlvars:
+ filter_htmlvars[htmlvar] = []
+ filter_htmlvars[htmlvar].append(fname)
+
+ filter_groups = {}
+ for sortindex, title, fname, filt in s:
+ filter_groups[fname] = set([])
+ for htmlvar in filt.htmlvars:
+ filter_groups[fname].update(filter_htmlvars[htmlvar])
+ filter_groups[fname].remove(fname)
+ filter_groups[fname] = list(filter_groups[fname])
+
shown_help = False
for sortindex, title, fname, filt in s:
forms.section(title)
@@ -620,14 +642,18 @@ def page_edit_view():
html.write('</div>')
html.write('<div class=clear></div>')
html.help(filt.comment)
-
- # Set all filters into the proper display state
+
html.write("<script language=\"javascript\">\n")
+
+ html.write("g_filter_groups = %r;\n" % filter_groups)
+
+ # Set all filters into the proper display state
for fname, filt in allowed_filters.items():
if fname not in ubiquitary_filters:
html.write("filter_activation(document.getElementById(\"filter_%s\"));\n"
% fname)
+
html.write("</script>\n")
-
+
def sorter_selection(title, var_prefix, maxnum, data):
allowed = allowed_for_datasource(data, datasourcename)