Simple Search Form Filtering Prefetched Data

by tbreuss

Level: advanced • Mithril.js Version: latest

This example shows a simple search form that filters prefetched data. It is using the Mitosis pattern for stage management. A live example can be seen here on this website.

Live Example

Dependencies

Type Name URL
scriptmithril@latesthttps://unpkg.com/mithril@latest

JavaScript

  const State = () => ({
    formData: {
      input: ''
    },
    rawData: [],
    filteredData: [],
  })

  const Actions = state => ({
    filter: (input) => {
      state.formData.input = input
      input = input.trim()
      if (input.length === 0) {
        state.filteredData = []
        return
      }
      const words = input.split(/\s+/)
      state.filteredData = state.rawData.filter(example => {
        let filtered = false
        words.map(word => {
          if (example.title.toLowerCase().indexOf(word.toLowerCase()) > -1) {
            filtered = true
          }
        })
        return filtered
      })
    },
    reset: () => {
      state.formData.input = ''
      state.filteredData = []
    }
  })

  const focus = ({dom}) => setTimeout(() => dom.focus())

  const filter = (e) => actions.filter(e.target.value)

  const Form = {
    view: ({attrs: {state, actions}}) => m('.search', [
      m('input[type=text]', {
        placeholder: 'Search for examples...',
        value: state.formData.input,
        oncreate: focus,
        onupdate: focus,
        oninput: filter
      }),
      state.formData.input.length > 0
        ? m('button', {onclick: actions.reset}, 'Reset')
        : ''
    ])
  }

  const List = {
    view: ({attrs: {state, actions}}) => {
      return state.filteredData.length > 0
        ? m('ul', state.filteredData.map(example => {
            return m('li', example.title)
          })
        )
        : state.formData.input.length > 0
          ? m('p', 'Your search did not match any examples.')
          : ''
    }
  }

  const apiUrl = 'https://mithril-by-examples.js.org/api/examples.json'
  const state = State()
  const actions = Actions(state)

  m.mount(document.body, {
    oninit: async function () {
      state.rawData = await m.request(apiUrl)
    },
    view: () => [
      m(Form, {state, actions}),
      m(List, {state, actions})
    ]
  })

CSS

@import "https://unpkg.com/water.css@2/out/water.min.css";
input {
  display: inline;
}

The snippet requires the latest version of Mithril.js framework. More advanced users should be able to follow this example, however it contains some first difficulties.

In this example we can see some Mithril.js API methods like m.mount or m.request, besides Mithril.js' basic m() hyperscript function. It also demonstrates, how Mithril.js' lifecycle methods (aka hooks) like oninit, oncreate and onupdate can be used.

The code sample was authored by tbreuss. It was last modified on 27 November 2021. Want to see more examples written by tbreuss? Then Click here.

Contribute

Do you see some improvements, that could be addressed here? Then let me know by opening an issue. As an alternative, you can fork the repository on GitHub, push your commits and send a pull request. To start your work, click on the edit link below. Thank you for contributing to this repo.

See more code examples  •  Edit this example on GitHub