-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheasyfilter.coffee
95 lines (78 loc) · 2.69 KB
/
easyfilter.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Utility functions
hasInputBox = (elem) -> $(elem).children('input').length > 0
zip = (a, b) ->
i = 0
results = []
while i < a.length
results.push([a[i], b[i]])
i++
return results
# Main application logic
setupFilters = ->
$('table[filterable-table]').each (i, table) ->
setupTable table
setupTable = (t) ->
$(t).find('thead').append '<tr filterable-column-inputs></tr>'
$(t).find('thead tr[filterable-header-row] th').each (i, elem) ->
if $(elem).is('[filterable-column]')
$(t).find('thead tr[filterable-column-inputs]')
.append '<th><input filterable-logic=\'' + $(elem).attr('filterable-logic') + '\'></input></th>'
else
$(t).find('thead tr[filterable-column-inputs]')
.append '<th></th>'
$('table[filterable-table] thead tr th input').change ->
updateFilters()
updateFilters = ->
$('table[filterable-table]').each (i, table) ->
updateTable table
updateTable = (table) ->
# Make an array with the cells with filter inputs
cellsWithPatterns = $(table).find('thead tr[filterable-column-inputs] th')
# Read patterns from cells into an array of objects
patterns = cellsWithPatterns.map (idx, cell) ->
if hasInputBox(cell)
pattern: $(cell).children('input').val()
logic: $(cell).children('input').attr('filterable-logic')
else
pattern: null
logic: null
# Get only the DOM objects from the jQuery object
patterns = patterns.toArray()
$(table).find('tbody tr').show()
# Compare each table row to the pattern and
# hide it
$(table).find('tbody tr').each (j, row) ->
values = $(row).find('td').map (i, x) -> $(x).text()
filterMatches = zip(patterns, values).map (x) -> matchFilter(x[0], x[1])
i = 0
while i < filterMatches.length
if not filterMatches[i]
$(row).hide()
i++
# Matchers
matchText = (pattern, value) -> value.toLowerCase().includes(pattern.toLowerCase())
matchNumber = (pattern, value) ->
value = value.replace(",", "")
# If the pattern starts with a digit,
# then we'll match using equality
if /^\d/.test(pattern)
return value.includes(pattern)
# eval a expression putting value on the LHS
# and the pattern on the RHS
return eval(value + pattern)
matchFilter = (filter, value) ->
# Unpack variables
pattern = filter['pattern']
logic = filter['logic']
# If there is no logic to apply or the pattern is empty,
# then just return true
if (logic == null) || (pattern.length == 0)
return true
# Transfer flow to matchers
if logic == 'text'
return matchText(pattern, value)
else if logic == 'numeric'
return matchNumber(pattern, value)
# Default behavior: do not hide the row
return true
$(document).ready setupFilters