Fossil SCM

fossil-scm / src / quickfilter.js
Blame History Raw 69 lines
1
/* Javascript code that will enable quick filtering of items in tables.
2
**
3
** Add an input field with the id 'quickfilter' as follows:
4
** <input type="search" id="quickfilter" style="display: none"
5
** placeholder="filter list...">
6
** The id on the input-field is important for the script. The input type
7
** can be text or search, with search some browsers add functionality to
8
** clear the field. The display: none is added to hide it from users that
9
** haven't enabled Javascript, as the script to make it visible is never
10
** executed. This is because without Javascript this input-field would be
11
** functionless.
12
**
13
** Mark the table with the filter items with the class 'filterable'.
14
** The table is expected to have a tbody around the rows that are
15
** filtered (to avoid filtering the header).
16
**
17
** The user can type to filter the table for elements matching the typed text.
18
*/
19
20
const quickfilter = document.getElementById('quickfilter');
21
22
document.addEventListener('DOMContentLoaded', function(){
23
quickfilter.style.display = '';
24
});
25
26
quickfilter.addEventListener('input', function(){
27
const filterrows = document.querySelectorAll('.filterable tbody tr');
28
const filter = quickfilter.value.toLowerCase().trim();
29
let group = null;
30
let groupmatched = false;
31
for(row of filterrows){
32
const orig = row.innerHTML;
33
const cleaned = orig.replaceAll("<mark>", "").replaceAll("</mark>", "");
34
if(filter===''){
35
row.innerHTML = cleaned;
36
row.style.display = 'table-row';
37
continue;
38
}
39
if (row.classList.contains("separator")){
40
group = [];
41
groupmatched = false;
42
}
43
let ind = cleaned.toLowerCase().lastIndexOf(filter);
44
if(ind<0 && !groupmatched){
45
row.innerHTML = cleaned;
46
row.style.display = 'none';
47
}
48
let marked = cleaned;
49
do{
50
if(cleaned.lastIndexOf('<',ind-1)<cleaned.lastIndexOf('>',ind-1)){
51
// not inside a tag
52
marked = marked.substring(0,ind)+'<mark>'+
53
marked.substring(ind, ind+filter.length)+'</mark>'+
54
marked.substring(ind+filter.length);
55
}
56
ind = cleaned.toLowerCase().lastIndexOf(filter,ind-1);
57
}while(ind>=0);
58
row.style.display =
59
(marked===cleaned && !groupmatched) ? 'none' : 'table-row';
60
row.innerHTML = marked;
61
if (marked!=cleaned && group){
62
if (!groupmatched)
63
for (grouprow of group) grouprow.style.display = 'table-row';
64
groupmatched = true;
65
}
66
if (group) group.push(row);
67
};
68
});
69

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button