vol1ura/Sat_9am_5km

View on GitHub
app/views/admin/_athlete_fields.html.erb

Summary

Maintainability
Test Coverage
<div class='autocomplete'>
  <%=
    form.hidden_field :athlete_id, id: 'autocomplete-athlete-id'
    text_field_tag :name, resource&.name, class: 'query-field', type: 'text', placeholder: 'Начните вводить имя...', autocomplete: 'off'
  %>
  <div class="suggestions"></div>
</div>

<script>
$(function () {
  function closeAutoComplete() {
    $('.suggestions').slideUp('fast')
    $('.suggestions').html('')
  };

  let timeout = null

  $('.query-field').on('input', (e) => {
    const name = $(e.target).val()
    if (name.length < 3) {
      closeAutoComplete()
      return
    }
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      suggestions = $('.autocomplete').find('.suggestions')
      findAthletes(suggestions, name)
      suggestions.slideDown('slow')
    }, 350)
  })

  $('.query-field').keydown((e) => {
    current = $('.autocomplete').find('.suggestions li.active')
    if (e.which == 40) {
      next = current.length ? current.next() : $('.suggestions li:first-child')
      if (next.length) {
        next.addClass('active')
        current.removeClass('active')
      }
    }
    if (e.which == 38) {
      current.prev().addClass('active')
      current.removeClass('active')
    }
    if (e.which == 13) {
      e.preventDefault()
      if (current.length) current.click()
    }
    if (e.which == 27) closeAutoComplete()
  });

  $('.suggestions').on('click', 'li', (e) => {
    $('.query-field').val($(e.target).attr('name'))
    $('#autocomplete-athlete-id').val($(e.target).attr('id'))
    closeAutoComplete()
  })

  $('body').on('click', (e) => {
    trigger = $('.suggestions')
    if (trigger != e.target && !trigger.has(e.target).length) {
      closeAutoComplete()
    }
  })
})

function findAthletes(element, query) {
  fetch(`/athletes.json?q=${query}`)
    .then(response => response.json())
    .then(data => {
      list = ''
      data.athletes.forEach((athlete, idx) => {
        if (idx >= 10) return;
        home_event = athlete.home_event ? ` (${athlete.home_event})` : ''
        list += `<li id="${athlete.id}" name="${athlete.name}"><b>A${athlete.code}</b> ${athlete.name}${home_event}</li>`
      })
      element.html(`<ul>${list}</ul>`)
      return true
    })
    .catch(function (err) {
      console.warn('Cannot find any athlete', err)
      return []
    })
}
</script>