AlchemyCMS/alchemy_cms

View on GitHub
app/javascript/alchemy_admin/components/list_filter.js

Summary

Maintainability
A
0 mins
Test Coverage
class ListFilter extends HTMLElement {
  constructor() {
    super()
    this.#attachEvents()
  }

  #attachEvents() {
    this.filterField.addEventListener("keyup", () => {
      const term = this.filterField.value
      this.clearButton.style.visibility = "visible"
      this.filter(term)
    })
    this.clearButton.addEventListener("click", (e) => {
      e.preventDefault()
      this.clear()
    })
    this.filterField.addEventListener("focus", () =>
      key.setScope("list_filter")
    )
    key("esc", "list_filter", () => {
      this.clear()
      this.filterField.blur()
    })
  }

  filter(term) {
    if (term === "") {
      this.clearButton.style.visibility = "hidden"
    }

    this.items.forEach((item) => {
      const name = item.getAttribute(this.nameAttribute)?.toLowerCase()
      // indexOf is much faster then match()
      if (name.indexOf(term.toLowerCase()) !== -1) {
        item.classList.remove("hidden")
      } else {
        item.classList.add("hidden")
      }
    })
  }

  clear() {
    this.filterField.value = ""
    this.filter("")
  }

  get nameAttribute() {
    return this.getAttribute("name-attribute") || "name"
  }

  get clearButton() {
    return this.querySelector('button[type="button"]')
  }

  get filterField() {
    return this.querySelector('input[type="text"]')
  }

  get items() {
    return document.querySelectorAll(this.itemsSelector)
  }

  get itemsSelector() {
    return this.getAttribute("items-selector")
  }
}

customElements.define("alchemy-list-filter", ListFilter)