|
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
|
|