Last active
September 18, 2025 12:08
-
-
Save kossoff/48db6928a7a187d12987f1bb51c236ba to your computer and use it in GitHub Desktop.
jQuery DataTables & RoR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# put it in app/controllers/concerns | |
# Backend for jQuery DataTables, https://datatables.net/ | |
module DataTables | |
include Pagy::Backend | |
private | |
def datatables_data(model) | |
@model = model | |
@objects = current_objects | |
@total_objects = model.where(conditions).count | |
end | |
def current_objects | |
current_page = (params[:start].to_i / params[:length].to_i) + 1 | |
_pagy, objects = pagy_countless(@model.where(conditions) | |
.order(order(params[:order])), | |
countless_minimal: true, | |
page: current_page, | |
limit: params[:length]) | |
objects | |
end | |
def datatable_columns(column_id) | |
@model.arel_table[%w[id title][column_id.to_i]] | |
end | |
def order(order_hash) | |
return if order_hash.blank? | |
order_hash.to_unsafe_h | |
.map { |o| datatable_columns(params[:order][o.first][:column]).send(params[:order][o.first][:dir]) } | |
end | |
def conditions | |
@search_string = params[:search][:value].downcase.gsub("'", "''") | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
= check_box_tag :some_filter, 0, @some_filter | |
= label_tag :some_filter, 'Some Filter' | |
table#model | |
javascript: | |
$(document).on('turbo:load.model', function () { | |
var dataTable = $("#model").DataTable({ | |
ajax: { | |
url: '#{model_path}', | |
data: function(d){ | |
d.some_filter = $('#some_filter').is(':checked'); | |
}, | |
}, | |
processing: true, | |
serverSide: true, | |
destroy: true, | |
columns: [ | |
{ data: 'id', title: 'ID' }, | |
{ data: 'title', title: 'Title' }, | |
{ data: 'another_col', title: 'Another columns', orderable: false }, | |
], | |
searching: true, | |
order: [[0, 'desc']], | |
createdRow: function(row, data, dataIndex) { | |
$(row).attr('data-href', data.id); | |
} | |
}); | |
$('.dataTable').on('click', 'tbody tr', function() { | |
document.location = "#{model_path}/" + $(this).data('href'); | |
}); | |
document.addEventListener("turbo:before-cache", function() { | |
if (dataTable !== null) { | |
dataTable.destroy(); | |
dataTable = null; | |
} | |
}); | |
$('#some_filter').on('change', function(e){ | |
dataTable.ajax.reload(); | |
}); | |
}); | |
$(document).on('turbo:before-render', function() { | |
$(document).off('turbo:load.model'); | |
}); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
json.draw params[:draw] || 1 | |
json.recordsTotal @total_objects | |
json.recordsFiltered @total_objects | |
json.data @objects do |object| | |
json.id object.id | |
json.title object.title | |
json.another_col object.another_col | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class ModelController < ApplicationController | |
include DataTables | |
def index | |
cookies.permanent[:some_filter] ||= false | |
cookies.permanent[:some_filter] = params[:some_filter] if params[:some_filter].present? | |
@some_filter = ActiveModel::Type::Boolean.new.cast(cookies[:some_filter]) | |
respond_to do |format| | |
format.html | |
format.json do | |
where_condition = '' | |
'model.column = true' if @some_filter == true | |
datatables_data(Model.where(where_condition)) | |
render layout: false | |
end | |
end | |
end | |
private | |
# <- ajax DataTables | |
def conditions | |
super | |
# some sql for search in table | |
Arel.sql "(LOWER(UNACCENT(model.title)) LIKE UNACCENT('%#{@search_string}%')" | |
end | |
# for columns ordering | |
def datatable_columns(column_id) | |
Arel.sql(%w[table.id table.title table.another_col][column_id.to_i]) | |
end | |
# ajax DataTables --> | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment