class JsAutocompleteBuilder
Public Class Methods
new(server: {list: '', action: ''})
click to toggle source
list: is the url of the server which returns the list action: is the url of the server to process the search request
# File lib/jsautocomplete_builder.rb, line 14 def initialize(server: {list: '', action: ''}) @server = server end
Public Instance Methods
to_css()
click to toggle source
# File lib/jsautocomplete_builder.rb, line 33 def to_css() css() end
to_html()
click to toggle source
returns just the form part
# File lib/jsautocomplete_builder.rb, line 19 def to_html() html=<<EOF <form action='#{@server[:action]}' method='get' name='searchForm'> <input tabindex='2' type='text' autofocus='true' onkeyup='input = this.value; updateList(event.keyCode, this)' placeholder='search' onfocus='showList()' onblur='hideList()' id='search' autocomplete='off' name='q'/> <input type='submit' value='search'> <ol id='autolist'></ol> </form> EOF end
to_js()
click to toggle source
# File lib/jsautocomplete_builder.rb, line 37 def to_js() url = @server[:list] =~ /\?\w+=$/ ? @server[:list] : @server[:list] + '?q=' ("\n var serverList = '%s';\n\n" % url) + js() end
to_webpage()
click to toggle source
# File lib/jsautocomplete_builder.rb, line 44 def to_webpage() doc = Rexle.new(build_html()) doc.root.element('body').add Rexle::Element.new('script').add_text(to_js()) doc.root.element('head').add Rexle::Element.new('style').add_text(to_css()) doc.xml(pretty: true) end
Private Instance Methods
build_html()
click to toggle source
# File lib/jsautocomplete_builder.rb, line 56 def build_html() RexleBuilder.build do |xml| xml.html do xml.head do xml.title 'Search' xml.meta name: "viewport", content: \ "width=device-width, initial-scale=1" end xml.body do xml.div({tabindex: '1', id: 'autosuggest'}, to_html()) xml.p 'Search page generated using the jsautocomplete_builder gem' end end end end
css()
click to toggle source
# File lib/jsautocomplete_builder.rb, line 73 def css() <<EOF body {font-family: Arial;} form input { background-color: transparent; padding: 0; margin: 0; } ol { background-color: #eee; position: absolute; left: 12px; padding: 0; margin: 0; list-style-type: none; } #autolist li { background-color: transparent; padding: 0; margin: 0; cursor: pointer; } #autolist li:hover, #autolist li:focus {background-color: rgba(223,223,200,7)} div#autosuggest {background-color: transparent; width: 14em; } #autosuggest ol {display: none} input[type=submit] {background-color: transparent; display: inline} EOF end
js()
click to toggle source
# File lib/jsautocomplete_builder.rb, line 108 def js() <<EOF const KEY_UP = 38; const KEY_DOWN = 40; const ESC_KEY = 27; const ENTER_KEY = 13; const SPACEBAR_KEY = 32; var input = ''; function ajaxRequest(url, cFunction) { var xhttp; xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { cFunction(this); } }; xhttp.open("GET", url, true); xhttp.send(); } function ajaxFetchList(e) { ajaxRequest(serverList + e.value, ajaxResponseList) } function ajaxResponseList(xhttp) { document.getElementById('autolist').innerHTML = xhttp.responseText; list = document.getElementById('autolist'); list.style.display = 'block'; } function updateList(keyCode, e) { if (keyCode == ESC_KEY) return if (keyCode == KEY_DOWN) { //showList(); li = document.getElementById('autolist').children.item(0); e.value = li.textContent; li.focus(); return } //e.value; if (e.value.length > 0) { ajaxFetchList(e); } } function hideList() { setTimeout(function(){ console.log('parent: ' + document.activeElement.nodeName); id = document.activeElement.parentElement.id; if (id !== 'autolist' && id !== 'autosuggest') { list = document.getElementById('autolist'); list.style.display = 'none'; } }, 100); } function itemKeyup(keyCode, e) { //console.log('keyCode: ' + keyCode); txt = document.getElementById('search'); if (keyCode == ENTER_KEY || keyCode == SPACEBAR_KEY) { itemSelected(e) } else if (keyCode == KEY_UP) { if (e.previousElementSibling) { txt.value = e.previousElementSibling.textContent; e.previousElementSibling.focus(); } else document.getElementById('search').focus(); } else if (keyCode == KEY_DOWN) { txt.value = e.nextElementSibling.textContent; e.nextElementSibling.focus(); } else if (keyCode == ESC_KEY) { // select the original search text value txt.value = input; list = document.getElementById('autolist'); list.style.display = 'none'; txt.focus(); } } function itemSelected(e) { txt = document.getElementById('search'); txt.value = e.textContent; list = document.getElementById('autolist'); list.style.display = 'none'; document.searchForm.submit(); } function showList() { console.log('parent2: ' + document.activeElement.nodeName); txt = document.getElementById('search'); if (txt.value.length > 0) { list = document.getElementById('autolist'); list.style.display = 'block'; } } EOF end