search bar in mithriljs

A search bar embedded as a component within a view that is defined the main route that updates the query string params.

by Barney Carroll

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.0/mithril.js"></script>

CSS

* { box-sizing: border-box; }
html, body { padding: 0px; margin: 0px; font-family: arial; }
.header { background: rgb(240,240,240); padding: 16px; }
.header input { font-size: 14px; width: 100%; padding: 8px; outline: none; }

.tasks .task { 
  font-size: 14px;
  padding: 16px;
  border-bottom: solid 1px rgb(240,240,240) 
}

.highlight { background: rgb(255,255,0) }

CoffeeScript

term = null

highlight = (text, search, case_sensitive=true) ->
  if search
    text   = text.toString()
    search = search.toString()
    bits =
    if case_sensitive
      text.split(search)
    else
      regex = new RegExp(search, "gi")
      text.split(regex)
    str = []
    i   = 1
    for bit in bits
      str.push m 'span.highlight', search if i % 2 is 0
      str.push m 'span', bit            
      i++
    str
  else
    text


data = [
  { id: 1, name: 'The quick brown fox jumps through hopes' }
  { id: 2, name: 'The lazy bear slept through the winter' }
  { id: 3, name: 'The stupid pug ate a ton of dirt' }    
  { id: 4, name: 'The fat cow was turned into steaks' }        
]

window.app =
  shared:
    header: {}
  tasks:
    index: {}

app.shared.header.controller = ->
  search: (ev)->
   term = ev.target.value
   #querystring = m.route.buildQueryString {search: term}
   m.route '/', {search: term}
app.shared.header.view = (ctrl)->
  attrs =
    placeholder: 'Search for tasks'
    value: term
    onkeyup: ctrl.search
    
  m '.header',
    m '.search', [
     m "input[type='text']", attrs
    ]

app.tasks.index.controller = ->
    m.redraw.strategy 'diff'
app.tasks.index.view = ->
  tasks = []
  tasks.push m '.task', highlight(t.name,term) for t in data
  [
    m.component app.shared.header
    m '.tasks', tasks
  ]
       
routes =
  '/': app.tasks.index
m.route.mode = 'pathname'
m.route document.body, '/', routes