1import { Controller } from "@hotwired/stimulus" 2 3// Generic GET filter form controller with debounce + inline clear actions. 4export default class extends Controller { 5 static targets = ["input", "clear"] 6 static values = { 7 delay: { type: Number, default: 400 } 8 } 9 10 connect() { 11 this.submitTimer = null 12 this.syncClearButtons() 13 } 14 15 disconnect() { 16 if (this.submitTimer) clearTimeout(this.submitTimer) 17 } 18 19 onInput() { 20 this.syncClearButtons() 21 this.scheduleSubmit() 22 } 23 24 onKeydown(event) { 25 if (event.key !== "Escape") return 26 const input = event.target 27 if (!(input instanceof HTMLInputElement)) return 28 if (!this.inputTargets.includes(input)) return 29 30 if (input.value !== "") { 31 event.preventDefault() 32 input.value = "" 33 this.syncClearButtons() 34 this.scheduleSubmit() 35 } 36 } 37 38 clear(event) { 39 const name = event.params.name 40 if (!name) return 41 42 const input = this.inputTargets.find((el) => el.name === name) 43 if (!input) return 44 45 if (input.value !== "") { 46 input.value = "" 47 input.focus() 48 this.syncClearButtons() 49 this.scheduleSubmit() 50 } 51 } 52 53 scheduleSubmit() { 54 if (this.submitTimer) clearTimeout(this.submitTimer) 55 this.submitTimer = setTimeout(() => { 56 this.submitTimer = null 57 // requestSubmit preserves normal form behavior and params. 58 this.element.requestSubmit() 59 }, this.delayValue) 60 } 61 62 syncClearButtons() { 63 this.clearTargets.forEach((btn) => { 64 const name = btn.dataset.autoFilterNameParam 65 const input = this.inputTargets.find((el) => el.name === name) 66 const hasValue = input && input.value.trim().length > 0 67 btn.classList.toggle("hidden", !hasValue) 68 }) 69 } 70};
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.