Ajax Load Datatable

Ajax Load Datatable

Datatable has been a good tool for displaying data to users. It provides a quick and easy way for user to search and sort record.

However, when it comes to a large number of records, we will face issues like slow loading. Other than that, it will also lead to timeout issue due to the load loading issue.

In order to solve this issue, we can implement ajax loading. This is how we can implement:

Gems

  • jquery-datatables-rails

Flow

  1. When user visit to the page, it will load the data separately.
  2. After the ajax data is loaded then it will load into the datatable.

Project Setup

  1. Create a ItemsDatatable at app/models
class ItemsDatatable
  delegate :params, :h, to: :@view

  def initialize(view)
    @view = view
  end

  def as_json(options = {})
    {
      sEcho: params[:sEcho].to_i,
      iTotalRecords: Item.count,
      iTotalDisplayRecords: items.total_entries,
      aaData: data
    }
  end

private

  def data
    items.map do |item|
      [
        item.id,
      ]
    end
  end

  def items
    @items ||= fetch_items
  end

  def fetch_items
    items = Item.order("#{sort_column} #{sort_direction}")
    items = items.page(page).per_page(per_page)
    if params[:sSearch].present?
      items = items.where("CAST(items.id AS TEXT) ilike :search", search: "%#{params[:sSearch]}%")
    end
    items
  end

  def page
    params[:iDisplayStart].to_i/per_page + 1
  end

  def per_page
    params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 10
  end

  def sort_column
    columns = %w[id]
    sort_col = "items.#{columns[params[:iSortCol_0].to_i]}"
  end

  def sort_direction
    params[:sSortDir_0] == "desc" ? "desc" : "asc"
  end
end

  1. Items Controller
def index_datatable
  respond_to do |format|
    format.json { render json: ItemsDatatable.new(view_context) }
  end
end
  1. Items Index
<table class="ajax-datatable" id="items" data-source="<%= index_datatable_path(format: :json) %>">
  <thead>
    <tr>
      <th>ID</th>
    </tr>
  </thead>

  <tbody>
  </tbody>
</table>
  1. Items coffeescript
$('.ajax-datatable').DataTable
  sPaginationType: "full_numbers"
  bProcessing: true
  bServerSide: true
  sAjaxSource: $('.ajax-datatable').data('source')