2025-02-12 14:00:03 +08:00
|
|
|
// app/javascript/controllers/search_controller.js
|
|
|
|
import { Controller } from "@hotwired/stimulus"
|
|
|
|
|
|
|
|
export default class extends Controller {
|
2025-02-12 14:47:30 +08:00
|
|
|
static targets = ["input", "clearButton", "spinner", "statusIcon"]
|
|
|
|
|
|
|
|
connect() {
|
|
|
|
this.pendingRequest = null
|
|
|
|
}
|
2025-02-12 14:00:03 +08:00
|
|
|
|
|
|
|
submit() {
|
|
|
|
clearTimeout(this.timeout)
|
|
|
|
this.timeout = setTimeout(() => {
|
2025-02-12 14:47:30 +08:00
|
|
|
// 如果有待处理的请求,则中止它
|
|
|
|
if (this.pendingRequest) {
|
|
|
|
this.pendingRequest.abort()
|
|
|
|
}
|
|
|
|
|
|
|
|
const form = this.element
|
|
|
|
const searchInput = this.inputTarget
|
|
|
|
const encodedValue = encodeURIComponent(searchInput.value)
|
|
|
|
|
|
|
|
// 更新 URL
|
|
|
|
const url = new URL(window.location)
|
|
|
|
url.searchParams.set('query', encodedValue)
|
|
|
|
window.history.pushState({}, '', url)
|
|
|
|
|
|
|
|
// 显示加载状态
|
|
|
|
this.showLoadingState()
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
this.pendingRequest = new AbortController()
|
|
|
|
fetch(form.action + '?' + new URLSearchParams(new FormData(form)), {
|
|
|
|
headers: {
|
|
|
|
'Accept': 'text/vnd.turbo-stream.html',
|
|
|
|
'Turbo-Frame': 'cities_results'
|
|
|
|
},
|
|
|
|
signal: this.pendingRequest.signal
|
|
|
|
})
|
|
|
|
.then(response => response.text())
|
|
|
|
.then(html => {
|
|
|
|
Turbo.renderStreamMessage(html)
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
if (error.name === 'AbortError') return
|
|
|
|
console.error('Search error:', error)
|
|
|
|
})
|
|
|
|
.finally(() => {
|
|
|
|
this.hideLoadingState()
|
|
|
|
this.pendingRequest = null
|
|
|
|
})
|
2025-02-12 14:00:03 +08:00
|
|
|
}, 300)
|
|
|
|
}
|
2025-02-12 14:47:30 +08:00
|
|
|
|
|
|
|
showLoadingState() {
|
|
|
|
if (this.hasClearButtonTarget) {
|
|
|
|
this.clearButtonTarget.classList.add('hidden')
|
|
|
|
}
|
|
|
|
if (this.hasSpinnerTarget) {
|
|
|
|
this.spinnerTarget.classList.remove('hidden')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hideLoadingState() {
|
|
|
|
if (this.hasClearButtonTarget) {
|
|
|
|
this.clearButtonTarget.classList.remove('hidden')
|
|
|
|
}
|
|
|
|
if (this.hasSpinnerTarget) {
|
|
|
|
this.spinnerTarget.classList.add('hidden')
|
|
|
|
}
|
|
|
|
}
|
2025-02-12 14:00:03 +08:00
|
|
|
}
|