Gem Filterrific
1. Giới thiệu Filterrific là gem hỗ trợ lọc, sắp xếp và tìm kiếm trong danh sách các bản ghi một cách rất dễ dàng. 2. Hướng dẫn cài đặt để tạo ứng dụng trong bài viết này, ta có thể tạo một ứng dụng tìm kiếm, lọc, sắp xếp một danh sách các sinh viên, ta đặt tên nó là app'user. Ta cài ...
1. Giới thiệu
Filterrific là gem hỗ trợ lọc, sắp xếp và tìm kiếm trong danh sách các bản ghi một cách rất dễ dàng.
2. Hướng dẫn cài đặt để tạo ứng dụng
trong bài viết này, ta có thể tạo một ứng dụng tìm kiếm, lọc, sắp xếp một danh sách các sinh viên, ta đặt tên nó là app'user.
- Ta cài đặt gem trong # Gemfile và bundle install
gem 'filterrific'
- Thêm Filterrific cho Student model của bạn:
# app/models/student.rb class Student < ActiveRecord::Base belongs_to :country # db columns: # integer: id # string: first_name # string: last_name # text: email # integer: country_id # datetime: created_at filterrific( default_filter_params: { sorted_by: 'created_at_desc' }, available_filters: [ :sorted_by, :search_query :with_country_id ] ) # ActiveRecord association declarations scope :search_query, lambda { |query| return nil if query.blank? terms = query.downcase.split(/s+/) terms = terms.map { |e| (e.gsub('*', '%') + '%').gsub(/%+/, '%') } num_or_conds = 2 where( terms.map { |term| "(LOWER(students.first_name) LIKE ? OR LOWER(students.last_name) LIKE ?)" }.join(' AND '), *terms.map { |e| [e] * num_or_conds }.flatten ). } scope :sorted_by, lambda { |sort_key| direction = (sort_option =~ /desc$/) ? 'desc' : 'asc' case sort_option.to_s when /^name_/ when /^country_name_/ order("LOWER(countries.name) #{ direction }").includes(:country) else raise(ArgumentError, "Invalid sort option: #{ sort_option.inspect }") end } scope :with_country_id, lambda { |country_ids| where(country_id: [*country_ids]) } def self.options_for_sorted_by [ ['Name (a-z)', 'name_asc'], ['Registration date (newest first)', 'created_at_desc'], ['Registration date (oldest first)', 'created_at_asc'], ['Country (a-z)', 'country_name_asc'] ] end end
Trong # app/models/country.rb
class Country < ActiveRecord::Base # db columns: # integer: id # string: name has_many :students def self.options_for_select order('LOWER(name)').map { |e| [e.name, e.id] } end end
- Sử dụngFilterrific trong StudentsController#index:
# app/controllers/students_controller.rb class StudentsController < ApplicationController def index @filterrific = initialize_filterrific( Student, params[:filterrific], select_options: { sorted_by: Student.options_for_sorted_by, with_country_id: Country.options_for_select }, persistence_id: 'shared_key', default_filter_params: {}, available_filters: [], ) or return @students = @filterrific.find.page(params[:page]) # Respond to html for initial page load and to js for AJAX filter updates. respond_to do |format| format.html format.js end rescue ActiveRecord::RecordNotFound => e # There is an issue with the persisted param_set. Reset it. puts "Had to reset filterrific params: #{ e.message }" redirect_to(reset_filterrific_url(format: :html)) and return end ... end
-
Sử dụngFilterrific trong view
Tại file app/views/students/index.html.erb
<h1>Students</h1> <%# Filterrific adds the `form_for_filterrific` view helper: * adds dom id 'filterrific_filter' * applies javascript behaviors: * AJAX form submission on change * AJAX spinner while AJAX request is being processed * sets form_for options like :url, :method and input name prefix %> <%= form_for_filterrific @filterrific do |f| %> <div> Search <%# give the search field the 'filterrific-periodically-observed' class for live updates %> <%= f.text_field( :search_query, class: 'filterrific-periodically-observed' ) %> </div> <div> Country <%= f.select( :with_country_id, @filterrific.select_options[:with_country_id], { include_blank: '- Any -' } ) %> </div> <div> Registered after <%= f.text_field(:with_created_at_gte, class: 'js-datepicker') %> </div> <div> Sorted by <%= f.select(:sorted_by, @filterrific.select_options[:sorted_by]) %> </div> <div> <%= link_to( 'Reset filters', reset_filterrific_url, ) %> </div> <%# add an automated spinner to your form when the list is refreshed %> <%= render_filterrific_spinner %> <% end %> <%= render( partial: 'students/list', locals: { students: @students } ) %>
Trong _list.html.erb
<%# app/views/students/_list.html.erb %> <div id="filterrific_results"> <div> <%= page_entries_info students # provided by will_paginate %> </div> <table> <tr> <th>Name</th> <th>Email</th> <th>Country</th> <th>Registered at</th> </tr> <% students.each do |student| %> <tr> <td><%= link_to(student.full_name, student_path(student)) %></td> <td><%= student.email %></td> <td><%= student.country_name %></td> <td><%= student.decorated_created_at %></td> </tr> <% end %> </table> </div> <%= will_paginate students # provided by will_paginate %>
Trong app/views/students/index.js.erb
<%# app/views/students/index.js.erb %> <% js = escape_javascript( render(partial: 'students/list', locals: { students: @students }) ) %> $("#filterrific_results").html("<%= js %>");
Trong application.js ta viết
//= require filterrific/filterrific-jquery
Sắp xếp theo tiêu đề cột trong app/views/students/_list.html.erb
<div id="filterrific_results"> <div> <%= page_entries_info students # provided by will_paginate %> </div> <table> <tr> <th><%= filterrific_sorting_link(@filterrific, :name) %></th> <th><%= filterrific_sorting_link(@filterrific, :email) %></th> <th><%= filterrific_sorting_link(@filterrific, :country) %></th> <th><%= filterrific_sorting_link(@filterrific, :registered_at) %> </th> </tr> <% students.each do |student| %> <tr> <td><%= link_to(student.full_name, student_path(student)) %></td> <td><%= student.email %></td> <td><%= student.country_name %></td> <td><%= student.decorated_created_at %></td> </tr> <% end %> </table> </div> <%= will_paginate students # provided by will_paginate %>
-
Kết luận
Việc sử dụng gem cho phép lọc, sắp xếp và tìm kiếm một cách tương đối dễ dàng
-