Rails 数据表选择过滤器

Posted

技术标签:

【中文标题】Rails 数据表选择过滤器【英文标题】:Rails datatables select filter 【发布时间】:2016-10-10 20:13:21 【问题描述】:

我的 SKU 有一个 ajax 数据表。为此,我使用了 ajax-datatables-rails gem。搜索和排序工作完美,但现在我试图在我的表中添加一个过滤功能,它似乎没有做任何事情。我将此示例用于过滤功能:https://datatables.net/examples/api/multi_filter_select.html。 在示例中,在页脚中绘制了选择框,但对我来说,页脚是空的。就像代码根本不运行一样。我也没有收到任何错误。

我在我的咖啡脚本文件 (assets/javascripts/vendor_skus.js.coffee) 中初始化了我的数据表,所以我不得不将它翻译成咖啡脚本。我没有使用咖啡脚本或使用带有rails的ajax的经验,所以我对出了什么问题感到有点迷茫。

我是如何解决我的问题的:

标准选择框对我的情况有问题,因为我在我的表中使用 AJAX,并且选择框似乎只能在客户端表上正常工作。我决定制作自己的自定义过滤器,而不是使用标准选择框。这些是常规选择框,如下所示:

<%= select_tag "store-id", options_from_collection_for_select(@stores, "id", "name"), include_blank: true, class:"store-id form-control" %>  
<%= select_tag "status", options_for_select([ "Open", "On Hold", "Cancelled", "Closed", "Error" ]), include_blank: true, class:"form-control", multiple:true %>

这是我的咖啡脚本,用于让 jQuery 将参数提交到服务器并重新加载表 onchange:

$ ->
  $('#orders-table').DataTable
    processing: true
    serverSide: true
    retrieve: true
    pageLength: 50
    title: 'orders'
    lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]]
    ajax: data: (d) ->
      d.store_id = $('#store-id').val();
      d.status = $('#status').val();
      return

$ ->
  $('#store-id').on 'change', ->
    $('#orders-table').DataTable().ajax.reload()
    return

$ ->
  $('#status').on 'change', ->
    $('#orders-table').DataTable().ajax.reload()
    return   

在您的控制器中,确保将参数传递给数据表,如下所示:

respond_to do |format|
  format.html
  format.json  render json: OrderDatatable.new(view_context,  store_id: params[:store_id], status: params[:status] ) 
end

然后在您的 Datatable 文件中,使用参数过滤您的结果。在这种情况下,我正在使用多选择的状态,因此在选择空白值时,Params [:status] .present?结果为真。这就是为什么我添加了一个检查以查看第一项是否为空字符串。

  def get_raw_records
    # insert query here
    query = Order.all
    query = query.status(params[:status]) if params[:status].present? && (params[:status].count == 1 && params[:status][0] == "") == false 
    query = query.store(params[:store_id]) if params[:store_id].present?
    query.joins(:store)
  end

【问题讨论】:

(1) 如果您不想使用 CoffeeScript,则不必使用,您仍然可以使用纯 JavaScript。 (2) 你的 CoffeeScript 中的缩进是正确的吗? 我更新了我的缩进。尝试使用纯 javascript 并且它有效,但它没有考虑分页(因此只有第一页中的值可以在下拉列表中选择)。此外,下拉列表中的值不等于我表中的值,因此搜索始终导致 0 个结果。我想我会考虑构建一个自定义过滤器 【参考方案1】:

我在实现这个时遇到了同样的问题。我发现问题出在这一行:

column.search((if val then '^' + val + '$' else ''), true, false).draw()

其中咖啡脚本不喜欢以下位:

,真,假

这样删除后:

column.search(if val then '^' + val + '$' else '').draw()

一切正常。需要注意的是,我不是 javascript/coffeescript 人,所以结果产生的负面影响超出了我的范围。但像你一样,我目前正在努力让所有结果出现在可选择的下拉过滤器中。它只显示当前数据页面中的任何唯一值 - 这没有帮助。

仅供参考,要进行分页,请转到您的 datatable.rb 文件并取消注释指向您正在使用的分页的顶部的正确行。我正在使用“will_paginate”进行引导,所以我的看起来像这样:

  include AjaxDatatablesRails::Extensions::WillPaginate

希望对您有所帮助。碰巧,您是否找到了一种在选择过滤器中显示所有结果的方法?

【讨论】:

我最终创建了自己的自定义过滤器。实际上,我发现这很容易做到,现在我的数据表上方有一个带有过滤器的可折叠面板,它将它们的值传递给数据表并在更改时重绘表。效果很好! 您介意发布一个示例吗?或者任何可以帮助某人做同样事情的在线文档? 你去吧,伙计。希望这会有所帮助!【参考方案2】:

我使用 ajax-datatables-rails gem 的 ajax 数据表过滤器的工作代码。

在数据表视图中,我在数据表上方创建了一个表格来输入范围变量,然后添加一些 javascript 以在更改时重新加载数据表:

<table>
        <tbody><tr>
            <td>Minimum CWD:</td>
            <td><input type="text" id="minCWD" name="minCWD"></td>
        </tr>
        <tr>
            <td>Maximum CWD:</td>
            <td><input type="text" id="maxCWD" name="maxCWD"></td>
        </tr>
    </tbody></table>

<script>
$(document).ready(function ()              
            // other options
            var table = $('#example').DataTable()
                    
            $("#minCWD").change(function () 
              table.ajax.reload();
            );
            $("#maxCWD").change(function() 
              table.ajax.reload();
            );
        );
</script>

然后将过滤器变量添加到ajax调用(在咖啡文件中):

ajax: 
      url: $('#example').data('source'),
      beforeSend: (xhr) => xhr.setRequestHeader('Content-Type', 'application/json'),
      data: (d) ->
        $.extend , d, 'minCWD': $('#minCWD').val(),
        $.extend , d, 'maxCWD': $('#maxCWD').val()
    
// note: the beforeSend may not be required

然后在model_datatable.rb中添加一个过滤器:

def get_raw_records
    #YOUR TYPICAL SELECTION...note: I'm using AREL and joining schools with pstats
    #now filter by your max min variables
    if params['minCWD'].present?
      schools = schools.where(pstats[:cwd_percent].gteq(params['minCWD']))
    end
    if params['maxCWD'].present?
      schools = schools.where(pstats[:cwd_percent].lteq(params['maxCWD']))
    end
    return schools
  end

我的控制器如下所示:

respond_to do |format|
      format.html
      format.json  render json: ExampleDatatable.new(params, view_context: view_context) 
end

这里的工作示例:https://schoolsparrow.com/arizona/schools

【讨论】:

以上是关于Rails 数据表选择过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 中使用下拉列表和 ajax 过滤数据

Rails 5搜索构面过滤器

Rails - 过滤多对多

Ruby on Rails - 针对相同数据查看两个不同的过滤器

如何过滤rails中的参数?

如何在没有 AJAX 的情况下在 Rails 客户端过滤数据