Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have used jquery-datatables-rails to present some information for my index and have added in filters following this. However the datatable appears to be ignoring the filters and they are not shown as part of the requested json in the get request.

I've enclosed my index method, the datatables class, my index view and the coffeescript I'm running.

Index Method

  def index
    @sbcons = Subcontractor.scoped
    if filters = params[:filter]
      @sbcons = @sbcons.where(sbcon_type: filters[:type]) unless filters[:type].blank?
      @sbcons = @sbcons.where(cscs_card: filters[:cscs]) unless filters[:cscs].blank?
      @sbcons = @sbcons.where(approved_status: filters[:approved]) unless filters[:approved].blank?
    end
    respond_to do |format|
      format.html
      format.json do
        render json: SubcontractorsDatatable.new(view_context, @sbcons)
      end
    end
  end

Index View

<% provide(:title, 'All Subcontractors') %>
<h1>Subcontractors List</h1>
<div class="filter">
  <%= form_tag(method: :get, id: "filter_form") do %>
    <%= label_tag :sbcon_type, "Type" %>
    <%= select_tag "filter[type]", options_for_select([[],["Labour Only"], ["Specialist"], ["Both"]]) %>
    <%= label_tag :cscs_card, "CSCS" %>
    <%= select_tag "filter[cscs]", options_for_select([[],["Yes"], ["No"]]) %>
    <%= label_tag :approved_status, "Approved Status" %>
    <%= select_tag "filter[approved]", options_for_select([[],["Approved"], ["Not Approved"]]) %> <br>
    <%= link_to "Filter", '#', id: "filterbutton", class: "btn btn-mini" %>
  <% end %>
  <br>
</div>
<table id="subcontractors" class="table table-condensed table-hover display" data-source="<%= subcontractors_url(format: "json") %>">
  <thead>
    <tr>
      <th>Name</th>
      <th>Contact Number</th>
      <th>CSCS</th>
      <th>Type</th>
      <th>Scotland</th>
      <th>NE England</th>
      <th>NW England</th>
      <th>Midlands</th>
      <th>SE England</th>
      <th>SW England</th>
      <th>London</th>
      <th>Wales</th>
      <th>Operatives</th>
      <th>Product Liability</th>
      <th>Employer Liability</th>
      <th>Public Liability</th>
      <th>Contractors All Risk</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

<%= javascript_tag do %> 
  $('#filterbutton').click(function (){
    $('#subcontractors').dataTable().fnDraw();
  });
<% end %>

Datatables class

class SubcontractorsDatatable
  delegate :params, :h, :link_to, to: :@view

  def initialize(view, sbcons)
    @view = view
    @sbcons = sbcons
  end

  def as_json(option = {})
    {
      sEcho: params[:sEcho].to_i,
      iTotalRecords: Subcontractor.count,
      iTotalDisplayRecords: subcontractors.total_entries,
      aaData: data
    }
  end

private
  def data
    subcontractors.map do |subcontractor|
      [
        link_to(subcontractor.sbcon_name, subcontractor),
        h(subcontractor.con_tel_num),
        h(subcontractor.cscs_card),
        h(subcontractor.sbcon_type),
        h(subcontractor.scot),
        h(subcontractor.ne_eng),
        h(subcontractor.nw_eng),
        h(subcontractor.mid),
        h(subcontractor.se_eng),
        h(subcontractor.sw_eng),
        h(subcontractor.ldn),
        h(subcontractor.wales),
        h(subcontractor.op_avail),
        h(subcontractor.ins_prod),
        h(subcontractor.ins_emp),
        h(subcontractor.ins_pub),
        h(subcontractor.ins_con_all),
        h(subcontractor.approved_status)
      ]
    end
  end

  def subcontractors
    @subcontractors ||= fetch_subcontractors
  end

  def fetch_subcontractors
    subcontractors = Subcontractor.order("#{sort_column} #{sort_direction}")
    subcontractors = subcontractors.page(page).per_page(per_page)
    if params[:sSearch].present?
      subcontractors = subcontractors.where("sbcon_name like :search or con_tel_num like :search", search: "%#{params[:sSearch]}%")
    end
    subcontractors
  end

  def page
    params[:iDisplayStart].to_i/per_page + 1
  end

  def per_page
    params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 10
  end

  def sort_column
    columns = %w[sbcon_name con_tel_num cscs_card sbcon_type scot ne_eng nw_eng mid se_eng sw_eng lon wales op_avail ins_prod ins_emp ins_pub ins_con_all approved_status]
    columns[params[:iSortCol_0].to_i]
  end

  def sort_direction
    params[:sSortDir_0] == "desc" ? "desc" : "asc"
  end
