Reputation: 63
I have a Search feature with Ransack which works well. but I am trying to implement it in a way that the search feature filters a particular user model after about a second or two while typing the search query. I have tried using javascript through Rails Stimulus but it doesn't work cos I can't alter the index action variable. my search field looks like this
<div class="relative">
<%= f.search_field :first_name_or_last_name_or_email_cont, placeholder: "Search...", data: { action: 'keydown->search-delay#search', search_delay_target: "input"}, class:
"block w-full rounded-md border-0 pl-10 py-2 pr-12 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" %>
<div class="absolute inset-y-0 left-0 flex py-3.5 pl-3">
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-5.5-5.5M10 14a7 7 0 1 1 0-14 7 7 0 0 1 0 14z"/>
</svg>
</div>
<div class="absolute inset-y-0 right-0 flex py-1.5 pr-1.5">
<kbd class="inline-flex items-center rounded border border-gray-200 px-1 font-sans text-xs text-gray-400">⌘K</kbd>
</div>
</div>
<%= f.submit "Search", class: "hidden" %>
<% end %>
</div>
while my Ransack modified index controller looks like this
def index
@query = User.ransack(params[:q])
@users = @query.result(distinct: true).order(created_at: :desc).includes(:group)
@pagy, @users = page(@query.result.includes(:group), items: 10)
end
like I said earlier I am using rails stimulus to activate the 2 seconds delay on keystroke and also trying to pass the search query to index action. I don't know if it is the right way to go about it though but this is what I can think of for now. here is the stimulus controller
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="search-delay"
export default class extends Controller {
static targets= ['input', "form", 'file']
connect() {
}
search(){
const input = this.inputTarget.value.trim()
setTimeout(this.searchKey(input), 2000)
}
searchKey(query){
fetch(`/users?utf8=✓&q[first_name_or_last_name_or_email_cont]=${query}`,{
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
}
}
```
Upvotes: 0
Views: 114
Reputation: 89
You can use sleep function of ruby in your index function to cause delay. such as
sleep(2)
where 2 is number of seconds
Upvotes: 0