How to optimize ajax search using rails and jquery

60 Views Asked by At

I have a users table with 150 records and on page load, it loads first 10 records and on scroll it keep showing up new records as I am using will_pagination gem.

The first problem occurs when I search for something and if found data is more than 10 records, will_pagination stops working.

Other problem is that, my result set never get reset when i remove keyword from text field so when i remove keyword from search field I want to reload that whole record set again like it was on page load with first 10 users.

def search_users
  if params[:search_term].size > 0
    @users = User.joins(:company_users).where("(lower(users.fname) LIKE ? OR lower(users.lname) LIKE ?) AND company_users.company_id = ?", "%#{params[:search_term]}%", "%#{params[:search_term]}%", 1)
    @users = @users.paginate(page: params[:page], per_page: 10)
  else
    @users = @company.users.accessible_by(current_ability).order('lname').paginate(page: params[:page], per_page: 10)
  end
  respond_to do |format|
    format.js { render 'dashboard/search_users' }
  end
end

Ajax Call:

var timer;
$('#searchUsers').keyup(function (e) {
    clearTimeout(timer);
    timer = setTimeout(function () {
        $.ajax({
            url: "<%= dashboard_search_users_path %>?search_term=" + e.target.value,
            type: 'get',
            dataType: "script",
        })
    }, 400);
})

search_users.js.erb

<% if params[:page] && params[:page] > "2" %>
  $('#users-list').append('<%= j render 'users', users: @users, team: @team, company: @company, role: @role %>');
<% else %>
  $('#users-list').html('<%= j render 'users', users: @users, team: @team, company: @company, role: @role %>');
<% end %>
<% if @users.next_page != nil %>
  $('.pagination').replaceWith('<%= j will_paginate @users %>');
<% end %>

_users.html.erb

<% users.each do |u| %>
    <tr>
      <td class="name"><%= u.fname %> <%= u.lname %></td>
    </tr>
<% end %>
<div id="user-pagination-container">
  <%= will_paginate users %>
</div>
<script>
    $(document).ready(function () {
        let prevTop = 0;
        let currentTop = 0;
        if ($('#user-pagination-container .pagination').length) {
            $('#users-table').scroll(function () {
                currentTop = $(this).scrollTop();
                if (prevTop !== currentTop) {
                    prevTop = currentTop;
                    let url = $('#user-pagination-container .pagination .next_page').attr('href');
                    if (url && ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight - 3)) {
                        // $('.pagination').html('<img class="ajax-loader-users" src="<%#= asset_path('ajax-loader.gif') %>" alt="Loading..." title="Loading..." />');
                        return $.getScript(url);
                    }
                }
            });
            return $('#users-table').scroll();
        }
    });
</script>

Any best practices or fix to cope this sort of issue and how to do it with some more efficient way? Typeahead or autocomplete will not work here i think.

1

There are 1 best solutions below

0
vitaly107 On

I cannot answer your exact question but I can suggest using datatables.js for your task. I have seen this used in many commercial projects, used it myself and would recommend it. With datattables.js in rails you can do both server side and client side processing of records in a view depending on the exact situation. you can combine it with popular pagination gems such as kaminary and will_paginate.