vol1ura/Sat_9am_5km

View on GitHub
app/javascript/controllers/table_head_controller.js

Summary

Maintainability
A
55 mins
Test Coverage
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  toggleSort(e) {
    e.target.closest('tr').querySelectorAll('i.fa').forEach(cell => {
      cell.classList.remove('fa-angle-up', 'fa-angle-down')
      if (cell == e.target) {
        let sort_direction = 'asc'
        if (cell.classList.contains('fa-caret-up')) {
          cell.classList.remove('fa-caret-up')
          cell.classList.add('fa-caret-down')
          sort_direction = 'desc'
        } else {
          cell.classList.remove('fa-caret-down')
          cell.classList.add('fa-caret-up')
        }
        this.sortTable(
          e.target.closest('table'),
          this.currentColumnIndex(e.target.closest('th')),
          sort_direction
        )
        return
      }
      cell.classList.remove('fa-caret-down', 'fa-caret-up')
      cell.classList.add('fa-angle-up')
    })
  }

  sortTable(table, column_idx, sort_direction) {
    const result = Array.prototype.slice.call(table.querySelectorAll('tbody>tr')).sort((a, b) => {
      const el1 = a.querySelector(`td:nth-child(${column_idx + 1})`)
      const el2 = b.querySelector(`td:nth-child(${column_idx + 1})`)
      let val1 = el1.getAttribute('sort_by') || el1.innerHTML
      let val2 = el2.getAttribute('sort_by') || el2.innerHTML
      if (isNaN(val1) || isNaN(val2)) {
        return (sort_direction == 'desc' ? 1 : -1) * val1.localeCompare(val2)
      }
      val1 = parseInt(val1)
      val2 = parseInt(val2)
      return sort_direction == 'desc' ? val1 - val2 : val2 - val1
    })
    const table_body = table.querySelector('tbody')
    table_body.innerHTML = ''
    result.forEach(row => table_body.appendChild(row))
  }

  currentColumnIndex(cell) {
    const columns = Array.prototype.slice.call(cell.closest('tr').cells)
    return columns.indexOf(cell)
  }
}