#340 DataTables
DataTables makes it easy to convert a plain HTML table into one with pagination, sorting, and searching - all done with JavaScript and jQuery. Here I show how to set this up and use a Rails application as the data source.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
I have been using datatables since it first came out and rely on its features for all my statistical production sites. Even though I love watching all of the railscasts produced here, I don't find this one particularly rewarding. I find my own use of streamlined helpers to be enough to work with and extend any of the datatables features.
One noticeable trend I'm finding others do, which I will not, is to become too dependent on gems that aren't necessary. jQuery UI, datatables, and a host of other jQuery related feature code works great right out of the box. Some gem authors update their code and keep it up to date, and others fall off and forget their code after time. Becoming too dependent on gems for features that are clearly outlined and easily usable out of the box seems counter-productive to me.
These are just my thoughts.
May be you can open source some of your thoughts in a demo application? This way, we can all benefit from your knowledge. I do. Here is my open source File Manager app:
http://github.com/bruparel/file_manager
Looks pretty nice. Have you tried using will_filter gem? It does similar things, and it also allows you to build powerful queries as well as save filters and share them across multiple users. You can build an entire admin tool in just 5 lines of code.
https://github.com/berk/will_filter
Looks interesting. I've noticed it also has a 'Export data' feature does it need another gem e.g. Prawn PDF? Thanks.
It currently exports to HTML, CSV, XML and JSON. So there is no dependency on any 3rd party library other than Kaminari (for pagination - which is also soon to be changed - so you can plug any pagination library or use will_filter's one).
You just gave me a great idea to add support for PDF. Thank you. I will research which PDF gem would be the best one to use. Very well could be Prawn PDF.
Btw, currently you can plug your own exporters/formats into your custom filter object, so you could generate sophisticated reports. At Geni, we use a few custom reports for various tables.
Thanks Michael. I think I will use will_filter in my project. PDF's would be a handy feature to so thanks for looking it to it.
wow, looks good!
I'm using DataTables, but will be switching!
Hi Michael,
I have tried the gem. It works, and thanks for the great work.
I have a question though. Is it ajax/pjax enabled? I see the whole page gets refreshed while sorting the tables. Any hint is most welcome. Thanks in advance.
I am using will_filter since a few days and it seems like a really helpful gem. My favorite feature is that you can combine saved filters to new filters. There is not that much documentation on customization but code to look into. A good starting point is the dummy application or parts of tr8n.
Thank you for your feedback. I am guilty of not providing enough documentation.
Since the gem was mostly used on internal projects, like tr8n admin tools and others, i never did my part on documenting it.
Well, i am fixing this now. Here is a document on customizing the table view:
https://github.com/berk/will_filter/wiki/Customizing-Table-View
Thanks for the nice documentation. Now there is nothing in the way to have an easy start with will_filter :)
Michael, will_filter is awesome, the biggest challege i face is when i try to use it with decimal data type. Could you pliz try and add a decimal container for it. It will be really nyce.
Thanks a lot
I m trying to use this gem and run into some issues. I managed to get around most of them, but now I am getting a seg fault. I believe it is happening in the controller where I have this code
``` here is the seg fault message I am getting
/home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/relation.rb:241: [BUG] Segmentation fault
ruby 1.9.3p362 (2012-12-25 revision 38607) [i686-linux]
-- Control frame information -----------------------------------------------
c:0186 p:0018 s:0821 b:0818 l:000817 d:000817 METHOD /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/relation.rb:241
c:0185 p:0028 s:0815 b:0815 l:000814 d:000814 METHOD /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/scoping/default.rb:41
c:0184 p:0024 s:0812 b:0812 l:001934 d:000811 LAMBDA /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/scoping/named.rb:180
c:0183 p:---- s:0807 b:0807 l:000806 d:000806 FINISH
c:0182 p:0022 s:0805 b:0805 l:0020c8 d:000804 BLOCK /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/relation/delegation.rb:37
c:0181 p:0007 s:0803 b:0803 l:002134 d:000802 BLOCK /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/relation.rb:241
c:0180 p:0396 s:0801 b:0801 l:000800 d:000800 METHOD /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/scoping.rb:98
c:0179 p:0018 s:0792 b:0792 l:002134 d:002134 METHOD /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/relation.rb:241
c:0178 p:0055 s:0789 b:0789 l:0020c8 d:0020c8 METHOD /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-3.2.9/lib/active_record/relation/delegation.rb:37
c:0177 p:---- s:0783 b:0783 l:000782 d:000782 FINISH
c:0176 p:0163 s:0781 b:0781 l:000780 d:000780 METHOD /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/will_filter-3.1.9/app/models/will_filter/filter.rb:821
c:0175 p:0250 s:0777 b:0777 l:000776 d:000776 METHOD /home/danny/.rvm/gems/ruby-1.9.3-p362/gems/will_filter-3.1.9/lib/will_filter/extensions/active_record_extension.rb:45
-- C level backtrace information -------------------------------------------
Same here!
Both in Rails 3.2.8 and 3.2.10
Gemfile:
source 'https://rubygems.org'
gem 'rails'
gem 'mysql2'
group :test, :development do
gem "rspec-rails", "~> 2.6"
gem 'factory_girl_rails'
end
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'uglifier', '>= 1.0.3'
gem 'jquery-datatables-rails'
gem 'jquery-ui-rails'
end
gem 'jquery-rails'
gem 'prawn'
gem 'kaminari'
ruby-1.9.3-p362 is buggy, and it's a known issue. so reinstall newer stable version(like 1.9.3-p374)
ruby-1.9.3-p362 is buggy, and it's a known issue. so reinstall newer stable version(like 1.9.3-p374)
Tried this. Looks great, but requires a lot of effort to fit in my environment (I18n, etc.).
Denis, i am trying to use datatables with i18n, but no successful. Could you give some hints to works with i18n? Please. Thanks.
A note to the readers: If you try to run the sample app using the episode code from github, you will get an error when you click on the "product name" link. This is because the show view is referencing the category model but there is none in the current code base. So just delete the offending lines of code that references the @product.category.name field.
I made a gem to do this a while back -- cuts out most of the heavy lifting: https://github.com/jasondew/data_table
Why do you create a Class when you can create the json in the respond_to block? For example:
I think Ryan mentioned that you can do that to keep the controller clean. I implemented this a couple of weeks ago, and I wish the screencast came out earlier; I would have followed his suggestion.
I am using the mongoid data table gem that has a one stop search functionality https://github.com/potatosalad/mongoid-data_table
Anyone have any tips for testing this thing? If you test the ProductsDatatable class on it's own (rather than testing the results of the products/index controller action) how can you instantiate a
view_context
on initialization? Or is it best to just rely on mocking/stubbing everything that would normally exist in the context of a normal request?Looking back to the Presenters from Scratch screencast looks like it might be something like this?
Rob, I know this is a year old but did you ever get some decent tests going for this?
Hi Steve,
in case you're still interested, this is how I set to add specs for an implementation based on this Railscast:
https://gist.github.com/antillas21/9a326abfb690d0c26306
Antonio,
I am very happy I found this but I am having issues getting these tests to work for me. Anyway you can help me out with this?
Thanks!
nathan.biles@skipjacksc.com
Hi Rob... in case you're still interested, this is how I set to add specs for an implementation based on this Railscast:
https://gist.github.com/antillas21/9a326abfb690d0c26306
to these u cant live without bootstrap: http://datatables.net/blog/Twitter_Bootstrap_2
Ooooh sexy!
Very useful for my internal admin panels which use Bootstrap2.
+1
Found an even better way to do it! It's in the readme for the jquery-datatables-rails gem:
Twitter Bootstrap 2 support
Add the JavaScript to application.js:
//= require dataTables/jquery.dataTables.bootstrap
Remove the initial stylesheets from application.css
Add the stylesheets to application.css:
*= require dataTables/jquery.dataTables.bootstrap
Initialize your datatables like this:
// For fluid containers
$('.datatable').dataTable({
"sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap"
});
// For fixed width containers
$('.datatable').dataTable({
"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap"
});
https://github.com/rweng/jquery-datatables-rails
Thanks Ira..Time Saver
Hi Ryan
Can you cover other features of data table in rails cast? features like add, delete, edit.
seconded.
One thing I noted when trying to implement datatables with server-side processing is that the SQL queries on search aren't as fuzzy as the default datatables search function. If you're going server-side, definitely check out other search solutions.
That is the issue #1 with server-side processing. Whatever server-side search will be implemented, anyway it will searching against server-side 'look' of the data. Client-side search will find exactly what user wants even in complex cases.
So I would rather implement some pre-filtering by date or other parameters and pass all that filtered data to client-side.
Other issues, that not covered in this episode, like sorting on associated table values, can be solved relatively easy using joins.
I'd like to use datatables but I'm using an api where not all columns are sortable and it has a weird way of passing the column argument, rather than column and direction i have to pass columnIsdesc=true or false or not pass it.
How would I go about that?
If you use Kaminari instead of will_paginate, just replace
total_entries
bytotal_count
andper_page(per_page)
byper(per_page)
in the class ProductsDatatableHi Ryan
Please please do an episode on CRUD in datatable and export features of it.
Just a tip -- don't put it in your assets group in the gemfile or it won't work on production when deploying to Heroku.
Thanks Ira!
Great screencast! However how can I pass a data set to json? Say in my controller index I have
@products = Product.where(:status => "active")
to initialize my view. In my view I've got a select tag to filter active, pending and inactive products. How can I pass the set of pending or inactive products to json?Secondly, how do I properly link to an edit path in ProductsDatatable? It gives me a no method error if I do
link_to("edit", edit_product_path(product)
Thanks!
Hello Pramsay
I know this post is a bit old but did you solved your problem ? I'm facing the same wall and can't find solution
Hey anso,
Use the normal link_to :
After some exploration, actually you can still use the url_helpers such as edit_product_path etc by just including the rails url_helper in your class e.g.
data-source for index action is
data-source="<%= products_url(format: "json")
how to code same for something like show action(member action) ??
Does anyone have a working example with Bootstrap and Ajax on Github that I could look at? I think I'm close to getting this to work, but the datatable isn't fetching the json data for some reason. I suspect it's a problem with my javascript, but I can't find the problem.
I initialize my datatables in assets/javascripts/table.js like this:
and in my view I have this:
but the table is empty.
Never mind, I had the javascript in two different files...Ugh!
How can I add a delete button column using the json/ajax approach? Here's what I'm trying to replicate:
<%= link_to 'Delete', product, method: :delete, class: "btn btn-mini btn-danger", confirm: "You sure?", title: product.product_number %>
+1
Try
Cheers
Nice example, has anyone tried this with associated tables?
i.e. product table has a category_id
e.g. so the search will result in the searching category.name or product.name...
Brett, I used:
Nested routes took me a little longer to get working.
eg.
When I went to /characters/1/drops, I was getting the full list of drops.
The index action was being called twice and then fetch. On the first call, the index action had all of the parameters, but params didn't have the character_id on the subsequent call to index or the call to fetch.
To resolve that, I changed the table tag in my view code to:
To use multicolumn sorting, I did this:
Getting error in view:Extract from log:
Highway Count at list: 229
Rendered highways/list.html.erb within layouts/application (107.9ms)
Completed 500 Internal Server Error in 164ms
ActionView::Template::Error (undefined method `highways_url' for #<#Class:0x98d7c4c:0x98d66a8>):
5:
6: <%= link_to("Add New Highway", {:action => 'new'}, :class => 'action new') %>
7:
8: ">
highways.js.coffee:
jQuery ->
$('#highways').dataTable
sPaginationType: "full_numbers"
bJQueryUI: true
bProcessing: true
bServerSide: true
sAjaxSource: $('#highways').data('source')
Rails:3.2.1.
What other information can I supply?
Thanks
Partially solved. Have included a specific route. No data in my table - will look further into that.
Thanks
In the ASCIIcast version, when you clear out the tbody section, you have two opening tbody tags. I think you want one opening and one closing. Thanks for the great examples!
Thank you for notifying us of that discrepancy, I've corrected the transcripts.
Thanks for the great examples. I have a question. One table I wish to show has 3 links to associated tables, and I want to use those associated fields as args for sorting and searching. I cannot work out the syntax in the Ruby class; if it's possible.
When I look at the log I can see 4 queries for every row, the first for the main table and another 3 for each link. Seems very inefficient.
I have this code in the model:
class Neighbour < ActiveRecord::Base
belongs_to :locality, :class_name => "Locality"
belongs_to :neighbour, :class_name => "Locality"
belongs_to :highway, :class_name => "Highway"
default_scope joins(:locality, highway).order('localities.name')
end
In straight SQL I would achieve this with one query and let the database optimise the method. How would I do this to supply a view of data to the dataTable?
Thanks
John,
I would like to do a very similar thing with DataTables. Have you made any progress in how to display data from associated tables using server side processing?
--Rick
Rick,
Sorry I have been away for a few days. I can display the table OK with pagination etc but still have the few issues mentioned above, including that I cannot sort or search the table. I intend to re-visit those problems later.
I have added some code to enable the user to select a row by clicking and render the appropriate view. The controller gets the correct id and the log shows the view as being rendered, but it does not show in the browser. I am working on that at present.
John
Hi John,
Glad to hear you're making progress; such is not the case with me!
I've posted a long message describing my problem over at StackOverflow.com...my handle there is rixter.
I feel close to a solution, so would like to stay in touch. This could be a powerful tool for my project -- if I can get it working!
--Rick
This is just amazing...I found the dataTables plugin a while ago and was trying to figure out all out for a few hours. So I come to railscasts to see if Ryan had anything similar, and lo and behold...he's got an episode on the exact plugin I'm using. This has happened so many times it scary - I'm trying to figure out how to use something and Ryan has an episode on exactly what I'm doing. Railscasts is well worth every dime! Thanks for your awesome work, Ryan.
hi,
i can not use symbol '€', anyone can help me ?
I wasn't aware that
was valid bundler syntax, I thought it was
:git
. Is there a difference between the two? I can't exactly google the issue due to white noise.This isn't valid bundler syntax:
.. but this is:
:github is a new-ish feature in bundler.
source
first one works well under ruby 1.9
Thank you Anna! Foreman (w ruby 2.0 and rails 3.2.14) was not appreciating the non-hashrocket syntax.
Great info, thank you.
It would have helped a novice like me to know that I needed to restart the rails server before "When we reload the page now our table looks quite different."
Also, I saw two places where products.js is mentioned without the .coffee
Has anyone successfully integrated individual column filtering (preferably with multiple columns) with a Rails back end?
Thanks a lot.
I'm also looking for this.. Does anyone did this?
Thanks!!
Hi there,
I am playing with data table following this guide.
But I feel the code in CoffeeScript was loaded before the html/haml code. So the jQuery select didn't find the .
Nothing happened after I load the page.
But when I type $('#provider-data-table').dataTable() on console, I can see the table. It is the same code in the CoffeeScript.
Could you please help me?
Thanks,
Shanbo
I have recently run into this issue and managed to solve it:
It turned out to be turbolinks issue preventing from loading any js on the first page load:
http://stackoverflow.com/questions/17881384/jquery-gets-loaded-only-on-page-refresh-in-rails-4-application
Simple commenting out
//= require turbolinks
helped me but you can try replacing it with 'jquery-turbolinks' gem as an answer on stackoverflow link suggests.
I have been messing around with this today but for some reason I still can't figure out where the following functions are defined and my rails server keeps telling me they are undefined:
Products.page(page).per_page(per_page) and products.total_entries.
Any help would be great.
the .page() and .per_page() are part of will_paginate. If you use kamanari, it's .page() and .per(). I'm not familiar with total_entries, but I use Mongoid and I can use .size
netwire, I am using Mongid as well and I can not get the bootstrap pagination to work. Any ideas?
You should also replace total_entries with total_count.
how can I combine edit, show, destroy button to one column.
try it
Thanks Ryan!! this was exceptionally useful. The fact that you took the time to figure out how to this gem run server side was just great.
It would be good to see a follow up casts using custom css formatting and other interesting tricks. (ie how to handle timeouts, ignoring searching on specific columns).
But what is really useful in the casts are the gems we never heard of used in ways we did not realize were possible. ie charting was a great example
Hi
I followed a railscast episode and got datatables up and running, beautifully along with the nice jquery-ui as in the front page.
The main issue I'm having though is that I suck at CoffeeScript/JS ~_~
I'm trying get the datatables to reload every 1 second but I don’t see any request coming into my webserver for refreshes and hence, no refreshes on the web page itself.
Here's my code:
app/assets/javascripts/comments.js.coffee
And here is the code that gets generated on the client side:
Help will be appreciated. ^_^
Missing sAjaxSource ?