Sort table data by columns in rails with bootstrap
Solution 1
Thanks to a lot of feedback from Hunter Stevens. Best option I found for me was to use sorttable.js
. Process I used was the following:
- Add gem
'jquery-turbolinks'
to yourGemfile
to fix turbolink javascript issue andbundle install
-
Add
jquery.turbolinks
to javascript manifest file:#app/assets/javascripts/application.js //= require jquery //= require jquery_ujs //= require jquery.turbolinks //= require bootstrap-sprockets //= require turbolinks //= require_tree .
-
Create
js
file at:app/assets/javascripts/shared/<whatever_you_want_to_call_it>.js
. Use$(document).ready
as shown to fix turbo link problem. Specify an IIFE (optional) then paste the vendor code within that IIFE:$(document).ready(function(){ (function vendorTableSorter(){ /* paste all the vendor code here */ }()); });// end document.ready
-
Then, simply add the class
sortable
to your table,which makes all the columns sortable:<table class=" table table-striped sortable"> <thead> <tr> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.age %></td> </tr> <% end %> </tbody>
Solution 2
Fast - sortTable.js
WARNING: if you plan to use pagination, this method will not work.
The faster way (that takes zero queries) involves the library sortTable.js
. The website does a great job explaining how to set your HTML document up. (Simply add some classes to column-headers.) You can also enable case-insensitive sorting.
Assuming you are using Rails 4, or have the turbolinks gem, I highly recommend following a detailed gist with instructions on setting up sortTable.js
in your type on environment. (Full discussion can be found at my Q&A on using turbolinks with sorttable.js.)
Reliable - custom controller methods
WARNING: this method requires at least one query on every page view.
This method comes from Railscast 228: Sortable Table Columns. Reading the attached code is pretty much all you need. This method does work with pagination.
If you choose to follow Railscast for pagination, just stop before the Ajax part, as the Javascript involved is deprecated. Second, watch out for possible SQL injection in that screencast. Thankfully, it explains how to avoid it.
Solution 3
Using bootstrap-sass & bootstrap-table-rails gems:
Gemfile
:
gem 'bootstrap-sass'
gem 'autoprefixer-rails' # i'm not sure whether this is relevant
gem 'bootstrap-table-rails'
Don't forget to run bundle
after you update your Gemfile.
app/assets/javascripts/application.js
:
//= require bootstrap-sprockets
//= require bootstrap-table
// # Replace below with desired locale if needed
//= require locale/bootstrap-table-ru-RU
app/assets/stylesheets/application.scss
:
@import "bootstrap-sprockets";
@import "bootstrap";
@import "bootstrap-table";
app/views/index.html.erb
:
<table data-toggle="table">
<thead>
<tr>
<th data-sortable="true">Name</th>
<th data-sortable="true">Age</th>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.age %></td>
</tr>
<% end %>
</tbody>
</table>
FYI, my gem versions:
bootstrap-sass-3.3.5.1
bootstrap-table-rails-1.8.2.1
Solution 4
Try this:
<table class=" table table-striped" data-sort-name="name" data-sort-order="desc">
<thead>
<tr>
<th data-field="name" data-sortable="true">Name</th>
<th data-field="age" data-sortable="true">Age</th>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.age %></td>
</tr>
<% end %>
</tbody>
</table>
Solution 5
- Add gem 'bootstrap-table-rails' in your Gemfile and run bundle install.
- Add require bootstrap-table in your application.js.
- Add require bootstrap-table in your application.css.
- Add data-toggle="table" to your table tag e.g.
<table data-toggle="table">
. - Add data-sortable="true" to your th tag e.g.
<th data-sortable="true">
. Make this property false if you don't want to sort any particular column e.g.<th data-sortable="false">
Neil
Updated on July 22, 2022Comments
-
Neil almost 2 years
Edit: I would prefer to using bootstrap for this functionality if possible since I have bootstrap in my project. It seems like I might just be missing something to utilize bootstrap's javascript within my rails project.
When the column name is clicked, the table should sort the data by that column name. Below is the table:
I attempted to sort the data with bootstrap, following the examples shown at this website, but it wasn't working for me. What am I missing?
Relevant gems in my Gemfile:
#Gemfile gem 'bootstrap-sass' gem 'autoprefixer-rails'
CSS:
#app/assets/stylesheets/application.css.scss @import "bootstrap-sprockets"; @import "bootstrap"; /* *= require_tree . *= require_self */
Javascript:
#app/assets/javascripts/application.js //= require jquery //= require jquery_ujs //= require turbolinks //= require bootstrap-sprockets //= require_tree .
View displaying records:
#app/views/index.html.erb <h4>Listing Users</h4> <table class=" table table-striped" data-sort-name="name" data-sort-order="desc"> <thead> <tr> <th data-field="name" data-sortable="true">Name</th> <th data-field="age" data-sortable="true">Age</th> </tr> </thead> <tbody> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.age %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to 'New User', new_user_path %>
-
Neil almost 9 yearsI tried that but still not working for me unfortunately.
-
Neil almost 9 yearsI reviewed all your links above. It looks like
sortTable.js
could be an option. The frustrating thing is that bootstrap comes with lots of great javascript functionality already, including table sorting. Since I am already using bootstrap on my project, I would prefer to use bootstrap instead ofsortTable.js
. It seems like I'm just not doing something to include bootstrap's javascript functionality. Any ideas? -
onebree almost 9 yearsIn bootstrap, table sorting is not column sorting, from what I understand. It is drag-to-sort, like rearranging priority of items in a list. We used the sorttable.js option for the company app, and we are using Bootstrap 3. We feel it is the best option.
-
Neil almost 9 yearsThey appear to be using just bootstrap here unless I am mistaken. So it seems like it is possible? wenzhixin.net.cn/p/bootstrap-table/docs/…
-
onebree almost 9 yearsI would not recommend that method. It is not vanilla bootstrap, but rather added libraries. It has to be downloaded, and is not a gem. So any updates must be checked manually (instead of bundle install). It is also a lot more to maintain, code wise, than 1 javascript file (method #1). Bootstrap is nothing more than prepackaged CSS and JavaScript to make a site responsive. Anything that is not vanilla bootstrap simply uses similar CSS or responsive concepts. Bootstrap is mainly for looks/motion of a web page, not function.
-
onebree almost 9 years@Niel, let me know how option #1 works out for you. As noted, go to my Q&A about sorttable.js
-
Neil almost 9 yearsworks like a charm! I will add a temporary answer. Please copy it into your answer, and I will remove my temp answer and give you credit for the help!
-
Neil almost 9 yearsok please append my answer into your answer if you don't mind.
-
onebree almost 9 yearsLet us continue this discussion in chat.
-
onebree almost 9 years@Neil I sent you chat messages above. It does not look like you've replied to any.
-
Artem P over 8 years
<thead>
is required. -
Artem P over 8 yearsand also jquery.turbolinks if you use turbolinks for ajax loading.
-
Evmorov almost 8 yearsFor now jquery.turbolinks doesn't work with Rails 5. You should disable turbolinks for this page or remove it completely
-
Evmorov almost 8 yearsIt's worth mentioning that this example only works with bootstrap-table-rails that is described in another answer
-
Artem P almost 8 years@Evmorov or set version less then 5
gem 'turbolinks', '< 5'
-
Steve Nims over 6 years@Evmorov, or not disable turbolinks, and actually learn how to use it w/ javascript/jquery. @installero, instead of using
$(document).on(load, function() {...});
use$(document).on('turbolinks:load', function() {...});