Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use jTable in Ruby on Rails?

I would like to use jTable jQuery plugin in Ruby on Rails 4. What is the best way to do it? Turbolink compatibility is important for me.

like image 581
havasi Avatar asked Jun 06 '14 07:06

havasi


1 Answers

I installed jTable js and css into the vendor directory (jQuery UI is needed, I used jquery-ui-rails gem)

I created a controller (called tables_controller), and used a little bit tricky way to make it easy to use and rails friendly.

See the following example. I used a special naming convention to make the process easier: the name of the fields contains the name of the table and the name of the column separated with ‘__’ - for example visitors__id. You will see how it helps to handle automatic ordering.

app/controllers/tables_controller.erb:

class TablesController < ApplicationController
  def demo
    respond_to do |format|
      format.json {
        page_size = params[:jtPageSize].to_i
        start_index = params[:jtStartIndex].to_i
        start_page = start_index / page_size + 1
        sort_by = params[:jtSorting].gsub('__', '.')
        filter = params[:filter]
        if filter
          @visitors_count = Visitor.joins(:city).
              where('visitors.name like ? OR cities.name like ?', "%#{filter}%", "%#{filter}%").size()
          @visitors = Visitor.joins(:city ).
              where('visitors.name like ? OR cities.name like ?', "%#{filter}%", "%#{filter}%").order(sort_by).
              paginate(:page => start_page, :per_page => page_size)
        else
          @visitors_count = Visitor.all.size()
          @visitors = Visitor.joins(:city).order(sort_by).
              paginate(:page => start_page, :per_page => page_size)
        end
      }
      format.html {}
      format.js {}
    end
  end
  def demo_delete
    @visitor = Visitor.find(params[:visitors__id])
    if @visitor
      if @visitor.destroy
        render js: '{"Result":"OK"}'
      end
    end
  end
end

app/views/tables/demo.json.jbuilder:

json.Result "OK"
json.TotalRecordCount @visitors_count
json.Records do
  json.array!(@visitors) do |visitor|
    json.visitors__id visitor.id
    json.visitors__name visitor.name
    json.visitors__age visitor.age
    json.cities__name visitor.city.name
  end
end

app/views/tables/demo.html.erb:

<div class="jtable-filter">
  <form class="jtable-filter">
    <input type="text" name="filter" id="filter"/>
    <button type="submit" data-jtable-filter="demo">Filter</button>
  </form>
</div>
<div id="demo" data-jtable-config="/demo">
</div>

app/views/tables/demo.js.erb:

var jtable_config = {
    title: '',
    paging: true, //Enable paging
    pageSize: 10, //Set page size (default: 10)
    sorting: true, //Enable sorting
    defaultSorting: 'visitors__name ASC', //Set default sorting
    defaultDateFormat: 'yy-mm-dd',
    gotoPageArea: 'combobox',
    actions: {
        listAction: '/demo',
        deleteAction: '/demo/delete'
    },
    fields: {
        visitors__id: {
            key: true,
            list: false
        },
        visitors__name: {
            title: 'Name',
            width: '30%'
        },
        visitors__age: {
            title: 'Age',
            width: '20%'
        },
        cities__name: {
            title: 'City',
            width: '20%'
        }
    }
};

application.js:

(function ($) {
    jQuery.fn.jtable_ou = function () {
        return this.each(function () {
            var $this = $(this);
            var config_url=$this.attr("data-jtable-config");
            $.getScript( config_url, function( data, textStatus, jqxhr ) {
                $this.jtable(jtable_config);
                $this.jtable('load');
            });
        });
    };
})(jQuery);

$(document).on("page:change", function() {
    $('[data-jtable-config]').jtable_ou();
    $('button[data-jtable-filter]').click(function (e) {
        e.preventDefault();
        var target=this.getAttribute("data-jtable-filter");
        $('#'+target).jtable('load', {
            filter: $('#filter').val()
        });
    });
});

Gemfile:

match '/demo',   to: 'tables#demo',   via: [:get, :post]
match '/demo/delete',   to: 'tables#demo_delete',   via: [:post]

It is turbolink friendly and uses unobtrusive JavaScript.

You can find detailed description in this post.

like image 177
havasi Avatar answered Oct 06 '22 00:10

havasi