103 lines
3.2 KiB
JavaScript
103 lines
3.2 KiB
JavaScript
/**
|
|
* Component for filtering a table or any list of children based on
|
|
* the dynamic value of a text input. It requires the prototype.js
|
|
* library.
|
|
*
|
|
* You should define the CSS class .QuickFinderNoMatch to say what
|
|
* happens to items that don't match the criteria. A reasonable
|
|
* default would be display:none.
|
|
*
|
|
* This code is heavily inspired by Filterlicious by Gavin
|
|
* Kistner. The filterlicious JavaScript file did not have a license;
|
|
* however, most of Gavin's code is under the license defined by
|
|
* http://phrogz.net/JS/_ReuseLicense.txt, so I'm including that URL
|
|
* and Gavin's name as acknowledgements.
|
|
*
|
|
* @author Chuck Hagenbuch <chuck@horde.org>
|
|
* @copyright 2014-2015 Horde LLC
|
|
* @license LGPL-2 (http://www.horde.org/licenses/lgpl)
|
|
*/
|
|
|
|
var QuickFinder = {
|
|
|
|
attachBehavior: function(input) {
|
|
var filterEmpty, i, t, targets,
|
|
filterTarget = input.readAttribute('for');
|
|
if (!filterTarget) {
|
|
return;
|
|
}
|
|
|
|
if (filterTarget.indexOf(',') != -1) {
|
|
input.filterTargets = [];
|
|
targets = filterTarget.split(',');
|
|
for (i = 0; i < targets.length; ++i) {
|
|
t = $(targets[i]);
|
|
if (t) {
|
|
input.filterTargets.push(t);
|
|
}
|
|
}
|
|
if (!input.filterTargets.size()) {
|
|
return;
|
|
}
|
|
} else {
|
|
input.filterTargets = [ $(filterTarget) ];
|
|
if (!input.filterTargets[0]) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
filterEmpty = input.readAttribute('empty');
|
|
if (filterEmpty) {
|
|
input.filterEmpty = $(filterEmpty);
|
|
}
|
|
|
|
input.observe('keyup', this.onKeyUp.bindAsEventListener(this));
|
|
|
|
for (i = 0, i_max = input.filterTargets.length; i < i_max; i++) {
|
|
input.filterTargets[i].childElements().each(function(line) {
|
|
var filterText = line.filterText || line.readAttribute('filterText');
|
|
if (!filterText) {
|
|
line.filterText = line.innerHTML.stripTags();
|
|
}
|
|
line.filterText = line.filterText.toLowerCase();
|
|
});
|
|
}
|
|
|
|
this.filter(input);
|
|
},
|
|
|
|
onKeyUp: function(e) {
|
|
var input = e.element();
|
|
if (input.filterTargets) {
|
|
this.filter(input);
|
|
}
|
|
},
|
|
|
|
filter: function(input) {
|
|
var i, matched = 0,
|
|
val = input.value.toLowerCase();
|
|
for (i = 0, i_max = input.filterTargets.length; i < i_max; i++) {
|
|
input.filterTargets[i].childElements().each(function(line) {
|
|
var filterText = line.filterText;
|
|
if (filterText.indexOf(val) == -1) {
|
|
line.addClassName('QuickFinderNoMatch');
|
|
} else {
|
|
++matched;
|
|
line.removeClassName('QuickFinderNoMatch');
|
|
}
|
|
});
|
|
}
|
|
|
|
try {
|
|
if (input.filterEmpty) {
|
|
(matched === 0) ? input.filterEmpty.show() : input.filterEmpty.hide();
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
};
|
|
|
|
document.observe('dom:loaded', function() {
|
|
$$('input').each(QuickFinder.attachBehavior.bind(QuickFinder));
|
|
});
|