Sort table data by columns in rails with bootstrap

17,973

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:

  1. Add gem 'jquery-turbolinks' to your Gemfile to fix turbolink javascript issue and bundle install
  2. 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 .
    
  3. Go here to copy the code for sorttable.js

  4. 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
    
  5. 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

  1. Add gem 'bootstrap-table-rails' in your Gemfile and run bundle install.
  2. Add require bootstrap-table in your application.js.
  3. Add require bootstrap-table in your application.css.
  4. Add data-toggle="table" to your table tag e.g. <table data-toggle="table">.
  5. 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">
Share:
17,973
Neil
Author by

Neil

Updated on July 22, 2022

Comments

  • Neil
    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:

    enter image description here

    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
    Neil almost 9 years
    I tried that but still not working for me unfortunately.
  • Neil
    Neil almost 9 years
    I 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 of sortTable.js. It seems like I'm just not doing something to include bootstrap's javascript functionality. Any ideas?
  • onebree
    onebree almost 9 years
    In 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
    Neil almost 9 years
    They 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
    onebree almost 9 years
    I 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
    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
    Neil almost 9 years
    works 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
    Neil almost 9 years
    ok please append my answer into your answer if you don't mind.
  • onebree
    onebree almost 9 years
  • onebree
    onebree almost 9 years
    @Neil I sent you chat messages above. It does not look like you've replied to any.
  • Artem P
    Artem P over 8 years
    <thead> is required.
  • Artem P
    Artem P over 8 years
    and also jquery.turbolinks if you use turbolinks for ajax loading.
  • Evmorov
    Evmorov almost 8 years
    For now jquery.turbolinks doesn't work with Rails 5. You should disable turbolinks for this page or remove it completely
  • Evmorov
    Evmorov almost 8 years
    It's worth mentioning that this example only works with bootstrap-table-rails that is described in another answer
  • Artem P
    Artem P almost 8 years
    @Evmorov or set version less then 5 gem 'turbolinks', '< 5'
  • Steve Nims
    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() {...});