end

Coffeescript

jQuery ->
        $('#subcontractors').dataTable
          sPaginationType: "bootstrap"
          sdom: "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>"
          bProcessing: true
          bServerSide: true
          sAjaxSource: $('#subcontractors').data('source')
          fnServerParams: (aoData) ->
              for form_element in $('#filter_form').serializeArray()
                aoData.push
                  name: form_element.name
                  value: form_element.value
share|improve this question
Hey Ryan, are you using pry to debug this? – Abram 20 hours ago
No I wasn't even sure where to start looking, I can't work out why it's skipping the filtering step. – RyanMacG 20 hours ago
Well, in this case I usually throw a binding.pry into various places and see where it isn't being triggered – Abram 20 hours ago
1  
Check out github.com/nixme/pry-debugger ... add gem "pry" and gem "pry-debugger" .. then bundle.. then restart server.. then add binding.pry anywhere in your code and when the server hits the binding.pry it will stop and you can interact with an irb console within your environment... try adding that in places you expect it to be called, and you might find your problem. Don't forget to check your server console for the pry irb once you reload the page with binding.pry triggered – Abram 20 hours ago
for example, you could test that if filters = params[:filter] is true by placing 'binding.pry' just below if filters = params[:filter] and seeing if your page load hangs. If it does, you're sorted.. check your server console.. if not.. well, if filters = params[:filter] was false – Abram 20 hours ago
show 6 more comments

1 Answer

At Abram's suggesting I looked through if filters part and found that it was never being called. I fixed this by amending the form_tag as follows:

<%= form_tag('#', method: :get, id: "filter_form") do %>

From here I found that the filters were being passed but ignored. Abram suggested moving the logic to the fetch_subcontractors method in the datatables class and changed the initalize method at the same time to reflect this

def initialize(view, subcontractors)
    @view = view
  end
def fetch_subcontractors
    subcontractors = Subcontractor.order("#{sort_column} #{sort_direction}")
    subcontractors = subcontractors.page(page).per_page(per_page)
    if params[:sSearch].present?
      subcontractors = subcontractors.where("sbcon_name like :search or con_tel_num like :search", search: "%#{params[:sSearch]}%")
    end
    if filters = params[:filter]
      binding.pry
      subcontractors = subcontractors.where(sbcon_type: filters[:type]) unless filters[:type].blank?
      subcontractors = subcontractors.where(cscs_card: filters[:cscs]) unless filters[:cscs].blank?
      subcontractors = subcontractors.where(approved: filters[:approved]) unless filters[:approved].blank?
    end
    subcontractors
  end

with these corrections the filters work properly and display the correct results.

share|improve this answer
Good work Ryan! – Abram 18 hours ago
hey just want to make sure that everything else is working, like your searching and ordering? – Abram 18 hours ago
I have a feeling looking at the above that if you have a search term and a filter the filter will override the search term.. correct me if I'm wrong. I hope I am! – Abram 18 hours ago
They work fine, I thought it would cause issues too but thankfully not – RyanMacG 18 hours ago
Awesome, impressive scoping. – Abram 18 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.