import { Controller } from '@hotwired/stimulus' import { useFetch } from '../mixins/use_fetch' import Autocomplete from '@trevoreyre/autocomplete-js' export default class extends Controller { static targets = [ 'input', 'field', 'resetButton', 'searchIcon' ] static values = { url: String, choices: Array, selected: Boolean } initialize() { useFetch(this) } connect() { const searchHandler = input => { return new Promise(resolve => { // Check input minimum length if (input.length < 2) { return resolve([]) } // Search choices if provided if (this.choicesValue.length > 0) { return resolve(this.choicesValue.filter(choice => { return -1 !== choice.text.toLowerCase().search(input.toLowerCase()) })) } // Use API otherwise let data = { search: input } fetch(this.urlValue, { method: 'POST', body: JSON.stringify(data), credentials: 'include' }) .then(this.checkStatus) .then(this.parseJSON) .then(data => { resolve(data) }) }) } const submitHandler = result => { this.fieldTarget.value = result.value this.selectedValue = true this.element.dispatchEvent(new CustomEvent('select', { detail: { result } })) } new Autocomplete(this.element, { search: searchHandler, getResultValue: result => result.text, submitOnEnter: true, onSubmit: submitHandler, debounceTime: 250, }) if (this.fieldTarget.value) { this.selectedValue = true } this.element.addEventListener('keypress', e => { if (e.key === 'Enter') { e.preventDefault() } }) } reset() { this.inputTarget.value = null this.fieldTarget.value = null this.selectedValue = false this.element.dispatchEvent(new CustomEvent('reset')) } selectedValueChanged() { this.resetButtonTarget.classList.toggle('hidden', false === this.selectedValue) this.searchIconTarget.classList.toggle('hidden', this.selectedValue) } }