|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
-
- (function($){
-
- window.initializeFilters = function() {
-
- // Bail early for Konqueror and IE5.2/Mac, which don't fully support dynamic
- // creation of form controls
- try {
- var test = document.createElement("input");
- test.type = "button";
- if (test.type != "button") throw Error();
- } catch (e) {
- return;
- }
-
- // Removes an existing row from the filters table
- function removeRow(button, propertyName) {
- var tr = getAncestorByTagName(button, "tr");
-
- var mode = null;
- var selects = tr.getElementsByTagName("select");
- for (var i = 0; i < selects.length; i++) {
- if (selects[i].name == propertyName + "_mode") {
- mode = selects[i];
- break;
- }
- }
- if (mode && (getAncestorByTagName(mode, "tr") == tr)) {
- // Check whether there are more 'or' rows for this filter
- var next = tr.nextSibling;
- if (next && (next.className == propertyName)) {
- function getChildElementAt(e, idx) {
- e = e.firstChild;
- var cur = 0;
- while (cur <= idx) {
- while (e && e.nodeType != 1) e = e.nextSibling;
- if (cur++ == idx) break;
- e = e.nextSibling;
- }
- return e;
- }
-
- var thisTh = getChildElementAt(tr, 0);
- var nextTh = getChildElementAt(next, 0);
- next.insertBefore(thisTh, nextTh);
- nextTh.colSpan = 1;
-
- thisTd = getChildElementAt(tr, 0);
- nextTd = getChildElementAt(next, 1);
- next.replaceChild(thisTd, nextTd);
- }
- }
-
- var tBody = tr.parentNode;
- tBody.deleteRow(tr.sectionRowIndex);
- if (!tBody.rows.length) {
- tBody.parentNode.removeChild(tBody);
- }
-
- if (propertyName) {
- var select = document.forms["query"].elements["add_filter"];
- for (var i = 0; i < select.options.length; i++) {
- var option = select.options[i];
- if (option.value == propertyName) option.disabled = false;
- }
- }
- }
-
- // Initializes a filter row, the 'input' parameter is the submit
- // button for removing the filter
- function initializeFilter(input) {
- var removeButton = document.createElement("input");
- removeButton.type = "button";
- removeButton.value = input.value;
- if (input.name.substr(0, 10) == "rm_filter_") {
- removeButton.onclick = function() {
- var endIndex = input.name.search(/_\d+$/);
- if (endIndex < 0) endIndex = input.name.length;
- removeRow(removeButton, input.name.substring(10, endIndex));
- return false;
- }
- } else {
- removeButton.onclick = function() {
- removeRow(removeButton);
- return false;
- }
- }
- input.parentNode.replaceChild(removeButton, input);
- }
-
- // Make the submit buttons for removing filters client-side triggers
- var filters = document.getElementById("filters");
- var inputs = filters.getElementsByTagName("input");
- for (var i = 0; i < inputs.length; i++) {
- var input = inputs[i];
- if (input.type == "submit" && input.name
- && input.name.match(/^rm_filter_/)) {
- initializeFilter(input);
- }
- }
-
- // Make the drop-down menu for adding a filter a client-side trigger
- var addButton = document.forms["query"].elements["add"];
- addButton.parentNode.removeChild(addButton);
- var select = document.getElementById("add_filter");
- select.onchange = function() {
- if (select.selectedIndex < 1) return;
-
- if (select.options[select.selectedIndex].disabled) {
- // Neither IE nor Safari supported disabled options at the time this was
- // written, so alert the user
- alert("A filter already exists for that property");
- return;
- }
-
- // Convenience function for creating a <label>
- function createLabel(text, htmlFor) {
- var label = document.createElement("label");
- if (text) label.appendChild(document.createTextNode(text));
- if (htmlFor) label.htmlFor = htmlFor;
- return label;
- }
-
- // Convenience function for creating an <input type="checkbox">
- function createCheckbox(name, value, id) {
- var input = document.createElement("input");
- input.type = "checkbox";
- if (name) input.name = name;
- if (value) input.value = value;
- if (id) input.id = id;
- return input;
- }
-
- // Convenience function for creating an <input type="radio">
- function createRadio(name, value, id) {
- var str = '<input type="radio"';
- if (name) str += ' name="' + name + '"';
- if (value) str += ' value="' + value + '"';
- if (id) str += ' id="' + id + '"';
- str += '/>';
- var span = document.createElement('span');
- // create radio button with innerHTML to avoid IE mangling it.
- span.innerHTML = str;
- return span;
- }
-
- // Convenience function for creating a <select>
- function createSelect(name, options, optional) {
- var e = document.createElement("select");
- if (name) e.name = name;
- if (optional) e.options[0] = new Option();
- if (options) {
- for (var i = 0; i < options.length; i++) {
- var option;
- if (typeof(options[i]) == "object") {
- option = new Option(options[i].text, options[i].value);
- } else {
- option = new Option(options[i], options[i]);
- }
- e.options[e.options.length] = option;
- }
- }
- return e;
- }
-
- var propertyName = select.options[select.selectedIndex].value;
- var property = properties[propertyName];
- var table = document.getElementById("filters").getElementsByTagName("table")[0];
- var tr = document.createElement("tr");
- tr.className = propertyName;
-
- var alreadyPresent = false;
- for (var i = 0; i < table.rows.length; i++) {
- if (table.rows[i].className == propertyName) {
- var existingTBody = table.rows[i].parentNode;
- alreadyPresent = true;
- break;
- }
- }
-
- // Add the row header
- var th = document.createElement("th");
- th.scope = "row";
- if (!alreadyPresent) {
- th.appendChild(createLabel(property.label));
- } else {
- th.colSpan = 2;
- th.appendChild(createLabel("or"));
- }
- tr.appendChild(th);
-
- var td = document.createElement("td");
- if (property.type == "radio" || property.type == "checkbox") {
- td.colSpan = 2;
- td.className = "filter";
- if (property.type == "radio") {
- for (var i = 0; i < property.options.length; i++) {
- var option = property.options[i];
- td.appendChild(createCheckbox(propertyName, option,
- propertyName + "_" + option));
- td.appendChild(createLabel(option ? option : "none",
- propertyName + "_" + option));
- }
- } else {
- td.appendChild(createRadio(propertyName, "1", propertyName + "_on"));
- td.appendChild(document.createTextNode(" "));
- td.appendChild(createLabel("yes", propertyName + "_on"));
- td.appendChild(createRadio(propertyName, "0", propertyName + "_off"));
- td.appendChild(document.createTextNode(" "));
- td.appendChild(createLabel("no", propertyName + "_off"));
- }
- tr.appendChild(td);
- } else {
- if (!alreadyPresent) {
- // Add the mode selector
- td.className = "mode";
- var modeSelect = createSelect(propertyName + "_mode",
- modes[property.type]);
- td.appendChild(modeSelect);
- tr.appendChild(td);
- }
-
- // Add the selector or text input for the actual filter value
- td = document.createElement("td");
- td.className = "filter";
- if (property.type == "select") {
- var element = createSelect(propertyName, property.options, true);
- } else if (property.type == "text") {
- var element = document.createElement("input");
- element.type = "text";
- element.name = propertyName;
- element.size = 42;
- }
- td.appendChild(element);
- element.focus();
- tr.appendChild(td);
- }
-
- // Add the add and remove buttons
- td = document.createElement("td");
- td.className = "actions";
- var removeButton = document.createElement("input");
- removeButton.type = "button";
- removeButton.value = "-";
- removeButton.onclick = function() { removeRow(removeButton, propertyName) };
- td.appendChild(removeButton);
- tr.appendChild(td);
-
- if (alreadyPresent) {
- existingTBody.appendChild(tr);
- } else {
- // Find the insertion point for the new row. We try to keep the filter rows
- // in the same order as the options in the 'Add filter' drop-down, because
- // that's the order they'll appear in when submitted.
- var insertionPoint = getAncestorByTagName(select, "tbody");
- outer: for (var i = select.selectedIndex + 1; i < select.options.length; i++) {
- for (var j = 0; j < table.tBodies.length; j++) {
- if (table.tBodies[j].rows[0].className == select.options[i].value) {
- insertionPoint = table.tBodies[j];
- break outer;
- }
- }
- }
- // Finally add the new row to the table
- var tbody = document.createElement("tbody");
- tbody.appendChild(tr);
- insertionPoint.parentNode.insertBefore(tbody, insertionPoint);
- }
-
- // Disable the add filter in the drop-down list
- if (property.type == "radio" || property.type == "checkbox") {
- select.options[select.selectedIndex].disabled = true;
- }
- select.selectedIndex = 0;
- }
- }
-
- })(jQuery);
|