forked from Humbedooh/whimsy-agenda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.js.rb
75 lines (62 loc) · 1.9 KB
/
search.js.rb
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
#
# Search component:
# * prompt for search
# * display matching paragraphs from agenda, highlighting search strings
# * keep query string in window location URL in synch
#
class Search < React
# initialize query text based on data passed to the component
def initialize
@text = @@item.query || ''
end
def render
# search input field
_div.search do
_label 'Search:', for: 'search_text'
_input.search_text! autofocus: 'autofocus', value: @text,
onInput: self.input
end
if @text.length > 2
matches = false
text = @text.downcase()
Agenda.index.each do |item|
next unless item.text and item.text.downcase().include? text
matches = true
_section do
_h4 {_Link text: item.title, href: item.href}
# highlight matching strings in paragraph
item.text.split(/\n\s*\n/).each do |paragraph|
if paragraph.downcase().include? text
_pre.report dangerouslySetInnerHTML: {
__html: htmlEscape(paragraph).gsub(/(#{text})/i,
"<span class='hilite'>$1</span>")
}
end
end
end
end
# if no sections were output, indicate 'no matches'
_p {_em 'No matches'} unless matches
else
# start producing query results when input string has three characters
_p 'Please enter at least three characters'
end
end
# update text whenever input changes
def input(event)
@text = event.target.value
end
# set history on initial rendering
def componentDidMount()
self.componentDidUpdate()
end
# replace history state on subsequent renderings
def componentDidUpdate()
state = {path: 'search', query: @text}
if state.query
history.replaceState(state, nil, "search?q=#{encodeURIComponent(@text)}")
else
history.replaceState(state, nil, 'search')
end
end
end