1import { Controller } from "@hotwired/stimulus" 2 3export default class extends Controller { 4 static targets = ["input", "results"] 5 static values = { 6 personId: { type: String, default: "0" }, 7 minLength: { type: Number, default: 3 }, 8 debounceMs: { type: Number, default: 250 }, 9 } 10 11 connect() { 12 this.clearResults() 13 } 14 15 search() { 16 clearTimeout(this.timeout) 17 this.timeout = setTimeout(() => this.performSearch(), this.debounceMsValue) 18 } 19 20 async performSearch() { 21 if (!this.hasInputTarget) return 22 23 const query = this.inputTarget.value.trim() 24 if (query.length < this.minLengthValue) { 25 this.clearResults() 26 return 27 } 28 29 const params = new URLSearchParams({ 30 query, 31 person_id: this.personIdValue, 32 }) 33 34 try { 35 const response = await fetch(`/products/search?${params.toString()}`, { 36 headers: { Accept: "text/vnd.turbo-stream.html" }, 37 }) 38 39 if (response.ok) { 40 const html = await response.text() 41 Turbo.renderStreamMessage(html) 42 } 43 } catch (error) { 44 console.error("Product search failed:", error) 45 } 46 } 47 48 clearResults() { 49 const results = this.hasResultsTarget 50 ? this.resultsTarget 51 : document.getElementById("search_results") 52 if (results) results.innerHTML = "" 53 } 54};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.