morris menanya
morris menanya

Reputation: 63

Search with Rails Ransack Gem: implement a 2 sec search delay while searching with Ransack

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

Answers (1)

Sannan Yousuf
Sannan Yousuf

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

Related Questions